diff --git a/.gitignore b/.gitignore
index 189b414f..cc6cfdb1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
-/build
+/build*
/CMakeLists.txt.user
+/vs/*/
+*.opensdf
+*.sdf
diff --git a/README.md b/README.md
index acaf178f..5494dc0b 100644
--- a/README.md
+++ b/README.md
@@ -1,133 +1,25 @@
-# XMRig
-
-:warning: **You must update miners to version 2.5 before March 28 due [Monero PoW change](https://getmonero.org/2018/02/11/PoW-change-and-key-reuse.html).**
-
-[](https://github.com/xmrig/xmrig/releases)
-[](https://github.com/xmrig/xmrig/releases)
-[](https://github.com/xmrig/xmrig/releases)
-[](https://github.com/xmrig/xmrig/blob/master/LICENSE)
-[](https://github.com/xmrig/xmrig/stargazers)
-[](https://github.com/xmrig/xmrig/network)
+# XMRig (enWILLYado version)
+[XMRig](https://github.com/xmrig) is a team that has some high performance Monero (XMR) miners, with official support for Windows.
+This fork is originally based on the [CPU-mining](https://github.com/xmrig/xmrig) version with some optimizations/rewrites, interesting features for final users and a little code refactors.
XMRig is a high performance Monero (XMR) CPU miner, with official support for Windows.
Originally based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code, since version 1.0.0 completely rewritten from scratch on C++.
+* This software is like the [CPU-mining](https://github.com/xmrig/xmrig) version; but there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd).
* This is the **CPU-mining** version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd).
-* [Roadmap](https://github.com/xmrig/xmrig/issues/106) for next releases.
-
+## Own features
-#### Table of contents
-* [Features](#features)
-* [Download](#download)
-* [Usage](#usage)
-* [Algorithm variations](#algorithm-variations)
-* [Build](https://github.com/xmrig/xmrig/wiki/Build)
-* [Common Issues](#common-issues)
-* [Other information](#other-information)
-* [Donations](#donations)
-* [Release checksums](#release-checksums)
-* [Contacts](#contacts)
-
-## Features
-* High performance.
-* Official Windows support.
-* Small Windows executable, without dependencies.
-* x86/x64 support.
-* Support for backup (failover) mining server.
-* keepalived support.
-* Command line options compatible with cpuminer.
-* CryptoNight-Lite support for AEON.
-* Smart automatic [CPU configuration](https://github.com/xmrig/xmrig/wiki/Threads).
-* Nicehash support
-* It's open source software.
-
-## Download
-* Binary releases: https://github.com/xmrig/xmrig/releases
-* Git tree: https://github.com/xmrig/xmrig.git
- * Clone with `git clone https://github.com/xmrig/xmrig.git` :hammer: [Build instructions](https://github.com/xmrig/xmrig/wiki/Build).
-
-## Usage
-Use [config.xmrig.com](https://config.xmrig.com/xmrig) to generate, edit or share configurations.
-
-### Options
-```
- -a, --algo=ALGO cryptonight (default) or cryptonight-lite
- -o, --url=URL URL of mining server
- -O, --userpass=U:P username:password pair for mining server
- -u, --user=USERNAME username for mining server
- -p, --pass=PASSWORD password for mining server
- -t, --threads=N number of miner threads
- -v, --av=N algorithm variation, 0 auto select
- -k, --keepalive send keepalived for prevent timeout (need pool support)
- -r, --retries=N number of times to retry before switch to backup server (default: 5)
- -R, --retry-pause=N time to pause between retries (default: 5)
- --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1
- --cpu-priority set process priority (0 idle, 2 normal to 5 highest)
- --no-huge-pages disable huge pages support
- --no-color disable colored output
- --donate-level=N donate level, default 5% (5 minutes in 100 minutes)
- --user-agent set custom user-agent string for pool
- -B, --background run the miner in the background
- -c, --config=FILE load a JSON-format configuration file
- -l, --log-file=FILE log all output to a file
- --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)
- --safe safe adjust threads and av settings for current CPU
- --nicehash enable nicehash/xmrig-proxy support
- --print-time=N print hashrate report every N seconds
- --api-port=N port for the miner API
- --api-access-token=T access token for API
- --api-worker-id=ID custom worker-id for API
- -h, --help display this help and exit
- -V, --version output version information and exit
-```
-
-Also you can use configuration via config file, default **config.json**. You can load multiple config files and combine it with command line options.
-
-## Algorithm variations
-Since version 0.8.0.
-* `--av=1` For CPUs with hardware AES.
-* `--av=2` Lower power mode (double hash) of `1`.
-* `--av=3` Software AES implementation.
-* `--av=4` Lower power mode (double hash) of `3`.
-
-## Common Issues
-### HUGE PAGES unavailable
-* Run XMRig as Administrator.
-* Since version 0.8.0 XMRig automatically enables SeLockMemoryPrivilege for current user, but reboot or sign out still required. [Manual instruction](https://msdn.microsoft.com/en-gb/library/ms190730.aspx).
-
-## Other information
-* No HTTP support, only stratum protocol support.
-* No TLS support.
-* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via command line option `--donate-level`.
-
-
-### CPU mining performance
-* **Intel i7-7700** - 307 H/s (4 threads)
-* **AMD Ryzen 7 1700X** - 560 H/s (8 threads)
-
-Please note performance is highly dependent on system load. The numbers above are obtained on an idle system. Tasks heavily using a processor cache, such as video playback, can greatly degrade hashrate. Optimal number of threads depends on the size of the L3 cache of a processor, 1 thread requires 2 MB of cache.
-
-### Maximum performance checklist
-* Idle operating system.
-* Do not exceed optimal thread count.
-* Use modern CPUs with AES-NI instruction set.
-* Try setup optimal cpu affinity.
-* Enable fast memory (Large/Huge pages).
+* Connect to pool or proxies over HTTP PROXY.
+* Include basic encrypted communications.
## Donations
-* XMR: `48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD`
-* BTC: `1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT`
-
-## Release checksums
-### SHA-256
-```
-232ea929f7219c8de81c7e6fcae7437d40d8128cf55b597a6e1fca0cd77f9f5b xmrig-2.5.0-xenial-amd64.tar.gz/xmrig-2.5.0/xmrig
-6149ffed21e740cac12aa61b2fdd17248cbd3e51bab2289d2766aad1d29df910 xmrig-2.5.0-gcc-win32.zip/xmrig.exe
-9c89f80e21db906439a7a1b333b8215dbe07d8e42f98a63f6c10c954288a7108 xmrig-2.5.0-gcc-win64.zip/xmrig.exe
-b50773c5a74ca9921597a1152e2469ec266cc89eb9765038db7e876f0bcece73 xmrig-2.5.0-msvc-win64.zip/xmrig.exe
-```
+* XMR: `433hhduFBtwVXtQiTTTeqyZsB36XaBLJB6bcQfnqqMs5RJitdpi8xBN21hWiEfuPp2hytmf1cshgK5Grgo6QUvLZCP2QSMi`
+* BTC: `13MTEjDv8JmS4suaRx6CcWNthR1vwPr7Ce`
+* DOGE: `DHif8RTy8E6K4b71u3fXXSk7AEyiuN2sUi`
## Contacts
-* support@xmrig.com
-* [reddit](https://www.reddit.com/user/XMRig/)
+* xmrig@enwillyado.com
+* [telegram](https://telegram.me/enWILLYado)
+
+¡Se habla español!
diff --git a/cmake/flags.cmake b/cmake/flags.cmake
index 488f1236..69706436 100644
--- a/cmake/flags.cmake
+++ b/cmake/flags.cmake
@@ -8,11 +8,11 @@ endif()
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -DFOUR_WAY -fomit-frame-pointer -Wno-strict-aliasing -msse -msse2 -msse3 -mmmx -m3dnow")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -ffast-math -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fpermissive -DFOUR_WAY -fomit-frame-pointer -Wno-strict-aliasing -msse -msse2 -msse3 -mmmx -m3dnow")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -ffast-math -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
if (XMRIG_ARMv8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto")
@@ -21,20 +21,20 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -flax-vector-conversions")
else()
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -maes")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -maes")
endif()
if (WIN32)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -flto")
else()
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -flto")
endif()
add_definitions(/D_GNU_SOURCE)
if (${CMAKE_VERSION} VERSION_LESS "3.1.0")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
endif()
#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2")
diff --git a/src/3rdparty/align.h b/src/3rdparty/align.h
new file mode 100644
index 00000000..b61179b9
--- /dev/null
+++ b/src/3rdparty/align.h
@@ -0,0 +1,33 @@
+/* XMRig
+ * Copyright 2010 Jeff Garzik
+ * Copyright 2012-2014 pooler
+ * Copyright 2014 Lucas Jones
+ * Copyright 2014-2016 Wolf9466
+ * Copyright 2016 Jay D Dee
+ * Copyright 2016-2017 XMRig
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __ALIGN_H__
+#define __ALIGN_H__
+
+#ifdef _MSC_VER
+# define VAR_ALIGN(x, decl) __declspec(align(x)) decl
+#else
+# define VAR_ALIGN(x, decl) decl __attribute__ ((aligned(x)))
+#endif
+
+#endif /* __ALIGN_H__ */
diff --git a/src/3rdparty/libcpuid/cpuid_main.c b/src/3rdparty/libcpuid/cpuid_main.c
index 9027b6f6..1005cef7 100644
--- a/src/3rdparty/libcpuid/cpuid_main.c
+++ b/src/3rdparty/libcpuid/cpuid_main.c
@@ -36,6 +36,10 @@
#include
#include
+#ifndef VERSION
+#define VERSION "7.10"
+#endif
+
/* Implementation: */
static int _libcpiud_errno = ERR_OK;
@@ -46,6 +50,11 @@ int set_error(cpu_error_t err)
return (int) err;
}
+static void raw_data_t_constructor(struct cpu_raw_data_t* raw)
+{
+ memset(raw, 0, sizeof(struct cpu_raw_data_t));
+}
+
static void cpu_id_t_constructor(struct cpu_id_t* id)
{
memset(id, 0, sizeof(struct cpu_id_t));
@@ -55,6 +64,37 @@ static void cpu_id_t_constructor(struct cpu_id_t* id)
id->sse_size = -1;
}
+static int parse_token(const char* expected_token, const char* token,
+ const char* value, uint32_t array[][4], int limit, int* recognized)
+{
+ char format[32];
+ int veax, vebx, vecx, vedx;
+ int index;
+
+ if(*recognized)
+ {
+ return 1; /* already recognized */
+ }
+ if(strncmp(token, expected_token, strlen(expected_token)))
+ {
+ return 1; /* not what we search for */
+ }
+ sprintf(format, "%s[%%d]", expected_token);
+ *recognized = 1;
+ if(1 == sscanf(token, format, &index) && index >= 0 && index < limit)
+ {
+ if(4 == sscanf(value, "%x%x%x%x", &veax, &vebx, &vecx, &vedx))
+ {
+ array[index][0] = veax;
+ array[index][1] = vebx;
+ array[index][2] = vecx;
+ array[index][3] = vedx;
+ return 1;
+ }
+ }
+ return 0;
+}
+
/* get_total_cpus() system specific code: uses OS routines to determine total number of CPUs */
#ifdef __APPLE__
#include
@@ -328,6 +368,31 @@ static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* dat
return set_error(ERR_OK);
}
+static void make_list_from_string(const char* csv, struct cpu_list_t* list)
+{
+ int i, n, l, last;
+ l = (int) strlen(csv);
+ n = 0;
+ for(i = 0; i < l; i++) if(csv[i] == ',')
+ {
+ n++;
+ }
+ n++;
+ list->num_entries = n;
+ list->names = (char**) malloc(sizeof(char*) * n);
+ last = -1;
+ n = 0;
+ for(i = 0; i <= l; i++) if(i == l || csv[i] == ',')
+ {
+ list->names[n] = (char*) malloc(i - last);
+ memcpy(list->names[n], &csv[last + 1], i - last - 1);
+ list->names[n][i - last - 1] = '\0';
+ n++;
+ last = i;
+ }
+}
+
+
/* Interface: */
int cpuid_get_total_cpus(void)
@@ -398,6 +463,140 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data)
return set_error(ERR_OK);
}
+int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename)
+{
+ int i;
+ FILE* f;
+
+ if(!strcmp(filename, ""))
+ {
+ f = stdout;
+ }
+ else
+ {
+ f = fopen(filename, "wt");
+ }
+ if(!f)
+ {
+ return set_error(ERR_OPEN);
+ }
+
+ fprintf(f, "version=%s\n", VERSION);
+ for(i = 0; i < MAX_CPUID_LEVEL; i++)
+ fprintf(f, "basic_cpuid[%d]=%08x %08x %08x %08x\n", i,
+ data->basic_cpuid[i][0], data->basic_cpuid[i][1],
+ data->basic_cpuid[i][2], data->basic_cpuid[i][3]);
+ for(i = 0; i < MAX_EXT_CPUID_LEVEL; i++)
+ fprintf(f, "ext_cpuid[%d]=%08x %08x %08x %08x\n", i,
+ data->ext_cpuid[i][0], data->ext_cpuid[i][1],
+ data->ext_cpuid[i][2], data->ext_cpuid[i][3]);
+ for(i = 0; i < MAX_INTELFN4_LEVEL; i++)
+ fprintf(f, "intel_fn4[%d]=%08x %08x %08x %08x\n", i,
+ data->intel_fn4[i][0], data->intel_fn4[i][1],
+ data->intel_fn4[i][2], data->intel_fn4[i][3]);
+ for(i = 0; i < MAX_INTELFN11_LEVEL; i++)
+ fprintf(f, "intel_fn11[%d]=%08x %08x %08x %08x\n", i,
+ data->intel_fn11[i][0], data->intel_fn11[i][1],
+ data->intel_fn11[i][2], data->intel_fn11[i][3]);
+ for(i = 0; i < MAX_INTELFN12H_LEVEL; i++)
+ fprintf(f, "intel_fn12h[%d]=%08x %08x %08x %08x\n", i,
+ data->intel_fn12h[i][0], data->intel_fn12h[i][1],
+ data->intel_fn12h[i][2], data->intel_fn12h[i][3]);
+ for(i = 0; i < MAX_INTELFN14H_LEVEL; i++)
+ fprintf(f, "intel_fn14h[%d]=%08x %08x %08x %08x\n", i,
+ data->intel_fn14h[i][0], data->intel_fn14h[i][1],
+ data->intel_fn14h[i][2], data->intel_fn14h[i][3]);
+
+ if(strcmp(filename, ""))
+ {
+ fclose(f);
+ }
+ return set_error(ERR_OK);
+}
+
+int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename)
+{
+ int i, len;
+ char line[100];
+ char token[100];
+ char* value;
+ int syntax;
+ int cur_line = 0;
+ int recognized;
+ FILE* f;
+
+ raw_data_t_constructor(data);
+
+ if(!strcmp(filename, ""))
+ {
+ f = stdin;
+ }
+ else
+ {
+ f = fopen(filename, "rt");
+ }
+ if(!f)
+ {
+ return set_error(ERR_OPEN);
+ }
+ while(fgets(line, sizeof(line), f))
+ {
+ ++cur_line;
+ len = (int) strlen(line);
+ if(len < 2)
+ {
+ continue;
+ }
+ if(line[len - 1] == '\n')
+ {
+ line[--len] = '\0';
+ }
+ for(i = 0; i < len && line[i] != '='; i++)
+ if(i >= len && i < 1 && len - i - 1 <= 0)
+ {
+ fclose(f);
+ return set_error(ERR_BADFMT);
+ }
+ strncpy(token, line, i);
+ token[i] = '\0';
+ value = &line[i + 1];
+ /* try to recognize the line */
+ recognized = 0;
+ if(!strcmp(token, "version") || !strcmp(token, "build_date"))
+ {
+ recognized = 1;
+ }
+ syntax = 1;
+ syntax = syntax && parse_token("basic_cpuid", token, value, data->basic_cpuid, MAX_CPUID_LEVEL, &recognized);
+ syntax = syntax &&
+ parse_token("ext_cpuid", token, value, data->ext_cpuid, MAX_EXT_CPUID_LEVEL, &recognized);
+ syntax = syntax &&
+ parse_token("intel_fn4", token, value, data->intel_fn4, MAX_INTELFN4_LEVEL, &recognized);
+ syntax = syntax &&
+ parse_token("intel_fn11", token, value, data->intel_fn11, MAX_INTELFN11_LEVEL, &recognized);
+ syntax = syntax &&
+ parse_token("intel_fn12h", token, value, data->intel_fn12h, MAX_INTELFN12H_LEVEL, &recognized);
+ syntax = syntax &&
+ parse_token("intel_fn14h", token, value, data->intel_fn14h, MAX_INTELFN14H_LEVEL, &recognized);
+ if(!syntax)
+ {
+ warnf("Error: %s:%d: Syntax error\n", filename, cur_line);
+ fclose(f);
+ return set_error(ERR_BADFMT);
+ }
+ if(!recognized)
+ {
+ warnf("Warning: %s:%d not understood!\n", filename, cur_line);
+ }
+ }
+
+ if(strcmp(filename, ""))
+ {
+ fclose(f);
+ }
+ return set_error(ERR_OK);
+}
+
int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal)
{
int r;
@@ -435,7 +634,264 @@ int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
return cpu_ident_internal(raw, data, &throwaway);
}
+const char* cpu_feature_str(cpu_feature_t feature)
+{
+ const struct
+ {
+ cpu_feature_t feature;
+ const char* name;
+ }
+ matchtable[] =
+ {
+ { CPU_FEATURE_FPU, "fpu" },
+ { CPU_FEATURE_VME, "vme" },
+ { CPU_FEATURE_DE, "de" },
+ { CPU_FEATURE_PSE, "pse" },
+ { CPU_FEATURE_TSC, "tsc" },
+ { CPU_FEATURE_MSR, "msr" },
+ { CPU_FEATURE_PAE, "pae" },
+ { CPU_FEATURE_MCE, "mce" },
+ { CPU_FEATURE_CX8, "cx8" },
+ { CPU_FEATURE_APIC, "apic" },
+ { CPU_FEATURE_MTRR, "mtrr" },
+ { CPU_FEATURE_SEP, "sep" },
+ { CPU_FEATURE_PGE, "pge" },
+ { CPU_FEATURE_MCA, "mca" },
+ { CPU_FEATURE_CMOV, "cmov" },
+ { CPU_FEATURE_PAT, "pat" },
+ { CPU_FEATURE_PSE36, "pse36" },
+ { CPU_FEATURE_PN, "pn" },
+ { CPU_FEATURE_CLFLUSH, "clflush" },
+ { CPU_FEATURE_DTS, "dts" },
+ { CPU_FEATURE_ACPI, "acpi" },
+ { CPU_FEATURE_MMX, "mmx" },
+ { CPU_FEATURE_FXSR, "fxsr" },
+ { CPU_FEATURE_SSE, "sse" },
+ { CPU_FEATURE_SSE2, "sse2" },
+ { CPU_FEATURE_SS, "ss" },
+ { CPU_FEATURE_HT, "ht" },
+ { CPU_FEATURE_TM, "tm" },
+ { CPU_FEATURE_IA64, "ia64" },
+ { CPU_FEATURE_PBE, "pbe" },
+ { CPU_FEATURE_PNI, "pni" },
+ { CPU_FEATURE_PCLMUL, "pclmul" },
+ { CPU_FEATURE_DTS64, "dts64" },
+ { CPU_FEATURE_MONITOR, "monitor" },
+ { CPU_FEATURE_DS_CPL, "ds_cpl" },
+ { CPU_FEATURE_VMX, "vmx" },
+ { CPU_FEATURE_SMX, "smx" },
+ { CPU_FEATURE_EST, "est" },
+ { CPU_FEATURE_TM2, "tm2" },
+ { CPU_FEATURE_SSSE3, "ssse3" },
+ { CPU_FEATURE_CID, "cid" },
+ { CPU_FEATURE_CX16, "cx16" },
+ { CPU_FEATURE_XTPR, "xtpr" },
+ { CPU_FEATURE_PDCM, "pdcm" },
+ { CPU_FEATURE_DCA, "dca" },
+ { CPU_FEATURE_SSE4_1, "sse4_1" },
+ { CPU_FEATURE_SSE4_2, "sse4_2" },
+ { CPU_FEATURE_SYSCALL, "syscall" },
+ { CPU_FEATURE_XD, "xd" },
+ { CPU_FEATURE_X2APIC, "x2apic"},
+ { CPU_FEATURE_MOVBE, "movbe" },
+ { CPU_FEATURE_POPCNT, "popcnt" },
+ { CPU_FEATURE_AES, "aes" },
+ { CPU_FEATURE_XSAVE, "xsave" },
+ { CPU_FEATURE_OSXSAVE, "osxsave" },
+ { CPU_FEATURE_AVX, "avx" },
+ { CPU_FEATURE_MMXEXT, "mmxext" },
+ { CPU_FEATURE_3DNOW, "3dnow" },
+ { CPU_FEATURE_3DNOWEXT, "3dnowext" },
+ { CPU_FEATURE_NX, "nx" },
+ { CPU_FEATURE_FXSR_OPT, "fxsr_opt" },
+ { CPU_FEATURE_RDTSCP, "rdtscp" },
+ { CPU_FEATURE_LM, "lm" },
+ { CPU_FEATURE_LAHF_LM, "lahf_lm" },
+ { CPU_FEATURE_CMP_LEGACY, "cmp_legacy" },
+ { CPU_FEATURE_SVM, "svm" },
+ { CPU_FEATURE_SSE4A, "sse4a" },
+ { CPU_FEATURE_MISALIGNSSE, "misalignsse" },
+ { CPU_FEATURE_ABM, "abm" },
+ { CPU_FEATURE_3DNOWPREFETCH, "3dnowprefetch" },
+ { CPU_FEATURE_OSVW, "osvw" },
+ { CPU_FEATURE_IBS, "ibs" },
+ { CPU_FEATURE_SSE5, "sse5" },
+ { CPU_FEATURE_SKINIT, "skinit" },
+ { CPU_FEATURE_WDT, "wdt" },
+ { CPU_FEATURE_TS, "ts" },
+ { CPU_FEATURE_FID, "fid" },
+ { CPU_FEATURE_VID, "vid" },
+ { CPU_FEATURE_TTP, "ttp" },
+ { CPU_FEATURE_TM_AMD, "tm_amd" },
+ { CPU_FEATURE_STC, "stc" },
+ { CPU_FEATURE_100MHZSTEPS, "100mhzsteps" },
+ { CPU_FEATURE_HWPSTATE, "hwpstate" },
+ { CPU_FEATURE_CONSTANT_TSC, "constant_tsc" },
+ { CPU_FEATURE_XOP, "xop" },
+ { CPU_FEATURE_FMA3, "fma3" },
+ { CPU_FEATURE_FMA4, "fma4" },
+ { CPU_FEATURE_TBM, "tbm" },
+ { CPU_FEATURE_F16C, "f16c" },
+ { CPU_FEATURE_RDRAND, "rdrand" },
+ { CPU_FEATURE_CPB, "cpb" },
+ { CPU_FEATURE_APERFMPERF, "aperfmperf" },
+ { CPU_FEATURE_PFI, "pfi" },
+ { CPU_FEATURE_PA, "pa" },
+ { CPU_FEATURE_AVX2, "avx2" },
+ { CPU_FEATURE_BMI1, "bmi1" },
+ { CPU_FEATURE_BMI2, "bmi2" },
+ { CPU_FEATURE_HLE, "hle" },
+ { CPU_FEATURE_RTM, "rtm" },
+ { CPU_FEATURE_AVX512F, "avx512f" },
+ { CPU_FEATURE_AVX512DQ, "avx512dq" },
+ { CPU_FEATURE_AVX512PF, "avx512pf" },
+ { CPU_FEATURE_AVX512ER, "avx512er" },
+ { CPU_FEATURE_AVX512CD, "avx512cd" },
+ { CPU_FEATURE_SHA_NI, "sha_ni" },
+ { CPU_FEATURE_AVX512BW, "avx512bw" },
+ { CPU_FEATURE_AVX512VL, "avx512vl" },
+ { CPU_FEATURE_SGX, "sgx" },
+ { CPU_FEATURE_RDSEED, "rdseed" },
+ { CPU_FEATURE_ADX, "adx" },
+ };
+ unsigned i, n = COUNT_OF(matchtable);
+ if(n != NUM_CPU_FEATURES)
+ {
+ warnf("Warning: incomplete library, feature matchtable size differs from the actual number of features.\n");
+ }
+ for(i = 0; i < n; i++)
+ if(matchtable[i].feature == feature)
+ {
+ return matchtable[i].name;
+ }
+ return "";
+}
+
+const char* cpuid_error(void)
+{
+ const struct
+ {
+ cpu_error_t error;
+ const char* description;
+ }
+ matchtable[] =
+ {
+ { ERR_OK , "No error"},
+ { ERR_NO_CPUID , "CPUID instruction is not supported"},
+ { ERR_NO_RDTSC , "RDTSC instruction is not supported"},
+ { ERR_NO_MEM , "Memory allocation failed"},
+ { ERR_OPEN , "File open operation failed"},
+ { ERR_BADFMT , "Bad file format"},
+ { ERR_NOT_IMP , "Not implemented"},
+ { ERR_CPU_UNKN , "Unsupported processor"},
+ { ERR_NO_RDMSR , "RDMSR instruction is not supported"},
+ { ERR_NO_DRIVER, "RDMSR driver error (generic)"},
+ { ERR_NO_PERMS , "No permissions to install RDMSR driver"},
+ { ERR_EXTRACT , "Cannot extract RDMSR driver (read only media?)"},
+ { ERR_HANDLE , "Bad handle"},
+ { ERR_INVMSR , "Invalid MSR"},
+ { ERR_INVCNB , "Invalid core number"},
+ { ERR_HANDLE_R , "Error on handle read"},
+ { ERR_INVRANGE , "Invalid given range"},
+ };
+ unsigned i;
+ for(i = 0; i < COUNT_OF(matchtable); i++)
+ if(_libcpiud_errno == matchtable[i].error)
+ {
+ return matchtable[i].description;
+ }
+ return "Unknown error";
+}
+
+
const char* cpuid_lib_version(void)
{
return VERSION;
}
+
+libcpuid_warn_fn_t cpuid_set_warn_function(libcpuid_warn_fn_t new_fn)
+{
+ libcpuid_warn_fn_t ret = _warn_fun;
+ _warn_fun = new_fn;
+ return ret;
+}
+
+void cpuid_set_verbosiness_level(int level)
+{
+ _current_verboselevel = level;
+}
+
+cpu_vendor_t cpuid_get_vendor(void)
+{
+ static cpu_vendor_t vendor = VENDOR_UNKNOWN;
+ uint32_t raw_vendor[4];
+ char vendor_str[VENDOR_STR_MAX];
+
+ if(vendor == VENDOR_UNKNOWN)
+ {
+ if(!cpuid_present())
+ {
+ set_error(ERR_NO_CPUID);
+ }
+ else
+ {
+ cpu_exec_cpuid(0, raw_vendor);
+ vendor = cpuid_vendor_identify(raw_vendor, vendor_str);
+ }
+ }
+ return vendor;
+}
+
+void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list)
+{
+ switch(vendor)
+ {
+ case VENDOR_INTEL:
+ cpuid_get_list_intel(list);
+ break;
+ case VENDOR_AMD:
+ cpuid_get_list_amd(list);
+ break;
+ case VENDOR_CYRIX:
+ make_list_from_string("Cx486,Cx5x86,6x86,6x86MX,M II,MediaGX,MediaGXi,MediaGXm", list);
+ break;
+ case VENDOR_NEXGEN:
+ make_list_from_string("Nx586", list);
+ break;
+ case VENDOR_TRANSMETA:
+ make_list_from_string("Crusoe,Efficeon", list);
+ break;
+ case VENDOR_UMC:
+ make_list_from_string("UMC x86 CPU", list);
+ break;
+ case VENDOR_CENTAUR:
+ make_list_from_string("VIA C3,VIA C7,VIA Nano", list);
+ break;
+ case VENDOR_RISE:
+ make_list_from_string("Rise mP6", list);
+ break;
+ case VENDOR_SIS:
+ make_list_from_string("SiS mP6", list);
+ break;
+ case VENDOR_NSC:
+ make_list_from_string("Geode GXm,Geode GXLV,Geode GX1,Geode GX2", list);
+ break;
+ default:
+ warnf("Unknown vendor passed to cpuid_get_cpu_list()\n");
+ break;
+ }
+}
+
+void cpuid_free_cpu_list(struct cpu_list_t* list)
+{
+ int i;
+ if(list->num_entries <= 0)
+ {
+ return;
+ }
+ for(i = 0; i < list->num_entries; i++)
+ {
+ free(list->names[i]);
+ }
+ free(list->names);
+}
diff --git a/src/3rdparty/libcpuid/libcpuid.h b/src/3rdparty/libcpuid/libcpuid.h
index 00c39322..88ec5721 100644
--- a/src/3rdparty/libcpuid/libcpuid.h
+++ b/src/3rdparty/libcpuid/libcpuid.h
@@ -85,7 +85,11 @@
@{ */
/* Include some integer type specifications: */
+#ifdef _WIN32
#include "libcpuid_types.h"
+#else
+# include
+#endif
/* Some limits and other constants */
#include "libcpuid_constants.h"
@@ -619,6 +623,39 @@ void cpu_exec_cpuid_ext(uint32_t* regs);
*/
int cpuid_get_raw_data(struct cpu_raw_data_t* data);
+/**
+ * @brief Writes the raw CPUID data to a text file
+ * @param data - a pointer to cpu_raw_data_t structure
+ * @param filename - the path of the file, where the serialized data should be
+ * written. If empty, stdout will be used.
+ * @note This is intended primarily for debugging. On some processor, which is
+ * not currently supported or not completely recognized by cpu_identify,
+ * one can still successfully get the raw data and write it to a file.
+ * libcpuid developers can later import this file and debug the detection
+ * code as if running on the actual hardware.
+ * The file is simple text format of "something=value" pairs. Version info
+ * is also written, but the format is not intended to be neither backward-
+ * nor forward compatible.
+ * @returns zero if successful, and some negative number on error.
+ * The error message can be obtained by calling \ref cpuid_error.
+ * @see cpu_error_t
+ */
+int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename);
+
+/**
+ * @brief Reads raw CPUID data from file
+ * @param data - a pointer to cpu_raw_data_t structure. The deserialized data will
+ * be written here.
+ * @param filename - the path of the file, containing the serialized raw data.
+ * If empty, stdin will be used.
+ * @note This function may fail, if the file is created by different version of
+ * the library. Also, see the notes on cpuid_serialize_raw_data.
+ * @returns zero if successful, and some negative number on error.
+ * The error message can be obtained by calling \ref cpuid_error.
+ * @see cpu_error_t
+*/
+int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename);
+
/**
* @brief Identifies the CPU
* @param raw - Input - a pointer to the raw CPUID data, which is obtained
@@ -644,6 +681,222 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data);
*/
int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data);
+/**
+ * @brief Returns the short textual representation of a CPU flag
+ * @param feature - the feature, whose textual representation is wanted.
+ * @returns a constant string like "fpu", "tsc", "sse2", etc.
+ * @note the names of the returned flags are compatible with those from
+ * /proc/cpuinfo in Linux, with the exception of `tm_amd'
+ */
+const char* cpu_feature_str(cpu_feature_t feature);
+
+/**
+ * @brief Returns textual description of the last error
+ *
+ * libcpuid stores an `errno'-style error status, whose description
+ * can be obtained with this function.
+ * @note This function is not thread-safe
+ * @see cpu_error_t
+ */
+const char* cpuid_error(void);
+
+/**
+ * @brief Executes RDTSC
+ *
+ * The RDTSC (ReaD Time Stamp Counter) instruction gives access to an
+ * internal 64-bit counter, which usually increments at each clock cycle.
+ * This can be used for various timing routines, and as a very precise
+ * clock source. It is set to zero on system startup. Beware that may not
+ * increment at the same frequency as the CPU. Consecutive calls of RDTSC
+ * are, however, guaranteed to return monotonically-increasing values.
+ *
+ * @param result - a pointer to a 64-bit unsigned integer, where the TSC value
+ * will be stored
+ *
+ * @note If 100% compatibility is a concern, you must first check if the
+ * RDTSC instruction is present (if it is not, your program will crash
+ * with "invalid opcode" exception). Only some very old processors (i486,
+ * early AMD K5 and some Cyrix CPUs) lack that instruction - they should
+ * have become exceedingly rare these days. To verify RDTSC presence,
+ * run cpu_identify() and check flags[CPU_FEATURE_TSC].
+ *
+ * @note The monotonically increasing nature of the TSC may be violated
+ * on SMP systems, if their TSC clocks run at different rate. If the OS
+ * doesn't account for that, the TSC drift may become arbitrary large.
+ */
+void cpu_rdtsc(uint64_t* result);
+
+/**
+ * @brief Store TSC and timing info
+ *
+ * This function stores the current TSC value and current
+ * time info from a precise OS-specific clock source in the cpu_mark_t
+ * structure. The sys_clock field contains time with microsecond resolution.
+ * The values can later be used to measure time intervals, number of clocks,
+ * FPU frequency, etc.
+ * @see cpu_rdtsc
+ *
+ * @param mark [out] - a pointer to a cpu_mark_t structure
+ */
+void cpu_tsc_mark(struct cpu_mark_t* mark);
+
+/**
+ * @brief Calculate TSC and timing difference
+ *
+ * @param mark - input/output: a pointer to a cpu_mark_t sturcture, which has
+ * already been initialized by cpu_tsc_mark. The difference in
+ * TSC and time will be written here.
+ *
+ * This function calculates the TSC and time difference, by obtaining the
+ * current TSC and timing values and subtracting the contents of the `mark'
+ * structure from them. Results are written in the same structure.
+ *
+ * Example:
+ * @code
+ * ...
+ * struct cpu_mark_t mark;
+ * cpu_tsc_mark(&mark);
+ * foo();
+ * cpu_tsc_unmark(&mark);
+ * printf("Foo finished. Executed in %llu cycles and %llu usecs\n",
+ * mark.tsc, mark.sys_clock);
+ * ...
+ * @endcode
+ */
+void cpu_tsc_unmark(struct cpu_mark_t* mark);
+
+/**
+ * @brief Calculates the CPU clock
+ *
+ * @param mark - pointer to a cpu_mark_t structure, which has been initialized
+ * with cpu_tsc_mark and later `stopped' with cpu_tsc_unmark.
+ *
+ * @note For reliable results, the marked time interval should be at least about
+ * 10 ms.
+ *
+ * @returns the CPU clock frequency, in MHz. Due to measurement error, it will
+ * differ from the true value in a few least-significant bits. Accuracy depends
+ * on the timing interval - the more, the better. If the timing interval is
+ * insufficient, the result is -1. Also, see the comment on cpu_clock_measure
+ * for additional issues and pitfalls in using RDTSC for CPU frequency
+ * measurements.
+ */
+int cpu_clock_by_mark(struct cpu_mark_t* mark);
+
+/**
+ * @brief Returns the CPU clock, as reported by the OS
+ *
+ * This function uses OS-specific functions to obtain the CPU clock. It may
+ * differ from the true clock for several reasons:
+ *
+ * i) The CPU might be in some power saving state, while the OS reports its
+ * full-power frequency, or vice-versa.
+ * ii) In some cases you can raise or lower the CPU frequency with overclocking
+ * utilities and the OS will not notice.
+ *
+ * @returns the CPU clock frequency in MHz. If the OS is not (yet) supported
+ * or lacks the necessary reporting machinery, the return value is -1
+ */
+int cpu_clock_by_os(void);
+
+/**
+ * @brief Measure the CPU clock frequency
+ *
+ * @param millis - How much time to waste in the busy-wait cycle. In millisecs.
+ * Useful values 10 - 1000
+ * @param quad_check - Do a more thorough measurement if nonzero
+ * (see the explanation).
+ *
+ * The function performs a busy-wait cycle for the given time and calculates
+ * the CPU frequency by the difference of the TSC values. The accuracy of the
+ * calculation depends on the length of the busy-wait cycle: more is better,
+ * but 100ms should be enough for most purposes.
+ *
+ * While this will calculate the CPU frequency correctly in most cases, there are
+ * several reasons why it might be incorrect:
+ *
+ * i) RDTSC doesn't guarantee it will run at the same clock as the CPU.
+ * Apparently there aren't CPUs at the moment, but still, there's no
+ * guarantee.
+ * ii) The CPU might be in a low-frequency power saving mode, and the CPU
+ * might be switched to higher frequency at any time. If this happens
+ * during the measurement, the result can be anywhere between the
+ * low and high frequencies. Also, if you're interested in the
+ * high frequency value only, this function might return the low one
+ * instead.
+ * iii) On SMP systems exhibiting TSC drift (see \ref cpu_rdtsc)
+ *
+ * the quad_check option will run four consecutive measurements and
+ * then return the average of the two most-consistent results. The total
+ * runtime of the function will still be `millis' - consider using
+ * a bit more time for the timing interval.
+ *
+ * Finally, for benchmarking / CPU intensive applications, the best strategy is
+ * to use the cpu_tsc_mark() / cpu_tsc_unmark() / cpu_clock_by_mark() method.
+ * Begin by mark()-ing about one second after application startup (allowing the
+ * power-saving manager to kick in and rise the frequency during that time),
+ * then unmark() just before application finishing. The result will most
+ * acurately represent at what frequency your app was running.
+ *
+ * @returns the CPU clock frequency in MHz (within some measurement error
+ * margin). If RDTSC is not supported, the result is -1.
+ */
+int cpu_clock_measure(int millis, int quad_check);
+
+/**
+ * @brief Measure the CPU clock frequency using instruction-counting
+ *
+ * @param millis - how much time to allocate for each run, in milliseconds
+ * @param runs - how many runs to perform
+ *
+ * The function performs a busy-wait cycle using a known number of "heavy" (SSE)
+ * instructions. These instructions run at (more or less guaranteed) 1 IPC rate,
+ * so by running a busy loop for a fixed amount of time, and measuring the
+ * amount of instructions done, the CPU clock is accurately measured.
+ *
+ * Of course, this function is still affected by the power-saving schemes, so
+ * the warnings as of cpu_clock_measure() still apply. However, this function is
+ * immune to problems with detection, related to the Intel Nehalem's "Turbo"
+ * mode, where the internal clock is raised, but the RDTSC rate is unaffected.
+ *
+ * The function will run for about (millis * runs) milliseconds.
+ * You can make only a single busy-wait run (runs == 1); however, this can
+ * be affected by task scheduling (which will break the counting), so allowing
+ * more than one run is recommended. As run length is not imperative for
+ * accurate readings (e.g., 50ms is sufficient), you can afford a lot of short
+ * runs, e.g. 10 runs of 50ms or 20 runs of 25ms.
+ *
+ * Recommended values - millis = 50, runs = 4. For more robustness,
+ * increase the number of runs.
+ *
+ * NOTE: on Bulldozer and later CPUs, the busy-wait cycle runs at 1.4 IPC, thus
+ * the results are skewed. This is corrected internally by dividing the resulting
+ * value by 1.4.
+ * However, this only occurs if the thread is executed on a single CMT
+ * module - if there are other threads competing for resources, the results are
+ * unpredictable. Make sure you run cpu_clock_by_ic() on a CPU that is free from
+ * competing threads, or if there are such threads, they shouldn't exceed the
+ * number of modules. On a Bulldozer X8, that means 4 threads.
+ *
+ * @returns the CPU clock frequency in MHz (within some measurement error
+ * margin). If SSE is not supported, the result is -1. If the input parameters
+ * are incorrect, or some other internal fault is detected, the result is -2.
+ */
+int cpu_clock_by_ic(int millis, int runs);
+
+/**
+ * @brief Get the CPU clock frequency (all-in-one method)
+ *
+ * This is an all-in-one method for getting the CPU clock frequency.
+ * It tries to use the OS for that. If the OS doesn't have this info, it
+ * uses cpu_clock_measure with 200ms time interval and quadruple checking.
+ *
+ * @returns the CPU clock frequency in MHz. If every possible method fails,
+ * the result is -1.
+ */
+int cpu_clock(void);
+
+
/**
* @brief The return value of cpuid_get_epc().
* @details
@@ -677,6 +930,232 @@ struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw);
*/
const char* cpuid_lib_version(void);
+typedef void (*libcpuid_warn_fn_t)(const char* msg);
+/**
+ * @brief Sets the warning print function
+ *
+ * In some cases, the internal libcpuid machinery would like to emit useful
+ * debug warnings. By default, these warnings are written to stderr. However,
+ * you can set a custom function that will receive those warnings.
+ *
+ * @param warn_fun - the warning function you want to set. If NULL, warnings
+ * are disabled. The function takes const char* argument.
+ *
+ * @returns the current warning function. You can use the return value to
+ * keep the previous warning function and restore it at your discretion.
+ */
+libcpuid_warn_fn_t cpuid_set_warn_function(libcpuid_warn_fn_t warn_fun);
+
+/**
+ * @brief Sets the verbosiness level
+ *
+ * When the verbosiness level is above zero, some functions might print
+ * diagnostic information about what are they doing. The higher the level is,
+ * the more detail is printed. Level zero is guaranteed to omit all such
+ * output. The output is written using the same machinery as the warnings,
+ * @see cpuid_set_warn_function()
+ *
+ * @param level the desired verbosiness level. Useful values 0..2 inclusive
+ */
+void cpuid_set_verbosiness_level(int level);
+
+
+/**
+ * @brief Obtains the CPU vendor from CPUID from the current CPU
+ * @note The result is cached.
+ * @returns VENDOR_UNKNOWN if failed, otherwise the CPU vendor type.
+ * @see cpu_vendor_t
+ */
+cpu_vendor_t cpuid_get_vendor(void);
+
+/**
+ * @brief a structure that holds a list of processor names
+ */
+struct cpu_list_t
+{
+ /** Number of entries in the list */
+ int num_entries;
+ /** Pointers to names. There will be num_entries of them */
+ char** names;
+};
+
+/**
+ * @brief Gets a list of all known CPU names from a specific vendor.
+ *
+ * This function compiles a list of all known CPU (code)names
+ * (i.e. the possible values of cpu_id_t::cpu_codename) for the given vendor.
+ *
+ * There are about 100 entries for Intel and AMD, and a few for the other
+ * vendors. The list is written out in approximate chronological introduction
+ * order of the parts.
+ *
+ * @param vendor the vendor to be queried
+ * @param list [out] the resulting list will be written here.
+ * NOTE: As the memory is dynamically allocated, be sure to call
+ * cpuid_free_cpu_list() after you're done with the data
+ * @see cpu_list_t
+ */
+void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list);
+
+/**
+ * @brief Frees a CPU list
+ *
+ * This function deletes all the memory associated with a CPU list, as obtained
+ * by cpuid_get_cpu_list()
+ *
+ * @param list - the list to be free()'d.
+ */
+void cpuid_free_cpu_list(struct cpu_list_t* list);
+
+struct msr_driver_t;
+/**
+ * @brief Starts/opens a driver, needed to read MSRs (Model Specific Registers)
+ *
+ * On systems that support it, this function will create a temporary
+ * system driver, that has privileges to execute the RDMSR instruction.
+ * After the driver is created, you can read MSRs by calling \ref cpu_rdmsr
+ *
+ * @returns a handle to the driver on success, and NULL on error.
+ * The error message can be obtained by calling \ref cpuid_error.
+ * @see cpu_error_t
+ */
+struct msr_driver_t* cpu_msr_driver_open(void);
+
+/**
+ * @brief Similar to \ref cpu_msr_driver_open, but accept one parameter
+ *
+ * This function works on certain operating systems (GNU/Linux, FreeBSD)
+ *
+ * @param core_num specify the core number for MSR.
+ * The first core number is 0.
+ * The last core number is \ref cpuid_get_total_cpus - 1.
+ *
+ * @returns a handle to the driver on success, and NULL on error.
+ * The error message can be obtained by calling \ref cpuid_error.
+ * @see cpu_error_t
+ */
+struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num);
+
+/**
+ * @brief Reads a Model-Specific Register (MSR)
+ *
+ * If the CPU has MSRs (as indicated by the CPU_FEATURE_MSR flag), you can
+ * read a MSR with the given index by calling this function.
+ *
+ * There are several prerequisites you must do before reading MSRs:
+ * 1) You must ensure the CPU has RDMSR. Check the CPU_FEATURE_MSR flag
+ * in cpu_id_t::flags
+ * 2) You must ensure that the CPU implements the specific MSR you intend to
+ * read.
+ * 3) You must open a MSR-reader driver. RDMSR is a privileged instruction and
+ * needs ring-0 access in order to work. This temporary driver is created
+ * by calling \ref cpu_msr_driver_open
+ *
+ * @param handle - a handle to the MSR reader driver, as created by
+ * cpu_msr_driver_open
+ * @param msr_index - the numeric ID of the MSR you want to read
+ * @param result - a pointer to a 64-bit integer, where the MSR value is stored
+ *
+ * @returns zero if successful, and some negative number on error.
+ * The error message can be obtained by calling \ref cpuid_error.
+ * @see cpu_error_t
+ */
+int cpu_rdmsr(struct msr_driver_t* handle, uint32_t msr_index, uint64_t* result);
+
+
+typedef enum
+{
+ INFO_MPERF, /*!< Maximum performance frequency clock. This
+ is a counter, which increments as a
+ proportion of the actual processor speed. */
+ INFO_APERF, /*!< Actual performance frequency clock. This
+ accumulates the core clock counts when the
+ core is active. */
+ INFO_MIN_MULTIPLIER, /*!< Minimum CPU:FSB ratio for this CPU,
+ multiplied by 100. */
+ INFO_CUR_MULTIPLIER, /*!< Current CPU:FSB ratio, multiplied by 100.
+ e.g., a CPU:FSB value of 18.5 reads as
+ "1850". */
+ INFO_MAX_MULTIPLIER, /*!< Maximum CPU:FSB ratio for this CPU,
+ multiplied by 100. */
+ INFO_TEMPERATURE, /*!< The current core temperature in Celsius. */
+ INFO_THROTTLING, /*!< 1 if the current logical processor is
+ throttling. 0 if it is running normally. */
+ INFO_VOLTAGE, /*!< The current core voltage in Volt,
+ multiplied by 100. */
+ INFO_BCLK, /*!< See \ref INFO_BUS_CLOCK. */
+ INFO_BUS_CLOCK, /*!< The main bus clock in MHz,
+ e.g., FSB/QPI/DMI/HT base clock,
+ multiplied by 100. */
+} cpu_msrinfo_request_t;
+
+/**
+ * @brief Similar to \ref cpu_rdmsr, but extract a range of bits
+ *
+ * @param handle - a handle to the MSR reader driver, as created by
+ * cpu_msr_driver_open
+ * @param msr_index - the numeric ID of the MSR you want to read
+ * @param highbit - the high bit in range, must be inferior to 64
+ * @param lowbit - the low bit in range, must be equal or superior to 0
+ * @param result - a pointer to a 64-bit integer, where the MSR value is stored
+ *
+ * @returns zero if successful, and some negative number on error.
+ * The error message can be obtained by calling \ref cpuid_error.
+ * @see cpu_error_t
+ */
+int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit,
+ uint8_t lowbit, uint64_t* result);
+
+/**
+ * @brief Reads extended CPU information from Model-Specific Registers.
+ * @param handle - a handle to an open MSR driver, @see cpu_msr_driver_open
+ * @param which - which info field should be returned. A list of
+ * available information entities is listed in the
+ * cpu_msrinfo_request_t enum.
+ * @retval - if the requested information is available for the current
+ * processor model, the respective value is returned.
+ * if no information is available, or the CPU doesn't support
+ * the query, the special value CPU_INVALID_VALUE is returned
+ * @note This function is not MT-safe. If you intend to call it from multiple
+ * threads, guard it through a mutex or a similar primitive.
+ */
+int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which);
+#define CPU_INVALID_VALUE 0x3fffffff
+
+/**
+ * @brief Writes the raw MSR data to a text file
+ * @param data - a pointer to msr_driver_t structure
+ * @param filename - the path of the file, where the serialized data should be
+ * written. If empty, stdout will be used.
+ * @note This is intended primarily for debugging. On some processor, which is
+ * not currently supported or not completely recognized by cpu_identify,
+ * one can still successfully get the raw data and write it to a file.
+ * libcpuid developers can later import this file and debug the detection
+ * code as if running on the actual hardware.
+ * The file is simple text format of "something=value" pairs. Version info
+ * is also written, but the format is not intended to be neither backward-
+ * nor forward compatible.
+ * @returns zero if successful, and some negative number on error.
+ * The error message can be obtained by calling \ref cpuid_error.
+ * @see cpu_error_t
+ */
+int msr_serialize_raw_data(struct msr_driver_t* handle, const char* filename);
+
+/**
+ * @brief Closes an open MSR driver
+ *
+ * This function unloads the MSR driver opened by cpu_msr_driver_open and
+ * frees any resources associated with it.
+ *
+ * @param handle - a handle to the MSR reader driver, as created by
+ * cpu_msr_driver_open
+ *
+ * @returns zero if successful, and some negative number on error.
+ * The error message can be obtained by calling \ref cpuid_error.
+ * @see cpu_error_t
+ */
+int cpu_msr_driver_close(struct msr_driver_t* handle);
+
#ifdef __cplusplus
}; /* extern "C" */
#endif
diff --git a/src/3rdparty/libcpuid/libcpuid_types.h b/src/3rdparty/libcpuid/libcpuid_types.h
index 9e897275..b0923cc6 100644
--- a/src/3rdparty/libcpuid/libcpuid_types.h
+++ b/src/3rdparty/libcpuid/libcpuid_types.h
@@ -32,6 +32,36 @@
#ifndef __LIBCPUID_TYPES_H__
#define __LIBCPUID_TYPES_H__
-#include
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#if defined(HAVE_STDINT_H)
+# include
+#else
+/* we have to provide our own: */
+# if !defined(HAVE_INT32_T) && !defined(__int32_t_defined)
+typedef int int32_t;
+# endif
+
+# if !defined(HAVE_UINT32_T) && !defined(__uint32_t_defined)
+typedef unsigned uint32_t;
+# endif
+
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+#if (defined _MSC_VER) && (_MSC_VER <= 1300)
+/* MSVC 6.0: no long longs ... */
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+/* all other sane compilers: */
+typedef signed long long int64_t;
+typedef unsigned long long uint64_t;
+#endif
+
+#endif
#endif /* __LIBCPUID_TYPES_H__ */
diff --git a/src/3rdparty/libcpuid/libcpuid_util.c b/src/3rdparty/libcpuid/libcpuid_util.c
index 90ac5125..8d4ca03d 100644
--- a/src/3rdparty/libcpuid/libcpuid_util.c
+++ b/src/3rdparty/libcpuid/libcpuid_util.c
@@ -32,6 +32,8 @@
#include "libcpuid.h"
#include "libcpuid_util.h"
+int _current_verboselevel;
+
void match_features(const struct feature_map_t* matchtable, int count, uint32_t reg, struct cpu_id_t* data)
{
int i;
@@ -42,6 +44,165 @@ void match_features(const struct feature_map_t* matchtable, int count, uint32_t
}
}
+static void default_warn(const char* msg)
+{
+ fprintf(stderr, "%s", msg);
+}
+
+libcpuid_warn_fn_t _warn_fun = default_warn;
+
+#if defined(_MSC_VER)
+# define vsnprintf _vsnprintf
+#endif
+void warnf(const char* format, ...)
+{
+ char buff[1024];
+ va_list va;
+ if(!_warn_fun)
+ {
+ return;
+ }
+ va_start(va, format);
+ vsnprintf(buff, sizeof(buff), format, va);
+ va_end(va);
+ _warn_fun(buff);
+}
+
+void debugf(int verboselevel, const char* format, ...)
+{
+ char buff[1024];
+ va_list va;
+ if(verboselevel > _current_verboselevel)
+ {
+ return;
+ }
+ va_start(va, format);
+ vsnprintf(buff, sizeof(buff), format, va);
+ va_end(va);
+ _warn_fun(buff);
+}
+
+static int popcount64(uint64_t mask)
+{
+ int num_set_bits = 0;
+
+ while(mask)
+ {
+ mask &= mask - 1;
+ num_set_bits++;
+ }
+
+ return num_set_bits;
+}
+
+static int score(const struct match_entry_t* entry, const struct cpu_id_t* data,
+ int brand_code, uint64_t bits, int model_code)
+{
+ int res = 0;
+ if(entry->family == data->family)
+ {
+ res += 2;
+ }
+ if(entry->model == data->model)
+ {
+ res += 2;
+ }
+ if(entry->stepping == data->stepping)
+ {
+ res += 2;
+ }
+ if(entry->ext_family == data->ext_family)
+ {
+ res += 2;
+ }
+ if(entry->ext_model == data->ext_model)
+ {
+ res += 2;
+ }
+ if(entry->ncores == data->num_cores)
+ {
+ res += 2;
+ }
+ if(entry->l2cache == data->l2_cache)
+ {
+ res += 1;
+ }
+ if(entry->l3cache == data->l3_cache)
+ {
+ res += 1;
+ }
+ if(entry->brand_code == brand_code)
+ {
+ res += 2;
+ }
+ if(entry->model_code == model_code)
+ {
+ res += 2;
+ }
+
+ res += popcount64(entry->model_bits & bits) * 2;
+ return res;
+}
+
+int match_cpu_codename(const struct match_entry_t* matchtable, int count,
+ struct cpu_id_t* data, int brand_code, uint64_t bits,
+ int model_code)
+{
+ int bestscore = -1;
+ int bestindex = 0;
+ int i, t;
+
+ debugf(3, "Matching cpu f:%d, m:%d, s:%d, xf:%d, xm:%d, ncore:%d, l2:%d, bcode:%d, bits:%I64u, code:%d\n",
+ data->family, data->model, data->stepping, data->ext_family,
+ data->ext_model, data->num_cores, data->l2_cache, brand_code, (unsigned long long) bits, model_code);
+
+ for(i = 0; i < count; i++)
+ {
+ t = score(&matchtable[i], data, brand_code, bits, model_code);
+ debugf(3, "Entry %d, `%s', score %d\n", i, matchtable[i].name, t);
+ if(t > bestscore)
+ {
+ debugf(2, "Entry `%s' selected - best score so far (%d)\n", matchtable[i].name, t);
+ bestscore = t;
+ bestindex = i;
+ }
+ }
+ strcpy(data->cpu_codename, matchtable[bestindex].name);
+ return bestscore;
+}
+
+void generic_get_cpu_list(const struct match_entry_t* matchtable, int count,
+ struct cpu_list_t* list)
+{
+ int i, j, n, good;
+ n = 0;
+ list->names = (char**) malloc(sizeof(char*) * count);
+ for(i = 0; i < count; i++)
+ {
+ if(strstr(matchtable[i].name, "Unknown"))
+ {
+ continue;
+ }
+ good = 1;
+ for(j = n - 1; j >= 0; j--)
+ if(!strcmp(list->names[j], matchtable[i].name))
+ {
+ good = 0;
+ break;
+ }
+ if(!good)
+ {
+ continue;
+ }
+#if defined(_MSC_VER)
+ list->names[n++] = _strdup(matchtable[i].name);
+#else
+ list->names[n++] = strdup(matchtable[i].name);
+#endif
+ }
+ list->num_entries = n;
+}
+
static int xmatch_entry(char c, const char* p)
{
int i, j;
@@ -126,3 +287,21 @@ int match_all(uint64_t bits, uint64_t mask)
{
return (bits & mask) == mask;
}
+
+void debug_print_lbits(int debuglevel, uint64_t mask)
+{
+ int i, first = 0;
+ for(i = 0; i < 64; i++) if(mask & (((uint64_t) 1) << i))
+ {
+ if(first)
+ {
+ first = 0;
+ }
+ else
+ {
+ debugf(2, " + ");
+ }
+ debugf(2, "LBIT(%d)", i);
+ }
+ debugf(2, "\n");
+}
diff --git a/src/3rdparty/libcpuid/libcpuid_util.h b/src/3rdparty/libcpuid/libcpuid_util.h
index eaff1430..9c75435e 100644
--- a/src/3rdparty/libcpuid/libcpuid_util.h
+++ b/src/3rdparty/libcpuid/libcpuid_util.h
@@ -50,6 +50,20 @@ struct match_entry_t
int match_cpu_codename(const struct match_entry_t* matchtable, int count,
struct cpu_id_t* data, int brand_code, uint64_t bits,
int model_code);
+
+void warnf(const char* format, ...)
+#ifdef __GNUC__
+__attribute__((format(printf, 1, 2)))
+#endif
+;
+void debugf(int verboselevel, const char* format, ...)
+#ifdef __GNUC__
+__attribute__((format(printf, 2, 3)))
+#endif
+;
+void generic_get_cpu_list(const struct match_entry_t* matchtable, int count,
+ struct cpu_list_t* list);
+
/*
* Seek for a pattern in `haystack'.
* Pattern may be an fixed string, or contain the special metacharacters
@@ -72,9 +86,15 @@ struct cpu_id_t* get_cached_cpuid(void);
/* returns true if all bits of mask are present in `bits'. */
int match_all(uint64_t bits, uint64_t mask);
+/* print what bits a mask consists of */
+void debug_print_lbits(int debuglevel, uint64_t mask);
+
/*
* Sets the current errno
*/
int set_error(cpu_error_t err);
+extern libcpuid_warn_fn_t _warn_fun;
+extern int _current_verboselevel;
+
#endif /* __LIBCPUID_UTIL_H__ */
diff --git a/src/3rdparty/libcpuid/msrdriver.c b/src/3rdparty/libcpuid/msrdriver.c
new file mode 100644
index 00000000..9dc42bdd
--- /dev/null
+++ b/src/3rdparty/libcpuid/msrdriver.c
@@ -0,0 +1,595 @@
+/*
+ * Copyright 2009 Veselin Georgiev,
+ * anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @File msrdriver.c
+ * @Brief Contains the binary images of the x86 and x64 MSR drivers for Windows
+ * @Date 2009-09-29
+ *
+ * The driver is courtesy of Nick 'Bombera' Gabareff, and its source is actually
+ * available, see the contrib/ dir.
+ *
+ * However, for simplicity, here we just include the images of the compiled .SYS
+ * files.
+ * They are extracted to the filesystem on demand and loaded in the kernel
+ * by the cpu_msr_driver_open() function
+ */
+#ifdef _WIN32
+#include "asm-bits.h"
+//begin {
+int cc_x86driver_code_size = 4608;
+uint8_t cc_x86driver_code[4608] =
+{
+ 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xb8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd,
+ 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d,
+ 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e, 0x20,
+ 0x44, 0x4f, 0x53, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x9f, 0x99, 0x48, 0xdf, 0xdb, 0xf8, 0x26, 0x8c, 0xdb, 0xf8, 0x26, 0x8c, 0xdb, 0xf8, 0x26, 0x8c,
+ 0xdb, 0xf8, 0x27, 0x8c, 0xdd, 0xf8, 0x26, 0x8c, 0x21, 0xdb, 0x3f, 0x8c, 0xd8, 0xf8, 0x26, 0x8c, 0xfc, 0x3e,
+ 0x57, 0x8c, 0xda, 0xf8, 0x26, 0x8c, 0xfc, 0x3e, 0x5a, 0x8c, 0xda, 0xf8, 0x26, 0x8c, 0xfc, 0x3e, 0x5e, 0x8c,
+ 0xda, 0xf8, 0x26, 0x8c, 0x52, 0x69, 0x63, 0x68, 0xdb, 0xf8, 0x26, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x4c, 0x01, 0x07, 0x00, 0x12, 0x9b, 0x9b, 0x4a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x02, 0x21, 0x0b, 0x01, 0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0xa9, 0xd1, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xc0, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x70, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x74,
+ 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
+ 0x00, 0x68, 0x2e, 0x72, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0x00, 0x00, 0x48, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xc8, 0x50, 0x41, 0x47, 0x45, 0x30, 0x44, 0x45, 0x46,
+ 0x8c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x49, 0x4e, 0x49, 0x54,
+ 0x00, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xe2,
+ 0x2e, 0x72, 0x73, 0x72, 0x63, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x42, 0x2e, 0x72, 0x65, 0x6c, 0x6f, 0x63, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x4c,
+ 0x24, 0x08, 0x83, 0x61, 0x18, 0x00, 0x83, 0x61, 0x1c, 0x00, 0x32, 0xd2, 0xff, 0x15, 0x08, 0x20, 0x01, 0x00,
+ 0x33, 0xc0, 0xc2, 0x08, 0x00, 0x56, 0x8b, 0x74, 0x24, 0x0c, 0x8b, 0x46, 0x60, 0x81, 0x78, 0x0c, 0x0c, 0xe0,
+ 0x22, 0x00, 0x57, 0x75, 0x3c, 0x83, 0x78, 0x04, 0x08, 0x72, 0x36, 0x83, 0x78, 0x08, 0x04, 0x75, 0x07, 0x8b,
+ 0x46, 0x0c, 0x8b, 0x08, 0xeb, 0x05, 0xb9, 0x9c, 0x01, 0x00, 0x00, 0x8b, 0x7e, 0x0c, 0x0f, 0x32, 0x89, 0x07,
+ 0x89, 0x57, 0x04, 0xc7, 0x46, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x33, 0xff, 0x32, 0xd2, 0x8b, 0xce, 0xff, 0x15,
+ 0x08, 0x20, 0x01, 0x00, 0x8b, 0xc7, 0x5f, 0x5e, 0xc2, 0x08, 0x00, 0x83, 0x66, 0x1c, 0x00, 0xbf, 0x01, 0x00,
+ 0x00, 0xc0, 0x89, 0x7e, 0x18, 0xeb, 0xe1, 0x55, 0x8b, 0xec, 0x51, 0x51, 0x8b, 0x45, 0x08, 0xff, 0x70, 0x04,
+ 0xff, 0x15, 0x04, 0x20, 0x01, 0x00, 0x68, 0x3c, 0x20, 0x01, 0x00, 0x8d, 0x45, 0xf8, 0x50, 0xff, 0x15, 0x00,
+ 0x20, 0x01, 0x00, 0x8d, 0x45, 0xf8, 0x50, 0xff, 0x15, 0x14, 0x20, 0x01, 0x00, 0xc9, 0xc2, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x50, 0x00, 0x00, 0x74, 0x50, 0x00, 0x00, 0x86, 0x50, 0x00, 0x00,
+ 0x9c, 0x50, 0x00, 0x00, 0xb4, 0x50, 0x00, 0x00, 0x44, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00,
+ 0x44, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x5c, 0x00, 0x54, 0x00, 0x6d, 0x00,
+ 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x44, 0x00, 0x6f, 0x00,
+ 0x73, 0x00, 0x44, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x5c, 0x00,
+ 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x8b, 0xec, 0x83,
+ 0xec, 0x14, 0x56, 0x8b, 0x35, 0x00, 0x20, 0x01, 0x00, 0x57, 0x68, 0x1c, 0x20, 0x01, 0x00, 0x8d, 0x45, 0xf4,
+ 0x50, 0xff, 0xd6, 0x8b, 0x7d, 0x08, 0x8d, 0x45, 0xfc, 0x50, 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x22, 0x8d, 0x45,
+ 0xf4, 0x50, 0x6a, 0x04, 0x57, 0xff, 0x15, 0x10, 0x20, 0x01, 0x00, 0x85, 0xc0, 0x75, 0x4f, 0x68, 0x3c, 0x20,
+ 0x01, 0x00, 0x8d, 0x45, 0xec, 0x50, 0xff, 0xd6, 0x8d, 0x45, 0xf4, 0x50, 0x8d, 0x45, 0xec, 0x50, 0xff, 0x15,
+ 0x0c, 0x20, 0x01, 0x00, 0x8b, 0xf0, 0x85, 0xf6, 0x74, 0x0d, 0xff, 0x75, 0xfc, 0xff, 0x15, 0x04, 0x20, 0x01,
+ 0x00, 0x8b, 0xc6, 0xeb, 0x23, 0x8b, 0x45, 0xfc, 0xa3, 0x00, 0x30, 0x01, 0x00, 0xb8, 0x00, 0x10, 0x01, 0x00,
+ 0x89, 0x47, 0x38, 0x89, 0x47, 0x40, 0xc7, 0x47, 0x34, 0x75, 0x10, 0x01, 0x00, 0xc7, 0x47, 0x70, 0x19, 0x10,
+ 0x01, 0x00, 0x33, 0xc0, 0x5f, 0x5e, 0xc9, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x28, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x50,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x50, 0x00, 0x00, 0x74, 0x50, 0x00, 0x00, 0x86, 0x50,
+ 0x00, 0x00, 0x9c, 0x50, 0x00, 0x00, 0xb4, 0x50, 0x00, 0x00, 0x44, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4b, 0x01, 0x49, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x63,
+ 0x4c, 0x69, 0x6e, 0x6b, 0x00, 0x00, 0x0b, 0x04, 0x52, 0x74, 0x6c, 0x49, 0x6e, 0x69, 0x74, 0x55, 0x6e, 0x69,
+ 0x63, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x49, 0x01, 0x49, 0x6f, 0x44, 0x65,
+ 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0xda, 0x01, 0x49, 0x6f, 0x66, 0x43,
+ 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, 0x00, 0x41, 0x01,
+ 0x49, 0x6f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x63, 0x4c, 0x69,
+ 0x6e, 0x6b, 0x00, 0x00, 0x38, 0x01, 0x49, 0x6f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x00, 0x00, 0x6e, 0x74, 0x6f, 0x73, 0x6b, 0x72, 0x6e, 0x6c, 0x2e, 0x65, 0x78, 0x65, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x09, 0x04, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x5c, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5c, 0x03, 0x34, 0x00, 0x00, 0x00, 0x56, 0x00, 0x53, 0x00, 0x5f, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00,
+ 0x53, 0x00, 0x49, 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x5f, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x46, 0x00, 0x4f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xbd, 0x04, 0xef, 0xfe, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xba, 0x02, 0x00, 0x00, 0x01, 0x00, 0x53, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00,
+ 0x67, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00,
+ 0x00, 0x00, 0x96, 0x02, 0x00, 0x00, 0x01, 0x00, 0x30, 0x00, 0x34, 0x00, 0x30, 0x00, 0x39, 0x00, 0x30, 0x00,
+ 0x34, 0x00, 0x62, 0x00, 0x30, 0x00, 0x00, 0x00, 0x58, 0x00, 0x20, 0x00, 0x01, 0x00, 0x43, 0x00, 0x6f, 0x00,
+ 0x6d, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x53, 0x00,
+ 0x52, 0x00, 0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00,
+ 0x33, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x62, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6b, 0x00, 0x65, 0x00,
+ 0x72, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x64, 0x00, 0x72, 0x00, 0x69, 0x00, 0x76, 0x00,
+ 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x42, 0x00, 0x11, 0x00, 0x01, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6d, 0x00,
+ 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x79, 0x00, 0x4e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x49, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x53, 0x00, 0x74, 0x00, 0x65, 0x00,
+ 0x65, 0x00, 0x64, 0x00, 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x44, 0x00,
+ 0x65, 0x00, 0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x69, 0x00, 0x70, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00,
+ 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00,
+ 0x20, 0x00, 0x33, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x62, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x4b, 0x00,
+ 0x65, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x64, 0x00,
+ 0x75, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x36, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00,
+ 0x6c, 0x00, 0x65, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00,
+ 0x2c, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x07, 0x00, 0x01, 0x00, 0x49, 0x00,
+ 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x4e, 0x00, 0x61, 0x00,
+ 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x13, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x65, 0x00, 0x67, 0x00, 0x61, 0x00,
+ 0x6c, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00,
+ 0x74, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x69, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x47, 0x00, 0x61, 0x00,
+ 0x62, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x76, 0x00, 0x20, 0x00, 0x27, 0x00, 0x32, 0x00, 0x30, 0x00,
+ 0x30, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x4f, 0x00, 0x72, 0x00,
+ 0x69, 0x00, 0x67, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00,
+ 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00,
+ 0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x2e, 0x00, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x54, 0x00, 0x1a, 0x00, 0x01, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00, 0x63, 0x00,
+ 0x74, 0x00, 0x4e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x6f, 0x00,
+ 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x32, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x70, 0x00,
+ 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x52, 0x00,
+ 0x65, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x0b, 0x00, 0x01, 0x00,
+ 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00, 0x63, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00,
+ 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x2c, 0x00, 0x20, 0x00,
+ 0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x00, 0x61, 0x00, 0x72, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00,
+ 0x65, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x54, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x74, 0x00,
+ 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x10, 0x30, 0x5c, 0x30, 0x82, 0x30, 0x87, 0x30, 0x91, 0x30, 0x9b, 0x30, 0x00, 0x40, 0x00, 0x00, 0x1c, 0x00,
+ 0x00, 0x00, 0x09, 0x30, 0x0f, 0x30, 0x2f, 0x30, 0x38, 0x30, 0x4c, 0x30, 0x5b, 0x30, 0x67, 0x30, 0x6c, 0x30,
+ 0x79, 0x30, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+int cc_x64driver_code_size = 5120;
+uint8_t cc_x64driver_code[5120] =
+{
+ 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xb8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd,
+ 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d,
+ 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e, 0x20,
+ 0x44, 0x4f, 0x53, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xb7, 0x04, 0xa8, 0xc2, 0xf3, 0x65, 0xc6, 0x91, 0xf3, 0x65, 0xc6, 0x91, 0xf3, 0x65, 0xc6, 0x91,
+ 0xf3, 0x65, 0xc7, 0x91, 0xf4, 0x65, 0xc6, 0x91, 0x85, 0xf8, 0xbd, 0x91, 0xf0, 0x65, 0xc6, 0x91, 0x85, 0xf8,
+ 0xab, 0x91, 0xf0, 0x65, 0xc6, 0x91, 0x30, 0x6a, 0x98, 0x91, 0xf2, 0x65, 0xc6, 0x91, 0x85, 0xf8, 0xbe, 0x91,
+ 0xf2, 0x65, 0xc6, 0x91, 0x52, 0x69, 0x63, 0x68, 0xf3, 0x65, 0xc6, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x64, 0x86, 0x07, 0x00,
+ 0x41, 0xc8, 0x6d, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x22, 0x00, 0x0b, 0x02,
+ 0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x60, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x79, 0x44, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x60, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x00, 0x70, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00,
+ 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x68, 0x2e, 0x72, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0xf0, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x48, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x00,
+ 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xc8, 0x2e, 0x70,
+ 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+ 0x00, 0x48, 0x50, 0x41, 0x47, 0x45, 0x30, 0x44, 0x45, 0x46, 0x4e, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x49, 0x4e, 0x49, 0x54, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xe2, 0x2e, 0x72, 0x73, 0x72, 0x63, 0x00, 0x00, 0x00,
+ 0xc0, 0x03, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0xec, 0x28,
+ 0x33, 0xc9, 0x48, 0x8b, 0xc2, 0x89, 0x4a, 0x30, 0x48, 0x89, 0x4a, 0x38, 0x33, 0xd2, 0x48, 0x8b, 0xc8, 0xff,
+ 0x15, 0xfd, 0x0f, 0x00, 0x00, 0x33, 0xc0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x48, 0x83, 0xec, 0x28, 0x48, 0x8b, 0x82, 0xb8, 0x00, 0x00,
+ 0x00, 0x4c, 0x8b, 0xca, 0x81, 0x78, 0x18, 0x0c, 0xe0, 0x22, 0x00, 0x75, 0x43, 0x83, 0x78, 0x08, 0x08, 0x72,
+ 0x3d, 0x83, 0x78, 0x10, 0x04, 0x75, 0x08, 0x48, 0x8b, 0x42, 0x18, 0x8b, 0x08, 0xeb, 0x05, 0xb9, 0x9c, 0x01,
+ 0x00, 0x00, 0x4c, 0x8b, 0x42, 0x18, 0x0f, 0x32, 0x48, 0xc1, 0xe2, 0x20, 0x49, 0x8b, 0xc9, 0x48, 0x0b, 0xc2,
+ 0x33, 0xd2, 0x49, 0x89, 0x00, 0x49, 0xc7, 0x41, 0x38, 0x08, 0x00, 0x00, 0x00, 0xff, 0x15, 0x95, 0x0f, 0x00,
+ 0x00, 0x33, 0xc0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0xc7, 0x42, 0x30, 0x01, 0x00, 0x00, 0xc0, 0x48, 0xc7, 0x42,
+ 0x38, 0x00, 0x00, 0x00, 0x00, 0x49, 0x8b, 0xc9, 0x33, 0xd2, 0xff, 0x15, 0x74, 0x0f, 0x00, 0x00, 0xb8, 0x01,
+ 0x00, 0x00, 0xc0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x48, 0x83, 0xec, 0x38, 0x48, 0x8b, 0x49, 0x08, 0xff, 0x15,
+ 0x32, 0x0f, 0x00, 0x00, 0x48, 0x8d, 0x15, 0x1b, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x4c, 0x24, 0x20, 0xff, 0x15,
+ 0x18, 0x0f, 0x00, 0x00, 0x48, 0x8d, 0x4c, 0x24, 0x20, 0xff, 0x15, 0x05, 0x0f, 0x00, 0x00, 0x48, 0x83, 0xc4,
+ 0x38, 0xc3, 0x5c, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x44, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00,
+ 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x16, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x61, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x41, 0xc8, 0x6d, 0x49, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00,
+ 0x5c, 0x20, 0x00, 0x00, 0x5c, 0x06, 0x00, 0x00, 0x52, 0x53, 0x44, 0x53, 0xd9, 0x5e, 0xab, 0x47, 0xc4, 0xf2,
+ 0x4f, 0x40, 0xaa, 0xe9, 0x90, 0x47, 0x67, 0x30, 0xa5, 0xfa, 0x03, 0x00, 0x00, 0x00, 0x44, 0x3a, 0x5c, 0x74,
+ 0x6d, 0x70, 0x5c, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5c, 0x6f, 0x62, 0x6a, 0x66, 0x72, 0x65, 0x5f, 0x77,
+ 0x6e, 0x65, 0x74, 0x5f, 0x41, 0x4d, 0x44, 0x36, 0x34, 0x5c, 0x61, 0x6d, 0x64, 0x36, 0x34, 0x5c, 0x54, 0x6d,
+ 0x70, 0x52, 0x64, 0x72, 0x2e, 0x70, 0x64, 0x62, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x04, 0x42,
+ 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x04, 0x42, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x04, 0x62, 0x00, 0x00,
+ 0x21, 0x00, 0x00, 0x00, 0x10, 0x50, 0x00, 0x00, 0x74, 0x50, 0x00, 0x00, 0xe4, 0x20, 0x00, 0x00, 0x21, 0x08,
+ 0x02, 0x00, 0x08, 0x74, 0x13, 0x00, 0x10, 0x50, 0x00, 0x00, 0x74, 0x50, 0x00, 0x00, 0xe4, 0x20, 0x00, 0x00,
+ 0x01, 0x0c, 0x03, 0x00, 0x0c, 0x34, 0x12, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xcd, 0x5d, 0x20, 0xd2, 0x66, 0xd4, 0xff, 0xff, 0x32, 0xa2, 0xdf, 0x2d, 0x99, 0x2b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0xa8, 0x20, 0x00, 0x00, 0x40, 0x10,
+ 0x00, 0x00, 0xbe, 0x10, 0x00, 0x00, 0xb0, 0x20, 0x00, 0x00, 0xd0, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
+ 0xb8, 0x20, 0x00, 0x00, 0x10, 0x50, 0x00, 0x00, 0x74, 0x50, 0x00, 0x00, 0xe4, 0x20, 0x00, 0x00, 0x74, 0x50,
+ 0x00, 0x00, 0xe8, 0x50, 0x00, 0x00, 0xd0, 0x20, 0x00, 0x00, 0xe8, 0x50, 0x00, 0x00, 0xf5, 0x50, 0x00, 0x00,
+ 0xc0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0xec, 0x78, 0x48, 0x89, 0x9c, 0x24,
+ 0x90, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xd9, 0x48, 0x8d, 0x15, 0x0a, 0x01, 0x00, 0x00, 0x48, 0x8d, 0x4c, 0x24,
+ 0x48, 0xff, 0x15, 0xd7, 0xcf, 0xff, 0xff, 0x41, 0xb9, 0x22, 0x00, 0x00, 0x00, 0x4c, 0x8d, 0x5c, 0x24, 0x40,
+ 0x4c, 0x89, 0x5c, 0x24, 0x30, 0x4c, 0x8d, 0x44, 0x24, 0x48, 0x41, 0x8d, 0x51, 0xe6, 0x48, 0x8b, 0xcb, 0xc6,
+ 0x44, 0x24, 0x28, 0x00, 0xc7, 0x44, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0xff, 0x15, 0xc0, 0xcf, 0xff, 0xff,
+ 0x85, 0xc0, 0x0f, 0x85, 0x80, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x15, 0x91, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x4c,
+ 0x24, 0x58, 0x48, 0x89, 0xbc, 0x24, 0x98, 0x00, 0x00, 0x00, 0xff, 0x15, 0x86, 0xcf, 0xff, 0xff, 0x48, 0x8d,
+ 0x54, 0x24, 0x48, 0x48, 0x8d, 0x4c, 0x24, 0x58, 0xff, 0x15, 0x86, 0xcf, 0xff, 0xff, 0x85, 0xc0, 0x8b, 0xf8,
+ 0x74, 0x0f, 0x48, 0x8b, 0x4c, 0x24, 0x40, 0xff, 0x15, 0x6d, 0xcf, 0xff, 0xff, 0x8b, 0xc7, 0xeb, 0x39, 0x48,
+ 0x8b, 0x44, 0x24, 0x40, 0x48, 0x89, 0x05, 0x5d, 0xe0, 0xff, 0xff, 0x48, 0x8d, 0x05, 0x16, 0xc0, 0xff, 0xff,
+ 0x48, 0x89, 0x43, 0x68, 0x48, 0x8d, 0x05, 0x4b, 0xbf, 0xff, 0xff, 0x48, 0x89, 0x43, 0x70, 0x48, 0x89, 0x83,
+ 0x80, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x05, 0x69, 0xbf, 0xff, 0xff, 0x48, 0x89, 0x83, 0xe0, 0x00, 0x00, 0x00,
+ 0x33, 0xc0, 0x48, 0x8b, 0xbc, 0x24, 0x98, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x9c, 0x24, 0x90, 0x00, 0x00, 0x00,
+ 0x48, 0x83, 0xc4, 0x78, 0xc3, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x5c, 0x00,
+ 0x44, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x44, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00,
+ 0x73, 0x00, 0x5c, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x00, 0x00,
+ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x5c, 0x00, 0x44, 0x00, 0x65, 0x00, 0x76, 0x00,
+ 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x5c, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x48, 0x8b, 0x05, 0xf1, 0xd0, 0xff, 0xff, 0x49, 0xb9, 0x32, 0xa2, 0xdf, 0x2d, 0x99, 0x2b, 0x00, 0x00, 0x48,
+ 0x85, 0xc0, 0x74, 0x05, 0x49, 0x3b, 0xc1, 0x75, 0x2f, 0x4c, 0x8d, 0x05, 0xd6, 0xd0, 0xff, 0xff, 0x48, 0xb8,
+ 0x20, 0x03, 0x00, 0x00, 0x80, 0xf7, 0xff, 0xff, 0x48, 0x8b, 0x00, 0x49, 0x33, 0xc0, 0x49, 0xb8, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x49, 0x23, 0xc0, 0x49, 0x0f, 0x44, 0xc1, 0x48, 0x89, 0x05, 0xae, 0xd0,
+ 0xff, 0xff, 0x48, 0xf7, 0xd0, 0x48, 0x89, 0x05, 0x9c, 0xd0, 0xff, 0xff, 0xe9, 0xa7, 0xef, 0xff, 0xff, 0xcc,
+ 0xcc, 0xcc, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x61, 0x00, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfe, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x61,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x60, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x01, 0x49, 0x6f, 0x66, 0x43,
+ 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, 0x00, 0x61, 0x01,
+ 0x49, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x63, 0x4c, 0x69,
+ 0x6e, 0x6b, 0x00, 0x00, 0x3e, 0x04, 0x52, 0x74, 0x6c, 0x49, 0x6e, 0x69, 0x74, 0x55, 0x6e, 0x69, 0x63, 0x6f,
+ 0x64, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x5f, 0x01, 0x49, 0x6f, 0x44, 0x65, 0x6c, 0x65,
+ 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x55, 0x01, 0x49, 0x6f, 0x43, 0x72, 0x65, 0x61,
+ 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x63, 0x4c, 0x69, 0x6e, 0x6b, 0x00, 0x00, 0x4c, 0x01,
+ 0x49, 0x6f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x6e, 0x74,
+ 0x6f, 0x73, 0x6b, 0x72, 0x6e, 0x6c, 0x2e, 0x65, 0x78, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x09, 0x04, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x60, 0x70, 0x00, 0x00, 0x60, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03,
+ 0x34, 0x00, 0x00, 0x00, 0x56, 0x00, 0x53, 0x00, 0x5f, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00, 0x53, 0x00,
+ 0x49, 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x5f, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x46, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xbd, 0x04, 0xef, 0xfe, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xbe, 0x02, 0x00, 0x00, 0x01, 0x00, 0x53, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00,
+ 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x00, 0x00,
+ 0x9a, 0x02, 0x00, 0x00, 0x01, 0x00, 0x30, 0x00, 0x34, 0x00, 0x30, 0x00, 0x39, 0x00, 0x30, 0x00, 0x34, 0x00,
+ 0x62, 0x00, 0x30, 0x00, 0x00, 0x00, 0x58, 0x00, 0x20, 0x00, 0x01, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6d, 0x00,
+ 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x53, 0x00, 0x52, 0x00,
+ 0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x36, 0x00,
+ 0x34, 0x00, 0x2d, 0x00, 0x62, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6b, 0x00, 0x65, 0x00, 0x72, 0x00,
+ 0x6e, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x64, 0x00, 0x72, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0x42, 0x00, 0x11, 0x00, 0x01, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00,
+ 0x61, 0x00, 0x6e, 0x00, 0x79, 0x00, 0x4e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x49, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x53, 0x00, 0x74, 0x00, 0x65, 0x00, 0x65, 0x00,
+ 0x64, 0x00, 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x60, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x44, 0x00, 0x65, 0x00,
+ 0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x69, 0x00, 0x70, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x20, 0x00,
+ 0x36, 0x00, 0x34, 0x00, 0x2d, 0x00, 0x62, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x4b, 0x00, 0x65, 0x00,
+ 0x72, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00,
+ 0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x36, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00,
+ 0x65, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x31, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00, 0x2c, 0x00,
+ 0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x07, 0x00, 0x01, 0x00, 0x49, 0x00, 0x6e, 0x00,
+ 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x4e, 0x00, 0x61, 0x00, 0x6d, 0x00,
+ 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x4a, 0x00, 0x13, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x65, 0x00, 0x67, 0x00, 0x61, 0x00, 0x6c, 0x00,
+ 0x43, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, 0x00,
+ 0x00, 0x00, 0x4e, 0x00, 0x69, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x47, 0x00, 0x61, 0x00, 0x62, 0x00,
+ 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x76, 0x00, 0x20, 0x00, 0x27, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00,
+ 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x4f, 0x00, 0x72, 0x00, 0x69, 0x00,
+ 0x67, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00,
+ 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00,
+ 0x64, 0x00, 0x72, 0x00, 0x36, 0x00, 0x34, 0x00, 0x2e, 0x00, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x54, 0x00, 0x1a, 0x00, 0x01, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00,
+ 0x63, 0x00, 0x74, 0x00, 0x4e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00,
+ 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x32, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, 0x00, 0x6d, 0x00,
+ 0x70, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00,
+ 0x52, 0x00, 0x65, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x0b, 0x00,
+ 0x01, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00, 0x63, 0x00, 0x74, 0x00, 0x56, 0x00,
+ 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x2c, 0x00,
+ 0x20, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x00, 0x61, 0x00, 0x72, 0x00, 0x46, 0x00, 0x69, 0x00,
+ 0x6c, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x54, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x6c, 0x00, 0x61, 0x00,
+ 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0xb0, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+//} end
+#endif // _WIN32
+
+int msrdriver_dummy; // a dummy to avoid a linker warning on OS X.
diff --git a/src/3rdparty/libcpuid/rdmsr.c b/src/3rdparty/libcpuid/rdmsr.c
new file mode 100644
index 00000000..60a75600
--- /dev/null
+++ b/src/3rdparty/libcpuid/rdmsr.c
@@ -0,0 +1,1291 @@
+/*
+ * Copyright 2009 Veselin Georgiev,
+ * anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#define _XOPEN_SOURCE 500
+#include
+#include
+#include
+#include "libcpuid.h"
+#include "asm-bits.h"
+#include "libcpuid_util.h"
+#include "libcpuid_internal.h"
+#include "rdtsc.h"
+
+#if defined (__linux__) || defined (__gnu_linux__)
+/* Assuming linux with /dev/cpu/x/msr: */
+#include
+#include
+#include
+#include
+#include
+#include
+struct msr_driver_t
+{
+ int fd;
+};
+static int rdmsr_supported(void);
+static int load_driver(char* msr_path)
+{
+ const int file_exists = !access(msr_path, F_OK);
+ const int file_readable = !access(msr_path, R_OK);
+
+ if(file_exists && file_readable)
+ {
+ return 1;
+ }
+ else if(file_exists && !file_readable)
+ {
+ return 0;
+ }
+ else if(getuid() != 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return !system("modprobe msr 2> /dev/null");
+ }
+}
+
+struct msr_driver_t* cpu_msr_driver_open(void)
+{
+ return cpu_msr_driver_open_core(0);
+}
+
+struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num)
+{
+ char msr[32];
+ struct msr_driver_t* handle;
+ if(core_num >= cpuid_get_total_cpus())
+ {
+ set_error(ERR_INVCNB);
+ return NULL;
+ }
+ if(!rdmsr_supported())
+ {
+ set_error(ERR_NO_RDMSR);
+ return NULL;
+ }
+ sprintf(msr, "/dev/cpu/%u/msr", core_num);
+ if(!load_driver(msr))
+ {
+ set_error(ERR_NO_DRIVER);
+ return NULL;
+ }
+ int fd = open(msr, O_RDONLY);
+ if(fd < 0)
+ {
+ if(errno == EIO)
+ {
+ set_error(ERR_NO_RDMSR);
+ return NULL;
+ }
+ set_error(ERR_NO_DRIVER);
+ return NULL;
+ }
+ handle = (struct msr_driver_t*) malloc(sizeof(struct msr_driver_t));
+ handle->fd = fd;
+ return handle;
+}
+
+int cpu_rdmsr(struct msr_driver_t* driver, uint32_t msr_index, uint64_t* result)
+{
+ ssize_t ret;
+
+ if(!driver || driver->fd < 0)
+ {
+ return set_error(ERR_HANDLE);
+ }
+ ret = pread(driver->fd, result, 8, msr_index);
+ if(ret != 8)
+ {
+ return set_error(ERR_INVMSR);
+ }
+ return 0;
+}
+
+int cpu_msr_driver_close(struct msr_driver_t* drv)
+{
+ if(drv && drv->fd >= 0)
+ {
+ close(drv->fd);
+ free(drv);
+ }
+ return 0;
+}
+
+/* #endif defined (__linux__) || defined (__gnu_linux__) */
+
+#elif defined (__FreeBSD__) || defined (__DragonFly__)
+/* Assuming FreeBSD with /dev/cpuctlX */
+#include
+#include
+#include
+#include
+#include
+
+struct msr_driver_t
+{
+ int fd;
+};
+static int rdmsr_supported(void);
+static int load_driver(char* msr_path)
+{
+ const int file_exists = !access(msr_path, F_OK);
+ const int file_readable = !access(msr_path, R_OK);
+
+ if(file_exists && file_readable)
+ {
+ return 1;
+ }
+ else if(file_exists && !file_readable)
+ {
+ return 0;
+ }
+ else if(getuid() != 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return !system("kldload -n cpuctl 2> /dev/null");
+ }
+}
+
+struct msr_driver_t* cpu_msr_driver_open(void)
+{
+ return cpu_msr_driver_open_core(0);
+}
+
+struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num)
+{
+ char msr[32];
+ struct msr_driver_t* handle;
+ if(core_num >= cpuid_get_total_cpus())
+ {
+ set_error(ERR_INVCNB);
+ return NULL;
+ }
+ if(!rdmsr_supported())
+ {
+ set_error(ERR_NO_RDMSR);
+ return NULL;
+ }
+ sprintf(msr, "/dev/cpuctl%u", core_num);
+ if(!load_driver(msr))
+ {
+ set_error(ERR_NO_DRIVER);
+ return NULL;
+ }
+ int fd = open(msr, O_RDONLY);
+ if(fd < 0)
+ {
+ if(errno == EIO)
+ {
+ set_error(ERR_NO_RDMSR);
+ return NULL;
+ }
+ set_error(ERR_NO_DRIVER);
+ return NULL;
+ }
+ handle = (struct msr_driver_t*) malloc(sizeof(struct msr_driver_t));
+ handle->fd = fd;
+ return handle;
+}
+
+int cpu_rdmsr(struct msr_driver_t* driver, uint32_t msr_index, uint64_t* result)
+{
+ cpuctl_msr_args_t args;
+ args.msr = msr_index;
+
+ if(!driver || driver->fd < 0)
+ {
+ return set_error(ERR_HANDLE);
+ }
+
+ if(ioctl(driver->fd, CPUCTL_RDMSR, &args))
+ {
+ return set_error(ERR_INVMSR);
+ }
+
+ *result = args.data;
+ return 0;
+}
+
+int cpu_msr_driver_close(struct msr_driver_t* drv)
+{
+ if(drv && drv->fd >= 0)
+ {
+ close(drv->fd);
+ free(drv);
+ }
+ return 0;
+}
+
+/* #endif defined (__FreeBSD__) || defined (__DragonFly__) */
+
+#elif defined (_WIN32)
+#include
+#include
+#include
+
+extern uint8_t cc_x86driver_code[];
+extern int cc_x86driver_code_size;
+extern uint8_t cc_x64driver_code[];
+extern int cc_x64driver_code_size;
+
+struct msr_driver_t
+{
+ char driver_path[MAX_PATH + 1];
+ SC_HANDLE scManager;
+ volatile SC_HANDLE scDriver;
+ HANDLE hhDriver;
+ OVERLAPPED ovl;
+ int errorcode;
+};
+
+static int rdmsr_supported(void);
+static int extract_driver(struct msr_driver_t* driver);
+static int load_driver(struct msr_driver_t* driver);
+
+struct msr_driver_t* cpu_msr_driver_open(void)
+{
+ struct msr_driver_t* drv;
+ int status;
+ if(!rdmsr_supported())
+ {
+ set_error(ERR_NO_RDMSR);
+ return NULL;
+ }
+
+ drv = (struct msr_driver_t*) malloc(sizeof(struct msr_driver_t));
+ if(!drv)
+ {
+ set_error(ERR_NO_MEM);
+ return NULL;
+ }
+ memset(drv, 0, sizeof(struct msr_driver_t));
+
+ if(!extract_driver(drv))
+ {
+ free(drv);
+ set_error(ERR_EXTRACT);
+ return NULL;
+ }
+
+ status = load_driver(drv);
+ if(!DeleteFile(drv->driver_path))
+ {
+ debugf(1, "Deleting temporary driver file failed.\n");
+ }
+ if(!status)
+ {
+ set_error(drv->errorcode ? drv->errorcode : ERR_NO_DRIVER);
+ free(drv);
+ return NULL;
+ }
+ return drv;
+}
+
+struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num)
+{
+ warnf("cpu_msr_driver_open_core(): parameter ignored (function is the same as cpu_msr_driver_open)\n");
+ return cpu_msr_driver_open();
+}
+
+typedef BOOL (WINAPI* LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
+static BOOL is_running_x64(void)
+{
+ BOOL bIsWow64 = FALSE;
+
+ LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(__TEXT("kernel32")),
+ "IsWow64Process");
+ if(NULL != fnIsWow64Process)
+ {
+ fnIsWow64Process(GetCurrentProcess(), &bIsWow64);
+ }
+ return bIsWow64;
+}
+
+
+static int extract_driver(struct msr_driver_t* driver)
+{
+ FILE* f;
+ if(!GetTempPath(sizeof(driver->driver_path), driver->driver_path))
+ {
+ return 0;
+ }
+ strcat(driver->driver_path, "TmpRdr.sys");
+
+ f = fopen(driver->driver_path, "wb");
+ if(!f)
+ {
+ return 0;
+ }
+ if(is_running_x64())
+ {
+ fwrite(cc_x64driver_code, 1, cc_x64driver_code_size, f);
+ }
+ else
+ {
+ fwrite(cc_x86driver_code, 1, cc_x86driver_code_size, f);
+ }
+ fclose(f);
+ return 1;
+}
+
+static BOOL wait_for_service_state(SC_HANDLE hService, DWORD dwDesiredState, SERVICE_STATUS* lpsrvStatus)
+{
+ BOOL fOK = FALSE;
+ DWORD dwWaitHint;
+
+ if(hService != NULL)
+ {
+ while(TRUE)
+ {
+ fOK = QueryServiceStatus(hService, lpsrvStatus);
+ if(!fOK)
+ {
+ break;
+ }
+ if(lpsrvStatus->dwCurrentState == dwDesiredState)
+ {
+ break;
+ }
+
+ dwWaitHint = lpsrvStatus->dwWaitHint / 10; // Poll 1/10 of the wait hint
+ if(dwWaitHint < 1000)
+ {
+ dwWaitHint = 1000; // At most once per second
+ }
+ if(dwWaitHint > 10000)
+ {
+ dwWaitHint = 10000; // At least every 10 seconds
+ }
+ Sleep(dwWaitHint);
+ }
+ }
+
+ return fOK;
+}
+
+static int load_driver(struct msr_driver_t* drv)
+{
+ LPTSTR lpszInfo = __TEXT("RDMSR Executor Driver");
+ USHORT uLen = 0;
+ SERVICE_STATUS srvStatus = {0};
+ BOOL fRunning = FALSE;
+ DWORD dwLastError;
+ LPTSTR lpszDriverServiceName = __TEXT("TmpRdr");
+ TCHAR lpszDriverName[] = __TEXT("\\\\.\\Global\\TmpRdr");
+
+ if((LPVOID)(drv->scManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) != NULL)
+ {
+ drv->scDriver = CreateService(drv->scManager, lpszDriverServiceName, lpszInfo, SERVICE_ALL_ACCESS,
+ SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
+ drv->driver_path, NULL, NULL, NULL, NULL, NULL);
+ if(drv->scDriver == NULL)
+ {
+ switch(dwLastError = GetLastError())
+ {
+ case ERROR_SERVICE_EXISTS:
+ case ERROR_SERVICE_MARKED_FOR_DELETE:
+ {
+ LPQUERY_SERVICE_CONFIG lpqsc;
+ DWORD dwBytesNeeded;
+
+ drv->scDriver = OpenService(drv->scManager, lpszDriverServiceName, SERVICE_ALL_ACCESS);
+ if(drv->scDriver == NULL)
+ {
+ debugf(1, "Error opening service: %d\n", GetLastError());
+ break;
+ }
+
+ QueryServiceConfig(drv->scDriver, NULL, 0, &dwBytesNeeded);
+ if((dwLastError = GetLastError()) == ERROR_INSUFFICIENT_BUFFER)
+ {
+ lpqsc = calloc(1, dwBytesNeeded);
+ if(!QueryServiceConfig(drv->scDriver, lpqsc, dwBytesNeeded, &dwBytesNeeded))
+ {
+ free(lpqsc);
+ debugf(1, "Error query service config(adjusted buffer): %d\n", GetLastError());
+ goto clean_up;
+ }
+ else
+ {
+ free(lpqsc);
+ }
+ }
+ else
+ {
+ debugf(1, "Error query service config: %d\n", dwLastError);
+ goto clean_up;
+ }
+
+ break;
+ }
+ case ERROR_ACCESS_DENIED:
+ drv->errorcode = ERR_NO_PERMS;
+ break;
+ default:
+ debugf(1, "Create driver service failed: %d\n", dwLastError);
+ break;
+ }
+ }
+ if(drv->scDriver != NULL)
+ {
+ if(StartService(drv->scDriver, 0, NULL))
+ {
+ if(!wait_for_service_state(drv->scDriver, SERVICE_RUNNING, &srvStatus))
+ {
+ debugf(1, "Driver load failed.\n");
+ DeleteService(drv->scDriver);
+ CloseServiceHandle(drv->scManager);
+ drv->scDriver = NULL;
+ goto clean_up;
+ }
+ else
+ {
+ fRunning = TRUE;
+ }
+ }
+ else
+ {
+ if((dwLastError = GetLastError()) == ERROR_SERVICE_ALREADY_RUNNING)
+ {
+ fRunning = TRUE;
+ }
+ else
+ {
+ debugf(1, "Driver start failed.\n");
+ DeleteService(drv->scDriver);
+ CloseServiceHandle(drv->scManager);
+ drv->scDriver = NULL;
+ goto clean_up;
+ }
+
+ }
+ if(fRunning)
+ {
+ debugf(1, "Driver already running.\n");
+ }
+ else
+ {
+ debugf(1, "Driver loaded.\n");
+ }
+ CloseServiceHandle(drv->scManager);
+ drv->hhDriver = CreateFile(lpszDriverName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
+ OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
+ drv->ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ return 1;
+ }
+ }
+ else
+ {
+ debugf(1, "Open SCM failed: %d\n", GetLastError());
+ }
+
+clean_up:
+ if(drv->scManager != NULL)
+ {
+ CloseServiceHandle(drv->scManager);
+ drv->scManager = 0; // pointless
+ }
+ if(drv->scDriver != NULL)
+ {
+ if(!DeleteService(drv->scDriver))
+ {
+ debugf(1, "Delete driver service failed: %d\n", GetLastError());
+ }
+ CloseServiceHandle(drv->scDriver);
+ drv->scDriver = 0;
+ }
+
+ return 0;
+}
+
+#define FILE_DEVICE_UNKNOWN 0x00000022
+#define IOCTL_UNKNOWN_BASE FILE_DEVICE_UNKNOWN
+#define IOCTL_PROCVIEW_RDMSR CTL_CODE(IOCTL_UNKNOWN_BASE, 0x0803, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+int cpu_rdmsr(struct msr_driver_t* driver, uint32_t msr_index, uint64_t* result)
+{
+ DWORD dwBytesReturned;
+ __int64 msrdata;
+ SERVICE_STATUS srvStatus = {0};
+
+ if(!driver)
+ {
+ return set_error(ERR_HANDLE);
+ }
+ DeviceIoControl(driver->hhDriver, IOCTL_PROCVIEW_RDMSR, &msr_index, sizeof(int), &msrdata, sizeof(__int64),
+ &dwBytesReturned, &driver->ovl);
+ GetOverlappedResult(driver->hhDriver, &driver->ovl, &dwBytesReturned, TRUE);
+ *result = msrdata;
+ return 0;
+}
+
+int cpu_msr_driver_close(struct msr_driver_t* drv)
+{
+ SERVICE_STATUS srvStatus = {0};
+ if(drv == NULL)
+ {
+ return 0;
+ }
+ if(drv->scDriver != NULL)
+ {
+ if(drv->hhDriver)
+ {
+ CancelIo(drv->hhDriver);
+ }
+ if(drv->ovl.hEvent != NULL)
+ {
+ CloseHandle(drv->ovl.hEvent);
+ }
+ if(drv->hhDriver)
+ {
+ CloseHandle(drv->hhDriver);
+ }
+ drv->hhDriver = NULL;
+ drv->ovl.hEvent = NULL;
+ if(ControlService(drv->scDriver, SERVICE_CONTROL_STOP, &srvStatus))
+ {
+ if(wait_for_service_state(drv->scDriver, SERVICE_STOPPED, &srvStatus))
+ {
+ DeleteService(drv->scDriver);
+ }
+ }
+ }
+ return 0;
+}
+
+/* endif defined (_WIN32) */
+
+#else /* Unsupported OS */
+/* On others OS (i.e., Darwin), we still do not support RDMSR, so supply dummy struct
+ and functions */
+
+#define RDMSR_UNSUPPORTED_OS
+
+struct msr_driver_t
+{
+ int dummy;
+};
+struct msr_driver_t* cpu_msr_driver_open(void)
+{
+ set_error(ERR_NOT_IMP);
+ return NULL;
+}
+
+struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num)
+{
+ set_error(ERR_NOT_IMP);
+ return NULL;
+}
+
+int cpu_rdmsr(struct msr_driver_t* driver, uint32_t msr_index, uint64_t* result)
+{
+ return set_error(ERR_NOT_IMP);
+}
+
+int cpu_msr_driver_close(struct msr_driver_t* driver)
+{
+ return set_error(ERR_NOT_IMP);
+}
+
+int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit,
+ uint8_t lowbit, uint64_t* result)
+{
+ return set_error(ERR_NOT_IMP);
+}
+
+int cpu_msrinfo(struct msr_driver_t* driver, cpu_msrinfo_request_t which)
+{
+ return set_error(ERR_NOT_IMP);
+}
+
+int msr_serialize_raw_data(struct msr_driver_t* handle, const char* filename)
+{
+ return set_error(ERR_NOT_IMP);
+}
+
+#endif /* Unsupported OS */
+
+#ifndef RDMSR_UNSUPPORTED_OS
+
+/* Useful links for hackers:
+- AMD MSRs:
+ AMD BIOS and Kernel Developer’s Guide (BKDG)
+ * AMD Family 10h Processors
+ http://support.amd.com/TechDocs/31116.pdf
+ * AMD Family 11h Processors
+ http://support.amd.com/TechDocs/41256.pdf
+ * AMD Family 12h Processors
+ http://support.amd.com/TechDocs/41131.pdf
+ * AMD Family 14h Processors
+ http://support.amd.com/TechDocs/43170_14h_Mod_00h-0Fh_BKDG.pdf
+ * AMD Family 15h Processors
+ http://support.amd.com/TechDocs/42301_15h_Mod_00h-0Fh_BKDG.pdf
+ http://support.amd.com/TechDocs/42300_15h_Mod_10h-1Fh_BKDG.pdf
+ http://support.amd.com/TechDocs/49125_15h_Models_30h-3Fh_BKDG.pdf
+ http://support.amd.com/TechDocs/50742_15h_Models_60h-6Fh_BKDG.pdf
+ http://support.amd.com/TechDocs/55072_AMD_Family_15h_Models_70h-7Fh_BKDG.pdf
+ * AMD Family 16h Processors
+ http://support.amd.com/TechDocs/48751_16h_bkdg.pdf
+ http://support.amd.com/TechDocs/52740_16h_Models_30h-3Fh_BKDG.pdf
+
+ AMD Processor Programming Reference (PPR)
+ * AMD Family 17h Processors
+ https://support.amd.com/TechDocs/54945_PPR_Family_17h_Models_00h-0Fh.pdf
+
+- Intel MSRs:
+ Intel® 64 and IA-32 Architectures Software Developer’s Manual
+ * Volume 3 (3A, 3B, 3C & 3D): System Programming Guide
+ http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-system-programming-manual-325384.pdf
+*/
+
+/* AMD MSRs addresses */
+#define MSR_PSTATE_L 0xC0010061
+#define MSR_PSTATE_S 0xC0010063
+#define MSR_PSTATE_0 0xC0010064
+#define MSR_PSTATE_1 0xC0010065
+#define MSR_PSTATE_2 0xC0010066
+#define MSR_PSTATE_3 0xC0010067
+#define MSR_PSTATE_4 0xC0010068
+#define MSR_PSTATE_5 0xC0010069
+#define MSR_PSTATE_6 0xC001006A
+#define MSR_PSTATE_7 0xC001006B
+static const uint32_t amd_msr[] =
+{
+ MSR_PSTATE_L,
+ MSR_PSTATE_S,
+ MSR_PSTATE_0,
+ MSR_PSTATE_1,
+ MSR_PSTATE_2,
+ MSR_PSTATE_3,
+ MSR_PSTATE_4,
+ MSR_PSTATE_5,
+ MSR_PSTATE_6,
+ MSR_PSTATE_7,
+ CPU_INVALID_VALUE
+};
+
+/* Intel MSRs addresses */
+#define IA32_MPERF 0xE7
+#define IA32_APERF 0xE8
+#define IA32_PERF_STATUS 0x198
+#define IA32_THERM_STATUS 0x19C
+#define MSR_EBL_CR_POWERON 0x2A
+#define MSR_TURBO_RATIO_LIMIT 0x1AD
+#define MSR_TEMPERATURE_TARGET 0x1A2
+#define MSR_PERF_STATUS 0x198
+#define MSR_PLATFORM_INFO 0xCE
+static const uint32_t intel_msr[] =
+{
+ IA32_MPERF,
+ IA32_APERF,
+ IA32_PERF_STATUS,
+ IA32_THERM_STATUS,
+ MSR_EBL_CR_POWERON,
+ MSR_TURBO_RATIO_LIMIT,
+ MSR_TEMPERATURE_TARGET,
+ MSR_PERF_STATUS,
+ MSR_PLATFORM_INFO,
+ CPU_INVALID_VALUE
+};
+
+struct msr_info_t
+{
+ int cpu_clock;
+ struct msr_driver_t* handle;
+ struct cpu_id_t* id;
+ struct internal_id_info_t* internal;
+};
+
+static int rdmsr_supported(void)
+{
+ struct cpu_id_t* id = get_cached_cpuid();
+ return id->flags[CPU_FEATURE_MSR];
+}
+
+static int perfmsr_measure(struct msr_driver_t* handle, int msr)
+{
+ int err;
+ uint64_t a, b;
+ uint64_t x, y;
+ err = cpu_rdmsr(handle, msr, &x);
+ if(err)
+ {
+ return CPU_INVALID_VALUE;
+ }
+ sys_precise_clock(&a);
+ busy_loop_delay(10);
+ cpu_rdmsr(handle, msr, &y);
+ sys_precise_clock(&b);
+ if(a >= b || x > y)
+ {
+ return CPU_INVALID_VALUE;
+ }
+ return (int)((y - x) / (b - a));
+}
+
+static int get_amd_multipliers(struct msr_info_t* info, uint32_t pstate, double* multiplier)
+{
+ int i, err;
+ uint64_t CpuFid, CpuDid, CpuDidLSD;
+
+ /* Constant values needed for 12h family */
+ const struct
+ {
+ uint64_t did;
+ double divisor;
+ } divisor_t[] =
+ {
+ { 0x0, 1 },
+ { 0x1, 1.5 },
+ { 0x2, 2 },
+ { 0x3, 3 },
+ { 0x4, 4 },
+ { 0x5, 6 },
+ { 0x6, 8 },
+ { 0x7, 12 },
+ { 0x8, 16 },
+ };
+ const int num_dids = (int) COUNT_OF(divisor_t);
+
+ /* Constant values for common families */
+ const int magic_constant = (info->id->ext_family == 0x11) ? 0x8 : 0x10;
+ const int is_apu = ((FUSION_C <= info->internal->code.amd) && (info->internal->code.amd <= FUSION_A)) ||
+ (info->internal->bits & _APU_);
+ const double divisor = is_apu ? 1.0 : 2.0;
+
+ /* Check if P-state is valid */
+ if(pstate < MSR_PSTATE_0 || MSR_PSTATE_7 < pstate)
+ {
+ return 1;
+ }
+
+ switch(info->id->ext_family)
+ {
+ case 0x12:
+ /* BKDG 12h, page 469
+ MSRC001_00[6B:64][8:4] is CpuFid
+ MSRC001_00[6B:64][3:0] is CpuDid
+ CPU COF is (100MHz * (CpuFid + 10h) / (divisor specified by CpuDid))
+ Note: This family contains only APUs */
+ err = cpu_rdmsr_range(info->handle, pstate, 8, 4, &CpuFid);
+ err += cpu_rdmsr_range(info->handle, pstate, 3, 0, &CpuDid);
+ i = 0;
+ while(i < num_dids && divisor_t[i].did != CpuDid)
+ {
+ i++;
+ }
+ if(i < num_dids)
+ {
+ *multiplier = (double)((CpuFid + magic_constant) / divisor_t[i].divisor);
+ }
+ else
+ {
+ err++;
+ }
+ break;
+ case 0x14:
+ /* BKDG 14h, page 430
+ MSRC001_00[6B:64][8:4] is CpuDidMSD
+ MSRC001_00[6B:64][3:0] is CpuDidLSD
+ PLL COF is (100 MHz * (D18F3xD4[MainPllOpFreqId] + 10h))
+ Divisor is (CpuDidMSD + (CpuDidLSD * 0.25) + 1)
+ CPU COF is (main PLL frequency specified by D18F3xD4[MainPllOpFreqId]) / (core clock divisor specified by CpuDidMSD and CpuDidLSD)
+ Note: This family contains only APUs */
+ err = cpu_rdmsr_range(info->handle, pstate, 8, 4, &CpuDid);
+ err += cpu_rdmsr_range(info->handle, pstate, 3, 0, &CpuDidLSD);
+ *multiplier = (double)(((info->cpu_clock + 5) / 100 + magic_constant) / (CpuDid + CpuDidLSD * 0.25 + 1));
+ break;
+ case 0x10:
+ /* BKDG 10h, page 429
+ MSRC001_00[6B:64][8:6] is CpuDid
+ MSRC001_00[6B:64][5:0] is CpuFid
+ CPU COF is (100 MHz * (CpuFid + 10h) / (2^CpuDid))
+ Note: This family contains only CPUs */
+ case 0x11:
+ /* BKDG 11h, page 236
+ MSRC001_00[6B:64][8:6] is CpuDid
+ MSRC001_00[6B:64][5:0] is CpuFid
+ CPU COF is ((100 MHz * (CpuFid + 08h)) / (2^CpuDid))
+ Note: This family contains only CPUs */
+ case 0x15:
+ /* BKDG 15h, page 570/580/635/692 (00h-0Fh/10h-1Fh/30h-3Fh/60h-6Fh)
+ MSRC001_00[6B:64][8:6] is CpuDid
+ MSRC001_00[6B:64][5:0] is CpuFid
+ CoreCOF is (100 * (MSRC001_00[6B:64][CpuFid] + 10h) / (2^MSRC001_00[6B:64][CpuDid]))
+ Note: This family contains BOTH CPUs and APUs */
+ case 0x16:
+ /* BKDG 16h, page 549/611 (00h-0Fh/30h-3Fh)
+ MSRC001_00[6B:64][8:6] is CpuDid
+ MSRC001_00[6B:64][5:0] is CpuFid
+ CoreCOF is (100 * (MSRC001_00[6B:64][CpuFid] + 10h) / (2^MSRC001_00[6B:64][CpuDid]))
+ Note: This family contains only APUs */
+ err = cpu_rdmsr_range(info->handle, pstate, 8, 6, &CpuDid);
+ err += cpu_rdmsr_range(info->handle, pstate, 5, 0, &CpuFid);
+ *multiplier = (double)((CpuFid + magic_constant) / (1ull << CpuDid)) / divisor;
+ break;
+ case 0x17:
+ /* PPR 17h, pages 30 and 138-139
+ MSRC001_00[6B:64][13:8] is CpuDfsId
+ MSRC001_00[6B:64][7:0] is CpuFid
+ CoreCOF is (Core::X86::Msr::PStateDef[CpuFid[7:0]] / Core::X86::Msr::PStateDef[CpuDfsId]) * 200 */
+ err = cpu_rdmsr_range(info->handle, pstate, 13, 8, &CpuDid);
+ err += cpu_rdmsr_range(info->handle, pstate, 7, 0, &CpuFid);
+ *multiplier = (double)(CpuFid / CpuDid) * 2;
+ break;
+ default:
+ err = 1;
+ break;
+ }
+
+ return err;
+}
+
+static uint32_t get_amd_last_pstate_addr(struct msr_info_t* info)
+{
+ static uint32_t last_addr = 0x0;
+ uint64_t reg = 0x0;
+
+ /* The result is cached, need to be computed once */
+ if(last_addr != 0x0)
+ {
+ return last_addr;
+ }
+
+ /* Refer links above
+ MSRC001_00[6B:64][63] is PstateEn
+ PstateEn indicates if the rest of the P-state information in the register is valid after a reset */
+ last_addr = MSR_PSTATE_7 + 1;
+ while((reg == 0x0) && (last_addr > MSR_PSTATE_0))
+ {
+ last_addr--;
+ cpu_rdmsr_range(info->handle, last_addr, 63, 63, ®);
+ }
+ return last_addr;
+}
+
+static double get_info_min_multiplier(struct msr_info_t* info)
+{
+ int err;
+ double mult;
+ uint32_t addr;
+ uint64_t reg;
+
+ if(info->id->vendor == VENDOR_INTEL)
+ {
+ /* Refer links above
+ Table 35-12. MSRs in Next Generation Intel Atom Processors Based on the Goldmont Microarchitecture
+ Table 35-13. MSRs in Processors Based on Intel® Microarchitecture Code Name Nehalem
+ Table 35-18. MSRs Supported by Intel® Processors based on Intel® microarchitecture code name Sandy Bridge (Contd.)
+ Table 35-23. Additional MSRs Supported by 3rd Generation Intel® Core™ Processors (based on Intel® microarchitecture code name Ivy Bridge)
+ Table 35-24. MSRs Supported by Intel® Xeon® Processors E5 v2 Product Family (based on Ivy Bridge-E microarchitecture)
+ Table 35-27. Additional MSRs Supported by Processors based on the Haswell or Haswell-E microarchitectures
+ Table 35-34. Additional MSRs Common to Intel® Xeon® Processor D and Intel Xeon Processors E5 v4 Family Based on the Broadwell Microarchitecture
+ Table 35-40. Selected MSRs Supported by Next Generation Intel® Xeon Phi™ Processors with DisplayFamily_DisplayModel Signature 06_57H
+ MSR_PLATFORM_INFO[47:40] is Maximum Efficiency Ratio
+ Maximum Efficiency Ratio is the minimum ratio that the processor can operates */
+ err = cpu_rdmsr_range(info->handle, MSR_PLATFORM_INFO, 47, 40, ®);
+ if(!err)
+ {
+ return (double) reg;
+ }
+ }
+ else if(info->id->vendor == VENDOR_AMD)
+ {
+ /* N.B.: Find the last P-state
+ get_amd_last_pstate_addr() returns the last P-state, MSR_PSTATE_0 <= addr <= MSR_PSTATE_7 */
+ addr = get_amd_last_pstate_addr(info);
+ err = get_amd_multipliers(info, addr, &mult);
+ if(!err)
+ {
+ return mult;
+ }
+ }
+
+ return (double) CPU_INVALID_VALUE / 100;
+}
+
+static double get_info_cur_multiplier(struct msr_info_t* info)
+{
+ int err;
+ double mult;
+ uint64_t reg;
+
+ if(info->id->vendor == VENDOR_INTEL && info->internal->code.intel == PENTIUM)
+ {
+ err = cpu_rdmsr(info->handle, MSR_EBL_CR_POWERON, ®);
+ if(!err)
+ {
+ return (double)((reg >> 22) & 0x1f);
+ }
+ }
+ else if(info->id->vendor == VENDOR_INTEL && info->internal->code.intel != PENTIUM)
+ {
+ /* Refer links above
+ Table 35-2. IA-32 Architectural MSRs (Contd.)
+ IA32_PERF_STATUS[15:0] is Current performance State Value
+ [7:0] is 0x0, [15:8] looks like current ratio */
+ err = cpu_rdmsr_range(info->handle, IA32_PERF_STATUS, 15, 8, ®);
+ if(!err)
+ {
+ return (double) reg;
+ }
+ }
+ else if(info->id->vendor == VENDOR_AMD)
+ {
+ /* Refer links above
+ MSRC001_0063[2:0] is CurPstate */
+ err = cpu_rdmsr_range(info->handle, MSR_PSTATE_S, 2, 0, ®);
+ err += get_amd_multipliers(info, MSR_PSTATE_0 + (uint32_t) reg, &mult);
+ if(!err)
+ {
+ return mult;
+ }
+ }
+
+ return (double) CPU_INVALID_VALUE / 100;
+}
+
+static double get_info_max_multiplier(struct msr_info_t* info)
+{
+ int err;
+ double mult;
+ uint64_t reg;
+
+ if(info->id->vendor == VENDOR_INTEL && info->internal->code.intel == PENTIUM)
+ {
+ err = cpu_rdmsr(info->handle, IA32_PERF_STATUS, ®);
+ if(!err)
+ {
+ return (double)((reg >> 40) & 0x1f);
+ }
+ }
+ else if(info->id->vendor == VENDOR_INTEL && info->internal->code.intel != PENTIUM)
+ {
+ /* Refer links above
+ Table 35-10. Specific MSRs Supported by Intel® Atom™ Processor C2000 Series with CPUID Signature 06_4DH
+ Table 35-12. MSRs in Next Generation Intel Atom Processors Based on the Goldmont Microarchitecture (Contd.)
+ Table 35-13. MSRs in Processors Based on Intel® Microarchitecture Code Name Nehalem (Contd.)
+ Table 35-14. Additional MSRs in Intel® Xeon® Processor 5500 and 3400 Series
+ Table 35-16. Additional MSRs Supported by Intel Processors (Based on Intel® Microarchitecture Code Name Westmere)
+ Table 35-19. MSRs Supported by 2nd Generation Intel® Core™ Processors (Intel® microarchitecture code name Sandy Bridge)
+ Table 35-21. Selected MSRs Supported by Intel® Xeon® Processors E5 Family (based on Sandy Bridge microarchitecture)
+ Table 35-28. MSRs Supported by 4th Generation Intel® Core™ Processors (Haswell microarchitecture) (Contd.)
+ Table 35-30. Additional MSRs Supported by Intel® Xeon® Processor E5 v3 Family
+ Table 35-33. Additional MSRs Supported by Intel® Core™ M Processors and 5th Generation Intel® Core™ Processors
+ Table 35-34. Additional MSRs Common to Intel® Xeon® Processor D and Intel Xeon Processors E5 v4 Family Based on the Broadwell Microarchitecture
+ Table 35-37. Additional MSRs Supported by 6th Generation Intel® Core™ Processors Based on Skylake Microarchitecture
+ Table 35-40. Selected MSRs Supported by Next Generation Intel® Xeon Phi™ Processors with DisplayFamily_DisplayModel Signature 06_57H
+ MSR_TURBO_RATIO_LIMIT[7:0] is Maximum Ratio Limit for 1C */
+ err = cpu_rdmsr_range(info->handle, MSR_TURBO_RATIO_LIMIT, 7, 0, ®);
+ if(!err)
+ {
+ return (double) reg;
+ }
+ }
+ else if(info->id->vendor == VENDOR_AMD)
+ {
+ /* Refer links above
+ MSRC001_0064 is Pb0
+ Pb0 is the highest-performance boosted P-state */
+ err = get_amd_multipliers(info, MSR_PSTATE_0, &mult);
+ if(!err)
+ {
+ return mult;
+ }
+ }
+
+ return (double) CPU_INVALID_VALUE / 100;
+}
+
+static int get_info_temperature(struct msr_info_t* info)
+{
+ int err;
+ uint64_t DigitalReadout, ReadingValid, TemperatureTarget;
+
+ if(info->id->vendor == VENDOR_INTEL)
+ {
+ /* Refer links above
+ Table 35-2. IA-32 Architectural MSRs
+ IA32_THERM_STATUS[22:16] is Digital Readout
+ IA32_THERM_STATUS[31] is Reading Valid
+
+ Table 35-6. MSRs Common to the Silvermont Microarchitecture and Newer Microarchitectures for Intel® Atom
+ Table 35-13. MSRs in Processors Based on Intel® Microarchitecture Code Name Nehalem (Contd.)
+ Table 35-18. MSRs Supported by Intel® Processors based on Intel® microarchitecture code name Sandy Bridge (Contd.)
+ Table 35-24. MSRs Supported by Intel® Xeon® Processors E5 v2 Product Family (based on Ivy Bridge-E microarchitecture) (Contd.)
+ Table 35-34. Additional MSRs Common to Intel® Xeon® Processor D and Intel Xeon Processors E5 v4 Family Based on the Broadwell Microarchitecture
+ Table 35-40. Selected MSRs Supported by Next Generation Intel® Xeon Phi™ Processors with DisplayFamily_DisplayModel Signature 06_57H
+ MSR_TEMPERATURE_TARGET[23:16] is Temperature Target */
+ err = cpu_rdmsr_range(info->handle, IA32_THERM_STATUS, 22, 16, &DigitalReadout);
+ err += cpu_rdmsr_range(info->handle, IA32_THERM_STATUS, 31, 31, &ReadingValid);
+ err += cpu_rdmsr_range(info->handle, MSR_TEMPERATURE_TARGET, 23, 16, &TemperatureTarget);
+ if(!err && ReadingValid)
+ {
+ return (int)(TemperatureTarget - DigitalReadout);
+ }
+ }
+
+ return CPU_INVALID_VALUE;
+}
+
+static double get_info_voltage(struct msr_info_t* info)
+{
+ int err;
+ double VIDStep;
+ uint64_t reg, CpuVid;
+
+ if(info->id->vendor == VENDOR_INTEL)
+ {
+ /* Refer links above
+ Table 35-18. MSRs Supported by Intel® Processors based on Intel® microarchitecture code name Sandy Bridge (Contd.)
+ MSR_PERF_STATUS[47:32] is Core Voltage
+ P-state core voltage can be computed by MSR_PERF_STATUS[37:32] * (float) 1/(2^13). */
+ err = cpu_rdmsr_range(info->handle, MSR_PERF_STATUS, 47, 32, ®);
+ if(!err)
+ {
+ return (double) reg / (1 << 13);
+ }
+ }
+ else if(info->id->vendor == VENDOR_AMD)
+ {
+ /* Refer links above
+ MSRC001_00[6B:64][15:9] is CpuVid (Jaguar and before)
+ MSRC001_00[6B:64][21:14] is CpuVid (Zen)
+ MSRC001_0063[2:0] is P-state Status
+ BKDG 10h, page 49: voltage = 1.550V - 0.0125V * SviVid (SVI1)
+ BKDG 15h, page 50: Voltage = 1.5500 - 0.00625 * Vid[7:0] (SVI2)
+ SVI2 since Piledriver (Family 15h, 2nd-gen): Models 10h-1Fh Processors */
+ VIDStep = ((info->id->ext_family < 0x15) || ((info->id->ext_family == 0x15) &&
+ (info->id->ext_model < 0x10))) ? 0.0125 : 0.00625;
+ err = cpu_rdmsr_range(info->handle, MSR_PSTATE_S, 2, 0, ®);
+ if(info->id->ext_family < 0x17)
+ {
+ err += cpu_rdmsr_range(info->handle, MSR_PSTATE_0 + (uint32_t) reg, 15, 9, &CpuVid);
+ }
+ else
+ {
+ err += cpu_rdmsr_range(info->handle, MSR_PSTATE_0 + (uint32_t) reg, 21, 14, &CpuVid);
+ }
+ if(!err && MSR_PSTATE_0 + (uint32_t) reg <= MSR_PSTATE_7)
+ {
+ return 1.550 - VIDStep * CpuVid;
+ }
+ }
+
+ return (double) CPU_INVALID_VALUE / 100;
+}
+
+static double get_info_bus_clock(struct msr_info_t* info)
+{
+ int err;
+ double mult;
+ uint32_t addr;
+ uint64_t reg;
+
+ if(info->id->vendor == VENDOR_INTEL)
+ {
+ /* Refer links above
+ Table 35-12. MSRs in Next Generation Intel Atom Processors Based on the Goldmont Microarchitecture
+ Table 35-13. MSRs in Processors Based on Intel® Microarchitecture Code Name Nehalem
+ Table 35-18. MSRs Supported by Intel® Processors based on Intel® microarchitecture code name Sandy Bridge (Contd.)
+ Table 35-23. Additional MSRs Supported by 3rd Generation Intel® Core™ Processors (based on Intel® microarchitecture code name Ivy Bridge)
+ Table 35-24. MSRs Supported by Intel® Xeon® Processors E5 v2 Product Family (based on Ivy Bridge-E microarchitecture)
+ Table 35-27. Additional MSRs Supported by Processors based on the Haswell or Haswell-E microarchitectures
+ Table 35-40. Selected MSRs Supported by Next Generation Intel® Xeon Phi™ Processors with DisplayFamily_DisplayModel Signature 06_57H
+ MSR_PLATFORM_INFO[15:8] is Maximum Non-Turbo Ratio */
+ err = cpu_rdmsr_range(info->handle, MSR_PLATFORM_INFO, 15, 8, ®);
+ if(!err)
+ {
+ return (double) info->cpu_clock / reg;
+ }
+ }
+ else if(info->id->vendor == VENDOR_AMD)
+ {
+ /* Refer links above
+ MSRC001_0061[6:4] is PstateMaxVal
+ PstateMaxVal is the the lowest-performance non-boosted P-state */
+ addr = get_amd_last_pstate_addr(info);
+ err = cpu_rdmsr_range(info->handle, MSR_PSTATE_L, 6, 4, ®);
+ err += get_amd_multipliers(info, addr - reg, &mult);
+ if(!err)
+ {
+ return (double) info->cpu_clock / mult;
+ }
+ }
+
+ return (double) CPU_INVALID_VALUE / 100;
+}
+
+int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit,
+ uint8_t lowbit, uint64_t* result)
+{
+ int err;
+ const uint8_t bits = highbit - lowbit + 1;
+
+ if(highbit > 63 || lowbit > highbit)
+ {
+ return set_error(ERR_INVRANGE);
+ }
+
+ err = cpu_rdmsr(handle, msr_index, result);
+
+ if(!err && bits < 64)
+ {
+ /* Show only part of register */
+ *result >>= lowbit;
+ *result &= (1ULL << bits) - 1;
+ }
+
+ return err;
+}
+
+int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which)
+{
+ static int err = 0, init = 0;
+ struct cpu_raw_data_t raw;
+ static struct cpu_id_t id;
+ static struct internal_id_info_t internal;
+ static struct msr_info_t info;
+
+ if(handle == NULL)
+ {
+ set_error(ERR_HANDLE);
+ return CPU_INVALID_VALUE;
+ }
+
+ info.handle = handle;
+ if(!init)
+ {
+ err = cpuid_get_raw_data(&raw);
+ err += cpu_ident_internal(&raw, &id, &internal);
+ info.cpu_clock = cpu_clock_measure(250, 1);
+ info.id = &id;
+ info.internal = &internal;
+ init = 1;
+ }
+
+ if(err)
+ {
+ return CPU_INVALID_VALUE;
+ }
+
+ switch(which)
+ {
+ case INFO_MPERF:
+ return perfmsr_measure(handle, IA32_MPERF);
+ case INFO_APERF:
+ return perfmsr_measure(handle, IA32_APERF);
+ case INFO_MIN_MULTIPLIER:
+ return (int)(get_info_min_multiplier(&info) * 100);
+ case INFO_CUR_MULTIPLIER:
+ return (int)(get_info_cur_multiplier(&info) * 100);
+ case INFO_MAX_MULTIPLIER:
+ return (int)(get_info_max_multiplier(&info) * 100);
+ case INFO_TEMPERATURE:
+ return get_info_temperature(&info);
+ case INFO_THROTTLING:
+ return CPU_INVALID_VALUE;
+ case INFO_VOLTAGE:
+ return (int)(get_info_voltage(&info) * 100);
+ case INFO_BCLK:
+ case INFO_BUS_CLOCK:
+ return (int)(get_info_bus_clock(&info) * 100);
+ default:
+ return CPU_INVALID_VALUE;
+ }
+}
+
+int msr_serialize_raw_data(struct msr_driver_t* handle, const char* filename)
+{
+ int i, j;
+ FILE* f;
+ uint64_t reg;
+ const uint32_t* msr;
+ struct cpu_raw_data_t raw;
+ struct cpu_id_t id;
+ struct internal_id_info_t internal;
+
+ if(handle == NULL)
+ {
+ return set_error(ERR_HANDLE);
+ }
+
+ if(!strcmp(filename, ""))
+ {
+ f = stdout;
+ }
+ else
+ {
+ f = fopen(filename, "wt");
+ }
+ if(!f)
+ {
+ return set_error(ERR_OPEN);
+ }
+
+ if(cpuid_get_raw_data(&raw) || cpu_ident_internal(&raw, &id, &internal))
+ {
+ return -1;
+ }
+
+ fprintf(f, "CPU is %s %s, stock clock is %dMHz.\n", id.vendor_str, id.brand_str, cpu_clock_measure(250, 1));
+ if(id.vendor == VENDOR_INTEL)
+ {
+ msr = intel_msr;
+ }
+ else if(id.vendor == VENDOR_AMD)
+ {
+ msr = amd_msr;
+ }
+ else
+ {
+ return set_error(ERR_CPU_UNKN);
+ }
+
+ for(i = 0; msr[i] != CPU_INVALID_VALUE; i++)
+ {
+ cpu_rdmsr(handle, msr[i], ®);
+ fprintf(f, "msr[%#08x]=", msr[i]);
+ for(j = 56; j >= 0; j -= 8)
+ {
+ fprintf(f, "%02x ", (int)(reg >> j) & 0xff);
+ }
+ printf("\n");
+ }
+
+ if(strcmp(filename, ""))
+ {
+ fclose(f);
+ }
+ return set_error(ERR_OK);
+}
+
+#endif // RDMSR_UNSUPPORTED_OS
diff --git a/src/3rdparty/libcpuid/rdtsc.c b/src/3rdparty/libcpuid/rdtsc.c
new file mode 100644
index 00000000..4c810132
--- /dev/null
+++ b/src/3rdparty/libcpuid/rdtsc.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright 2008 Veselin Georgiev,
+ * anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include
+#include
+#include "libcpuid.h"
+#include "libcpuid_util.h"
+#include "asm-bits.h"
+#include "rdtsc.h"
+
+#ifdef _WIN32
+#include
+void sys_precise_clock(uint64_t* result)
+{
+ double c, f;
+ LARGE_INTEGER freq, counter;
+ QueryPerformanceCounter(&counter);
+ QueryPerformanceFrequency(&freq);
+ c = (double) counter.QuadPart;
+ f = (double) freq.QuadPart;
+ *result = (uint64_t)(c * 1000000.0 / f);
+}
+#else
+/* assuming Linux, Mac OS or other POSIX */
+#include
+void sys_precise_clock(uint64_t* result)
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ *result = (uint64_t) tv.tv_sec * (uint64_t) 1000000 +
+ (uint64_t) tv.tv_usec;
+}
+#endif /* _WIN32 */
+
+/* out = a - b */
+static void mark_t_subtract(struct cpu_mark_t* a, struct cpu_mark_t* b, struct cpu_mark_t* out)
+{
+ out->tsc = a->tsc - b->tsc;
+ out->sys_clock = a->sys_clock - b->sys_clock;
+}
+
+void cpu_tsc_mark(struct cpu_mark_t* mark)
+{
+ cpu_rdtsc(&mark->tsc);
+ sys_precise_clock(&mark->sys_clock);
+}
+
+void cpu_tsc_unmark(struct cpu_mark_t* mark)
+{
+ struct cpu_mark_t temp;
+ cpu_tsc_mark(&temp);
+ mark_t_subtract(&temp, mark, mark);
+}
+
+
+int cpu_clock_by_mark(struct cpu_mark_t* mark)
+{
+ uint64_t result;
+
+ /* Check if some subtraction resulted in a negative number: */
+ if((mark->tsc >> 63) != 0 || (mark->sys_clock >> 63) != 0)
+ {
+ return -1;
+ }
+
+ /* Divide-by-zero check: */
+ if(mark->sys_clock == 0)
+ {
+ return -1;
+ }
+
+ /* Check if the result fits in 32bits */
+ result = mark->tsc / mark->sys_clock;
+ if(result > (uint64_t) 0x7fffffff)
+ {
+ return -1;
+ }
+ return (int) result;
+}
+
+#ifdef _WIN32
+int cpu_clock_by_os(void)
+{
+ HKEY key;
+ DWORD result;
+ DWORD size = 4;
+
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0, KEY_READ,
+ &key) != ERROR_SUCCESS)
+ {
+ return -1;
+ }
+
+ if(RegQueryValueEx(key, TEXT("~MHz"), NULL, NULL, (LPBYTE) &result, (LPDWORD) &size) != ERROR_SUCCESS)
+ {
+ RegCloseKey(key);
+ return -1;
+ }
+ RegCloseKey(key);
+
+ return (int)result;
+}
+#else
+#ifdef __APPLE__
+#include
+#include
+/* Assuming Mac OS X with hw.cpufrequency sysctl */
+int cpu_clock_by_os(void)
+{
+ long long result = -1;
+ size_t size = sizeof(result);
+ if(sysctlbyname("hw.cpufrequency", &result, &size, NULL, 0))
+ {
+ return -1;
+ }
+ return (int)(result / (long long) 1000000);
+}
+#else
+/* Assuming Linux with /proc/cpuinfo */
+int cpu_clock_by_os(void)
+{
+ FILE* f;
+ char line[1024], *s;
+ int result;
+
+ f = fopen("/proc/cpuinfo", "rt");
+ if(!f)
+ {
+ return -1;
+ }
+
+ while(fgets(line, sizeof(line), f))
+ {
+ if(!strncmp(line, "cpu MHz", 7))
+ {
+ s = strchr(line, ':');
+ if(s && 1 == sscanf(s, ":%d.", &result))
+ {
+ fclose(f);
+ return result;
+ }
+ }
+ }
+ fclose(f);
+ return -1;
+}
+#endif /* __APPLE__ */
+#endif /* _WIN32 */
+
+/* Emulate doing useful CPU intensive work */
+static int busy_loop(int amount)
+{
+ int i, j, k, s = 0;
+ static volatile int data[42] = {32, 12, -1, 5, 23, 0 };
+ for(i = 0; i < amount; i++)
+ for(j = 0; j < 65536; j++)
+ for(k = 0; k < 42; k++)
+ {
+ s += data[k];
+ }
+ return s;
+}
+
+int busy_loop_delay(int milliseconds)
+{
+ int cycles = 0, r = 0, first = 1;
+ uint64_t a, b, c;
+ sys_precise_clock(&a);
+ while(1)
+ {
+ sys_precise_clock(&c);
+ if((c - a) / 1000 > milliseconds)
+ {
+ return r;
+ }
+ r += busy_loop(cycles);
+ if(first)
+ {
+ first = 0;
+ }
+ else
+ {
+ if(c - b < 1000)
+ {
+ cycles *= 2;
+ }
+ if(c - b > 10000)
+ {
+ cycles /= 2;
+ }
+ }
+ b = c;
+ }
+}
+
+int cpu_clock_measure(int millis, int quad_check)
+{
+ struct cpu_mark_t begin[4], end[4], temp, temp2;
+ int results[4], cycles, n, k, i, j, bi, bj, mdiff, diff, _zero = 0;
+ uint64_t tl;
+
+ if(millis < 1)
+ {
+ return -1;
+ }
+ tl = millis * (uint64_t) 1000;
+ if(quad_check)
+ {
+ tl /= 4;
+ }
+ n = quad_check ? 4 : 1;
+ cycles = 1;
+ for(k = 0; k < n; k++)
+ {
+ cpu_tsc_mark(&begin[k]);
+ end[k] = begin[k];
+ do
+ {
+ /* Run busy loop, and fool the compiler that we USE the garbishy
+ value it calculates */
+ _zero |= (1 & busy_loop(cycles));
+ cpu_tsc_mark(&temp);
+ mark_t_subtract(&temp, &end[k], &temp2);
+ /* If busy loop is too short, increase it */
+ if(temp2.sys_clock < tl / 8)
+ {
+ cycles *= 2;
+ }
+ end[k] = temp;
+ }
+ while(end[k].sys_clock - begin[k].sys_clock < tl);
+ mark_t_subtract(&end[k], &begin[k], &temp);
+ results[k] = cpu_clock_by_mark(&temp);
+ }
+ if(n == 1)
+ {
+ return results[0];
+ }
+ mdiff = 0x7fffffff;
+ bi = bj = -1;
+ for(i = 0; i < 4; i++)
+ {
+ for(j = i + 1; j < 4; j++)
+ {
+ diff = results[i] - results[j];
+ if(diff < 0)
+ {
+ diff = -diff;
+ }
+ if(diff < mdiff)
+ {
+ mdiff = diff;
+ bi = i;
+ bj = j;
+ }
+ }
+ }
+ if(results[bi] == -1)
+ {
+ return -1;
+ }
+ return (results[bi] + results[bj] + _zero) / 2;
+}
+
+
+static void adjust_march_ic_multiplier(const struct cpu_id_t* id, int* numerator, int* denom)
+{
+ /*
+ * for cpu_clock_by_ic: we need to know how many clocks does a typical ADDPS instruction
+ * take, when issued in rapid succesion without dependencies. The whole idea of
+ * cpu_clock_by_ic was that this is easy to determine, at least it was back in 2010. Now
+ * it's getting progressively more hairy, but here are the current measurements:
+ *
+ * 1. For CPUs with 64-bit SSE units, ADDPS issue rate is 0.5 IPC (one insn in 2 clocks)
+ * 2. For CPUs with 128-bit SSE units, issue rate is exactly 1.0 IPC
+ * 3. For Bulldozer and later, it is 1.4 IPC (we multiply by 5/7)
+ * 4. For Skylake and later, it is 1.6 IPC (we multiply by 5/8)
+ */
+ //
+ if(id->sse_size < 128)
+ {
+ debugf(1, "SSE execution path is 64-bit\n");
+ // on a CPU with half SSE unit length, SSE instructions execute at 0.5 IPC;
+ // the resulting value must be multiplied by 2:
+ *numerator = 2;
+ }
+ else
+ {
+ debugf(1, "SSE execution path is 128-bit\n");
+ }
+ //
+ // Bulldozer or later: assume 1.4 IPC
+ if(id->vendor == VENDOR_AMD && id->ext_family >= 21)
+ {
+ debugf(1, "cpu_clock_by_ic: Bulldozer (or later) detected, dividing result by 1.4\n");
+ *numerator = 5;
+ *denom = 7; // multiply by 5/7, to divide by 1.4
+ }
+ //
+ // Skylake or later: assume 1.6 IPC
+ if(id->vendor == VENDOR_INTEL && id->ext_model >= 94)
+ {
+ debugf(1, "cpu_clock_by_ic: Skylake (or later) detected, dividing result by 1.6\n");
+ *numerator = 5;
+ *denom = 8; // to divide by 1.6, multiply by 5/8
+ }
+}
+
+int cpu_clock_by_ic(int millis, int runs)
+{
+ int max_value = 0, cur_value, i, ri, cycles_inner, cycles_outer, c;
+ struct cpu_id_t* id;
+ uint64_t t0, t1, tl, hz;
+ int multiplier_numerator = 1, multiplier_denom = 1;
+ if(millis <= 0 || runs <= 0)
+ {
+ return -2;
+ }
+ id = get_cached_cpuid();
+ // if there aren't SSE instructions - we can't run the test at all
+ if(!id || !id->flags[CPU_FEATURE_SSE])
+ {
+ return -1;
+ }
+ //
+ adjust_march_ic_multiplier(id, &multiplier_numerator, &multiplier_denom);
+ //
+ tl = millis * 125; // (*1000 / 8)
+ cycles_inner = 128;
+ cycles_outer = 1;
+ do
+ {
+ if(cycles_inner < 1000000000)
+ {
+ cycles_inner *= 2;
+ }
+ else
+ {
+ cycles_outer *= 2;
+ }
+ sys_precise_clock(&t0);
+ for(i = 0; i < cycles_outer; i++)
+ {
+ busy_sse_loop(cycles_inner);
+ }
+ sys_precise_clock(&t1);
+ }
+ while(t1 - t0 < tl);
+ debugf(2, "inner: %d, outer: %d\n", cycles_inner, cycles_outer);
+ for(ri = 0; ri < runs; ri++)
+ {
+ sys_precise_clock(&t0);
+ c = 0;
+ do
+ {
+ c++;
+ for(i = 0; i < cycles_outer; i++)
+ {
+ busy_sse_loop(cycles_inner);
+ }
+ sys_precise_clock(&t1);
+ }
+ while(t1 - t0 < tl * (uint64_t) 8);
+ // cpu_Hz = cycles_inner * cycles_outer * 256 / (t1 - t0) * 1000000
+ debugf(2, "c = %d, td = %d\n", c, (int)(t1 - t0));
+ hz = ((uint64_t) cycles_inner * (uint64_t) 256 + 12) *
+ (uint64_t) cycles_outer * (uint64_t) multiplier_numerator * (uint64_t) c * (uint64_t) 1000000
+ / ((t1 - t0) * (uint64_t) multiplier_denom);
+ cur_value = (int)(hz / 1000000);
+ if(cur_value > max_value)
+ {
+ max_value = cur_value;
+ }
+ }
+ return max_value;
+}
+
+int cpu_clock(void)
+{
+ int result;
+ result = cpu_clock_by_os();
+ if(result <= 0)
+ {
+ result = cpu_clock_measure(200, 1);
+ }
+ return result;
+}
diff --git a/src/3rdparty/libcpuid/rdtsc.h b/src/3rdparty/libcpuid/rdtsc.h
new file mode 100644
index 00000000..7a3307d9
--- /dev/null
+++ b/src/3rdparty/libcpuid/rdtsc.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010 Veselin Georgiev,
+ * anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __RDTSC_H__
+#define __RDTSC_H__
+
+void sys_precise_clock(uint64_t* result);
+int busy_loop_delay(int milliseconds);
+
+
+#endif /* __RDTSC_H__ */
diff --git a/src/3rdparty/libcpuid/recog_amd.c b/src/3rdparty/libcpuid/recog_amd.c
index c7f48000..1c851901 100644
--- a/src/3rdparty/libcpuid/recog_amd.c
+++ b/src/3rdparty/libcpuid/recog_amd.c
@@ -58,6 +58,238 @@ enum _amd_model_codes_t
_1600,
};
+
+const struct match_entry_t cpudb_amd[] =
+{
+ { -1, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD CPU" },
+
+ /* 486 and the likes */
+ { 4, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD 486" },
+ { 4, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX2" },
+ { 4, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX2WB" },
+ { 4, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX4" },
+ { 4, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX4WB" },
+
+ /* Pentia clones */
+ { 5, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD 586" },
+ { 5, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
+ { 5, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
+ { 5, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
+ { 5, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
+
+ /* The K6 */
+ { 5, 6, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6" },
+ { 5, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6" },
+
+ { 5, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-2" },
+ { 5, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-III" },
+ { 5, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" },
+ { 5, 11, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" },
+ { 5, 12, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" },
+ { 5, 13, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-2+" },
+
+ /* Athlon et al. */
+ { 6, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (Slot-A)" },
+ { 6, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (Slot-A)" },
+ { 6, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Duron (Spitfire)" },
+ { 6, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (ThunderBird)" },
+
+ { 6, 6, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Athlon" },
+ { 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_ , 0, "Athlon (Palomino)" },
+ { 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _MP_ , 0, "Athlon MP (Palomino)" },
+ { 6, 6, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Palomino)" },
+ { 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ , 0, "Athlon XP" },
+
+ { 6, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Athlon XP" },
+ { 6, 7, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Morgan)" },
+
+ { 6, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon XP" },
+ { 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ , 0, "Athlon XP (Thoroughbred)" },
+ { 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ , 0, "Athlon XP (Thoroughbred)" },
+ { 6, 8, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Applebred)" },
+ { 6, 8, -1, -1, -1, 1, -1, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" },
+ { 6, 8, -1, -1, -1, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" },
+ { 6, 8, -1, -1, -1, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" },
+ { 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _MP_ , 0, "Athlon MP (Thoroughbred)" },
+ { 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ | _M_ , 0, "Mobile Athlon (T-Bred)" },
+ { 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ | _M_ | _LV_, 0, "Mobile Athlon (T-Bred)" },
+
+ { 6, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon XP (Barton)" },
+ { 6, 10, -1, -1, -1, 1, 512, -1, NC, ATHLON_ | _XP_ , 0, "Athlon XP (Barton)" },
+ { 6, 10, -1, -1, -1, 1, 512, -1, NC, SEMPRON_ , 0, "Sempron (Barton)" },
+ { 6, 10, -1, -1, -1, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron (Thorton)" },
+ { 6, 10, -1, -1, -1, 1, 256, -1, NC, ATHLON_ | _XP_ , 0, "Athlon XP (Thorton)" },
+ { 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _MP_ , 0, "Athlon MP (Barton)" },
+ { 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ | _M_ , 0, "Mobile Athlon (Barton)" },
+ { 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ | _M_ | _LV_, 0, "Mobile Athlon (Barton)" },
+
+ /* K8 Architecture */
+ { 15, -1, -1, 15, -1, 1, -1, -1, NC, 0 , 0, "Unknown K8" },
+ { 15, -1, -1, 16, -1, 1, -1, -1, NC, 0 , 0, "Unknown K9" },
+
+ { 15, -1, -1, 15, -1, 1, -1, -1, NC, 0 , 0, "Unknown A64" },
+ { 15, -1, -1, 15, -1, 1, -1, -1, NC, OPTERON_ , 0, "Opteron" },
+ { 15, -1, -1, 15, -1, 2, -1, -1, NC, OPTERON_ | _X2 , 0, "Opteron (Dual Core)" },
+ { 15, 3, -1, 15, -1, 1, -1, -1, NC, OPTERON_ , 0, "Opteron" },
+ { 15, 3, -1, 15, -1, 2, -1, -1, NC, OPTERON_ | _X2 , 0, "Opteron (Dual Core)" },
+ { 15, -1, -1, 15, -1, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (512K)" },
+ { 15, -1, -1, 15, -1, 1, 1024, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (1024K)" },
+ { 15, -1, -1, 15, -1, 1, -1, -1, NC, ATHLON_ | _FX , 0, "Athlon FX" },
+ { 15, -1, -1, 15, -1, 1, -1, -1, NC, ATHLON_ | _64_ | _FX , 0, "Athlon 64 FX" },
+ { 15, 3, -1, 15, 35, 2, -1, -1, NC, ATHLON_ | _64_ | _FX , 0, "Athlon 64 FX X2 (Toledo)" },
+ { 15, -1, -1, 15, -1, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (512K)" },
+ { 15, -1, -1, 15, -1, 2, 1024, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (1024K)" },
+ { 15, -1, -1, 15, -1, 1, 512, -1, NC, TURION_ | _64_ , 0, "Turion 64 (512K)" },
+ { 15, -1, -1, 15, -1, 1, 1024, -1, NC, TURION_ | _64_ , 0, "Turion 64 (1024K)" },
+ { 15, -1, -1, 15, -1, 2, 512, -1, NC, TURION_ | _X2 , 0, "Turion 64 X2 (512K)" },
+ { 15, -1, -1, 15, -1, 2, 1024, -1, NC, TURION_ | _X2 , 0, "Turion 64 X2 (1024K)" },
+ { 15, -1, -1, 15, -1, 1, 128, -1, NC, SEMPRON_ , 0, "A64 Sempron (128K)" },
+ { 15, -1, -1, 15, -1, 1, 256, -1, NC, SEMPRON_ , 0, "A64 Sempron (256K)" },
+ { 15, -1, -1, 15, -1, 1, 512, -1, NC, SEMPRON_ , 0, "A64 Sempron (512K)" },
+ { 15, -1, -1, 15, 0x4f, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Orleans/512K)" },
+ { 15, -1, -1, 15, 0x5f, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Orleans/512K)" },
+ { 15, -1, -1, 15, 0x2f, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Venice/512K)" },
+ { 15, -1, -1, 15, 0x2c, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Venice/512K)" },
+ { 15, -1, -1, 15, 0x1f, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Winchester/512K)" },
+ { 15, -1, -1, 15, 0x0c, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Newcastle/512K)" },
+ { 15, -1, -1, 15, 0x27, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (San Diego/512K)" },
+ { 15, -1, -1, 15, 0x37, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (San Diego/512K)" },
+ { 15, -1, -1, 15, 0x04, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (ClawHammer/512K)" },
+
+ { 15, -1, -1, 15, 0x5f, 1, 1024, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Orleans/1024K)" },
+ { 15, -1, -1, 15, 0x27, 1, 1024, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (San Diego/1024K)" },
+ { 15, -1, -1, 15, 0x04, 1, 1024, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (ClawHammer/1024K)" },
+
+ { 15, -1, -1, 15, 0x4b, 2, 256, -1, NC, SEMPRON_ , 0, "Athlon 64 X2 (Windsor/256K)" },
+
+ { 15, -1, -1, 15, 0x23, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Toledo/512K)" },
+ { 15, -1, -1, 15, 0x4b, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Windsor/512K)" },
+ { 15, -1, -1, 15, 0x43, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Windsor/512K)" },
+ { 15, -1, -1, 15, 0x6b, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Brisbane/512K)" },
+ { 15, -1, -1, 15, 0x2b, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Manchester/512K)"},
+
+ { 15, -1, -1, 15, 0x23, 2, 1024, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Toledo/1024K)" },
+ { 15, -1, -1, 15, 0x43, 2, 1024, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Windsor/1024K)" },
+
+ { 15, -1, -1, 15, 0x08, 1, 128, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Dublin/128K)"},
+ { 15, -1, -1, 15, 0x08, 1, 256, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Dublin/256K)"},
+ { 15, -1, -1, 15, 0x0c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Paris)" },
+ { 15, -1, -1, 15, 0x1c, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" },
+ { 15, -1, -1, 15, 0x1c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" },
+ { 15, -1, -1, 15, 0x1c, 1, 128, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Sonora/128K)"},
+ { 15, -1, -1, 15, 0x1c, 1, 256, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Sonora/256K)"},
+ { 15, -1, -1, 15, 0x2c, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" },
+ { 15, -1, -1, 15, 0x2c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" },
+ { 15, -1, -1, 15, 0x2c, 1, 128, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Albany/128K)"},
+ { 15, -1, -1, 15, 0x2c, 1, 256, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Albany/256K)"},
+ { 15, -1, -1, 15, 0x2f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" },
+ { 15, -1, -1, 15, 0x2f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" },
+ { 15, -1, -1, 15, 0x4f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/128K)" },
+ { 15, -1, -1, 15, 0x4f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/256K)" },
+ { 15, -1, -1, 15, 0x5f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/128K)" },
+ { 15, -1, -1, 15, 0x5f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/256K)" },
+ { 15, -1, -1, 15, 0x6b, 2, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 Dual (Sherman/256K)"},
+ { 15, -1, -1, 15, 0x6b, 2, 512, -1, NC, SEMPRON_ , 0, "Sempron 64 Dual (Sherman/512K)"},
+ { 15, -1, -1, 15, 0x7f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Sparta/256K)" },
+ { 15, -1, -1, 15, 0x7f, 1, 512, -1, NC, SEMPRON_ , 0, "Sempron 64 (Sparta/512K)" },
+ { 15, -1, -1, 15, 0x4c, 1, 256, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Keene/256K)"},
+ { 15, -1, -1, 15, 0x4c, 1, 512, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Keene/512K)"},
+ { 15, -1, -1, 15, -1, 2, -1, -1, NC, SEMPRON_ , 0, "Sempron Dual Core" },
+
+ { 15, -1, -1, 15, 0x24, 1, 512, -1, NC, TURION_ | _64_ , 0, "Turion 64 (Lancaster/512K)" },
+ { 15, -1, -1, 15, 0x24, 1, 1024, -1, NC, TURION_ | _64_ , 0, "Turion 64 (Lancaster/1024K)" },
+ { 15, -1, -1, 15, 0x48, 2, 256, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Taylor)" },
+ { 15, -1, -1, 15, 0x48, 2, 512, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Trinidad)" },
+ { 15, -1, -1, 15, 0x4c, 1, 512, -1, NC, TURION_ | _64_ , 0, "Turion 64 (Richmond)" },
+ { 15, -1, -1, 15, 0x68, 2, 256, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Tyler/256K)" },
+ { 15, -1, -1, 15, 0x68, 2, 512, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Tyler/512K)" },
+ { 15, -1, -1, 17, 3, 2, 512, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Griffin/512K)" },
+ { 15, -1, -1, 17, 3, 2, 1024, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Griffin/1024K)" },
+
+ /* K10 Architecture (2007) */
+ { 15, -1, -1, 16, -1, 1, -1, -1, PHENOM, 0 , 0, "Unknown AMD Phenom" },
+ { 15, 2, -1, 16, -1, 1, -1, -1, PHENOM, 0 , 0, "Phenom" },
+ { 15, 2, -1, 16, -1, 3, -1, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman)" },
+ { 15, 2, -1, 16, -1, 4, -1, -1, PHENOM, 0 , 0, "Phenom X4 (Agena)" },
+ { 15, 2, -1, 16, -1, 3, 512, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman/256K)" },
+ { 15, 2, -1, 16, -1, 3, 512, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman/512K)" },
+ { 15, 2, -1, 16, -1, 4, 128, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/128K)" },
+ { 15, 2, -1, 16, -1, 4, 256, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/256K)" },
+ { 15, 2, -1, 16, -1, 4, 512, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/512K)" },
+ { 15, 2, -1, 16, -1, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon X2 (Kuma)" },
+ /* Phenom II derivates: */
+ { 15, 4, -1, 16, -1, 4, -1, -1, NC, 0 , 0, "Phenom (Deneb-based)" },
+ { 15, 4, -1, 16, -1, 1, 1024, -1, NC, SEMPRON_ , 0, "Sempron (Sargas)" },
+ { 15, 4, -1, 16, -1, 2, 512, -1, PHENOM2, 0 , 0, "Phenom II X2 (Callisto)" },
+ { 15, 4, -1, 16, -1, 3, 512, -1, PHENOM2, 0 , 0, "Phenom II X3 (Heka)" },
+ { 15, 4, -1, 16, -1, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4" },
+ { 15, 4, -1, 16, 4, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Deneb)" },
+ { 15, 5, -1, 16, 5, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Deneb)" },
+ { 15, 4, -1, 16, 10, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Zosma)" },
+ { 15, 4, -1, 16, 10, 6, 512, -1, PHENOM2, 0 , 0, "Phenom II X6 (Thuban)" },
+ /* Athlon II derivates: */
+ { 15, 6, -1, 16, 6, 2, 512, -1, NC, ATHLON_ | _X2 , 0, "Athlon II (Champlain)" },
+ { 15, 6, -1, 16, 6, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon II X2 (Regor)" },
+ { 15, 6, -1, 16, 6, 2, 1024, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon II X2 (Regor)" },
+ { 15, 5, -1, 16, 5, 3, 512, -1, NC, ATHLON_ | _64_ | _X3 , 0, "Athlon II X3 (Rana)" },
+ { 15, 5, -1, 16, 5, 4, 512, -1, NC, ATHLON_ | _64_ | _X4 , 0, "Athlon II X4 (Propus)" },
+ /* Llano APUs (2011): */
+ { 15, 1, -1, 18, 1, 2, -1, -1, FUSION_EA, 0 , 0, "Llano X2" },
+ { 15, 1, -1, 18, 1, 3, -1, -1, FUSION_EA, 0 , 0, "Llano X3" },
+ { 15, 1, -1, 18, 1, 4, -1, -1, FUSION_EA, 0 , 0, "Llano X4" },
+
+ /* Family 14h: Bobcat Architecture (2011) */
+ { 15, 2, -1, 20, -1, 1, -1, -1, FUSION_C, 0 , 0, "Brazos Ontario" },
+ { 15, 2, -1, 20, -1, 2, -1, -1, FUSION_C, 0 , 0, "Brazos Ontario (Dual-core)" },
+ { 15, 1, -1, 20, -1, 1, -1, -1, FUSION_E, 0 , 0, "Brazos Zacate" },
+ { 15, 1, -1, 20, -1, 2, -1, -1, FUSION_E, 0 , 0, "Brazos Zacate (Dual-core)" },
+ { 15, 2, -1, 20, -1, 2, -1, -1, FUSION_Z, 0 , 0, "Brazos Desna (Dual-core)" },
+
+ /* Family 15h: Bulldozer Architecture (2011) */
+ { 15, -1, -1, 21, 0, 4, -1, -1, NC, 0 , 0, "Bulldozer X2" },
+ { 15, -1, -1, 21, 1, 4, -1, -1, NC, 0 , 0, "Bulldozer X2" },
+ { 15, -1, -1, 21, 1, 6, -1, -1, NC, 0 , 0, "Bulldozer X3" },
+ { 15, -1, -1, 21, 1, 8, -1, -1, NC, 0 , 0, "Bulldozer X4" },
+ /* 2nd-gen, Piledriver core (2012): */
+ { 15, -1, -1, 21, 2, 4, -1, -1, NC, 0 , 0, "Vishera X2" },
+ { 15, -1, -1, 21, 2, 6, -1, -1, NC, 0 , 0, "Vishera X3" },
+ { 15, -1, -1, 21, 2, 8, -1, -1, NC, 0 , 0, "Vishera X4" },
+ { 15, 0, -1, 21, 16, 2, -1, -1, FUSION_A, 0 , 0, "Trinity X2" },
+ { 15, 0, -1, 21, 16, 4, -1, -1, FUSION_A, 0 , 0, "Trinity X4" },
+ { 15, 3, -1, 21, 19, 2, -1, -1, FUSION_A, 0 , 0, "Richland X2" },
+ { 15, 3, -1, 21, 19, 4, -1, -1, FUSION_A, 0 , 0, "Richland X4" },
+ /* 3rd-gen, Steamroller core (2014): */
+ { 15, 0, -1, 21, 48, 2, -1, -1, FUSION_A, 0 , 0, "Kaveri X2" },
+ { 15, 0, -1, 21, 48, 4, -1, -1, FUSION_A, 0 , 0, "Kaveri X4" },
+ { 15, 8, -1, 21, 56, 4, -1, -1, FUSION_A, 0 , 0, "Godavari X4" },
+ /* 4th-gen, Excavator core (2015): */
+ { 15, 1, -1, 21, 96, 2, -1, -1, FUSION_A, 0 , 0, "Carrizo X2" },
+ { 15, 1, -1, 21, 96, 4, -1, -1, FUSION_A, 0 , 0, "Carrizo X4" },
+ { 15, 5, -1, 21, 101, 2, -1, -1, FUSION_A, 0 , 0, "Bristol Ridge X2" },
+ { 15, 5, -1, 21, 101, 4, -1, -1, FUSION_A, 0 , 0, "Bristol Ridge X4" },
+ { 15, 0, -1, 21, 112, 2, -1, -1, FUSION_A, 0 , 0, "Stoney Ridge X2" },
+ { 15, 0, -1, 21, 112, 2, -1, -1, FUSION_E, 0 , 0, "Stoney Ridge X2" },
+
+ /* Family 16h: Jaguar Architecture (2013) */
+ { 15, 0, -1, 22, 0, 2, -1, -1, FUSION_A, 0 , 0, "Kabini X2" },
+ { 15, 0, -1, 22, 0, 4, -1, -1, FUSION_A, 0 , 0, "Kabini X4" },
+ /* 2nd-gen, Puma core (2013): */
+ { 15, 0, -1, 22, 48, 2, -1, -1, FUSION_E, 0 , 0, "Mullins X2" },
+ { 15, 0, -1, 22, 48, 4, -1, -1, FUSION_A, 0 , 0, "Mullins X4" },
+
+ /* Family 17h: Zen Architecture (2017) */
+ { 15, -1, -1, 23, 1, 8, -1, -1, NC, 0 , 0, "Ryzen 7" },
+ { 15, -1, -1, 23, 1, 6, -1, -1, NC, 0 , _1600, "Ryzen 5" },
+ { 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , _1500, "Ryzen 5" },
+ { 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , _1400, "Ryzen 5" },
+ { 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , 0, "Ryzen 3" },
+ //{ 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , 0, "Raven Ridge" }, //TBA
+
+ /* Newer Opterons: */
+ { 15, 9, -1, 22, 9, 8, -1, -1, NC, OPTERON_ , 0, "Magny-Cours Opteron" },
+};
+
+
static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{
const struct feature_map_t matchtable_edx81[] =
@@ -190,10 +422,217 @@ static void decode_amd_number_of_cores(struct cpu_raw_data_t* raw, struct cpu_id
}
}
+static int amd_has_turion_modelname(const char* bs)
+{
+ /* We search for something like TL-60. Ahh, I miss regexes...*/
+ int i, l, k;
+ char code[3] = {0};
+ const char* codes[] = { "ML", "MT", "MK", "TK", "TL", "RM", "ZM", "" };
+ l = (int) strlen(bs);
+ for(i = 3; i < l - 2; i++)
+ {
+ if(bs[i] == '-' &&
+ isupper(bs[i - 1]) && isupper(bs[i - 2]) && !isupper(bs[i - 3]) &&
+ isdigit(bs[i + 1]) && isdigit(bs[i + 2]) && !isdigit(bs[i + 3]))
+ {
+ code[0] = bs[i - 2];
+ code[1] = bs[i - 1];
+ for(k = 0; codes[k][0]; k++)
+ if(!strcmp(codes[k], code))
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static struct amd_code_and_bits_t decode_amd_codename_part1(const char* bs)
+{
+ amd_code_t code = NC;
+ uint64_t bits = 0;
+ struct amd_code_and_bits_t result;
+
+ if(strstr(bs, "Dual Core") ||
+ strstr(bs, "Dual-Core") ||
+ strstr(bs, " X2 "))
+ {
+ bits |= _X2;
+ }
+ if(strstr(bs, " X4 "))
+ {
+ bits |= _X4;
+ }
+ if(strstr(bs, " X3 "))
+ {
+ bits |= _X3;
+ }
+ if(strstr(bs, "Opteron"))
+ {
+ bits |= OPTERON_;
+ }
+ if(strstr(bs, "Phenom"))
+ {
+ code = (strstr(bs, "II")) ? PHENOM2 : PHENOM;
+ }
+ if(amd_has_turion_modelname(bs))
+ {
+ bits |= TURION_;
+ }
+ if(strstr(bs, "Athlon(tm)"))
+ {
+ bits |= ATHLON_;
+ }
+ if(strstr(bs, "Sempron(tm)"))
+ {
+ bits |= SEMPRON_;
+ }
+ if(strstr(bs, "Duron"))
+ {
+ bits |= DURON_;
+ }
+ if(strstr(bs, " 64 "))
+ {
+ bits |= _64_;
+ }
+ if(strstr(bs, " FX"))
+ {
+ bits |= _FX;
+ }
+ if(strstr(bs, " MP"))
+ {
+ bits |= _MP_;
+ }
+ if(strstr(bs, "Athlon(tm) 64") || strstr(bs, "Athlon(tm) II X") || match_pattern(bs, "Athlon(tm) X#"))
+ {
+ bits |= ATHLON_ | _64_;
+ }
+ if(strstr(bs, "Turion"))
+ {
+ bits |= TURION_;
+ }
+
+ if(strstr(bs, "mobile") || strstr(bs, "Mobile"))
+ {
+ bits |= MOBILE_;
+ }
+
+ if(strstr(bs, "XP"))
+ {
+ bits |= _XP_;
+ }
+ if(strstr(bs, "XP-M"))
+ {
+ bits |= _M_;
+ }
+ if(strstr(bs, "(LV)"))
+ {
+ bits |= _LV_;
+ }
+ if(strstr(bs, " APU "))
+ {
+ bits |= _APU_;
+ }
+
+ if(match_pattern(bs, "C-##"))
+ {
+ code = FUSION_C;
+ }
+ if(match_pattern(bs, "E-###"))
+ {
+ code = FUSION_E;
+ }
+ if(match_pattern(bs, "Z-##"))
+ {
+ code = FUSION_Z;
+ }
+ if(match_pattern(bs, "[EA]#-####"))
+ {
+ code = FUSION_EA;
+ }
+
+ result.code = code;
+ result.bits = bits;
+ return result;
+}
+
+static int decode_amd_ryzen_model_code(const char* bs)
+{
+ const struct
+ {
+ int model_code;
+ const char* match_str;
+ } patterns[] =
+ {
+ { _1600, "1600" },
+ { _1500, "1500" },
+ { _1400, "1400" },
+ };
+ int i;
+
+ for(i = 0; i < COUNT_OF(patterns); i++)
+ if(strstr(bs, patterns[i].match_str))
+ {
+ return patterns[i].model_code;
+ }
+ //
+ return 0;
+}
+
+static void decode_amd_codename(struct cpu_raw_data_t* raw, struct cpu_id_t* data,
+ struct internal_id_info_t* internal)
+{
+ struct amd_code_and_bits_t code_and_bits = decode_amd_codename_part1(data->brand_str);
+ int i = 0;
+ char* code_str = NULL;
+ int model_code;
+
+ for(i = 0; i < COUNT_OF(amd_code_str); i++)
+ {
+ if(code_and_bits.code == amd_code_str[i].code)
+ {
+ code_str = amd_code_str[i].str;
+ break;
+ }
+ }
+ if(/*code == ATHLON_64_X2*/ match_all(code_and_bits.bits, ATHLON_ | _64_ | _X2) && data->l2_cache < 512)
+ {
+ code_and_bits.bits &= ~(ATHLON_ | _64_);
+ code_and_bits.bits |= SEMPRON_;
+ }
+ if(code_str)
+ {
+ debugf(2, "Detected AMD brand code: %d (%s)\n", code_and_bits.code, code_str);
+ }
+ else
+ {
+ debugf(2, "Detected AMD brand code: %d\n", code_and_bits.code);
+ }
+
+ if(code_and_bits.bits)
+ {
+ debugf(2, "Detected AMD bits: ");
+ debug_print_lbits(2, code_and_bits.bits);
+ }
+ // is it Ryzen? if so, we need to detect discern between the four-core 1400/1500 (Ryzen 5) and the four-core Ryzen 3:
+ model_code = (data->ext_family == 23) ? decode_amd_ryzen_model_code(data->brand_str) : 0;
+
+ internal->code.amd = code_and_bits.code;
+ internal->bits = code_and_bits.bits;
+ internal->score = match_cpu_codename(cpudb_amd, COUNT_OF(cpudb_amd), data, code_and_bits.code,
+ code_and_bits.bits, model_code);
+}
+
int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal)
{
load_amd_features(raw, data);
decode_amd_cache_info(raw, data);
decode_amd_number_of_cores(raw, data);
+ decode_amd_codename(raw, data, internal);
return 0;
}
+
+void cpuid_get_list_amd(struct cpu_list_t* list)
+{
+ generic_get_cpu_list(cpudb_amd, COUNT_OF(cpudb_amd), list);
+}
diff --git a/src/3rdparty/libcpuid/recog_amd.h b/src/3rdparty/libcpuid/recog_amd.h
index 19f839ba..34e89598 100644
--- a/src/3rdparty/libcpuid/recog_amd.h
+++ b/src/3rdparty/libcpuid/recog_amd.h
@@ -27,5 +27,6 @@
#define __RECOG_AMD_H__
int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal);
+void cpuid_get_list_amd(struct cpu_list_t* list);
#endif /* __RECOG_AMD_H__ */
diff --git a/src/3rdparty/libcpuid/recog_intel.c b/src/3rdparty/libcpuid/recog_intel.c
index 850bbb56..3e4707ac 100644
--- a/src/3rdparty/libcpuid/recog_intel.c
+++ b/src/3rdparty/libcpuid/recog_intel.c
@@ -66,6 +66,298 @@ enum _intel_model_t
};
typedef enum _intel_model_t intel_model_t;
+const struct match_entry_t cpudb_intel[] =
+{
+ { -1, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Intel CPU" },
+
+ /* i486 */
+ { 4, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown i486" },
+ { 4, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX-25/33" },
+ { 4, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX-50" },
+ { 4, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SX" },
+ { 4, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX2" },
+ { 4, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SL" },
+ { 4, 5, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SX2" },
+ { 4, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX2 WriteBack" },
+ { 4, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX4" },
+ { 4, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX4 WriteBack" },
+
+ /* All Pentia:
+ Pentium 1 */
+ { 5, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium" },
+ { 5, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium A-Step" },
+ { 5, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.8u)" },
+ { 5, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" },
+ { 5, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium OverDrive" },
+ { 5, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" },
+ { 5, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" },
+ { 5, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium MMX (0.25u)" },
+
+ /* Pentium 2 / 3 / M / Conroe / whatsnext - all P6 based. */
+ { 6, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown P6" },
+ { 6, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium Pro" },
+ { 6, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium Pro" },
+ { 6, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium II (Klamath)" },
+ { 6, 5, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium II (Deschutes)" },
+ { 6, 5, -1, -1, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile Pentium II (Tonga)"},
+ { 6, 6, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium II (Dixon)" },
+
+ { 6, 3, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Klamath)" },
+ { 6, 5, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Drake)" },
+ { 6, 6, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Dixon)" },
+
+ { 6, 5, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-II Celeron (Covington)" },
+ { 6, 6, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-II Celeron (Mendocino)" },
+
+ /* -------------------------------------------------- */
+
+ { 6, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Katmai)" },
+ { 6, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Coppermine)"},
+ { 6, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Coppermine)"},
+ { 6, 11, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Tualatin)" },
+
+ { 6, 7, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Tanner)" },
+ { 6, 8, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Cascades)" },
+ { 6, 10, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Cascades)" },
+ { 6, 11, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Tualatin)" },
+
+ { 6, 7, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Katmai)" },
+ { 6, 8, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Coppermine)" },
+ { 6, 10, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Coppermine)" },
+ { 6, 11, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Tualatin)" },
+
+ /* Netburst based (Pentium 4 and later)
+ classic P4s */
+ { 15, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium 4" },
+ { 15, -1, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "Unknown P-4 Celeron" },
+ { 15, -1, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Unknown Xeon" },
+
+ { 15, 0, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Willamette)" },
+ { 15, 1, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Willamette)" },
+ { 15, 2, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Northwood)" },
+ { 15, 3, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Prescott)" },
+ { 15, 4, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Prescott)" },
+ { 15, 6, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Cedar Mill)" },
+ { 15, 0, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Willamette)" },
+ { 15, 1, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Willamette)" },
+ { 15, 2, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Northwood)" },
+ { 15, 3, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Prescott)" },
+ { 15, 4, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Prescott)" },
+ { 15, 6, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Cedar Mill)" },
+
+ /* server CPUs */
+ { 15, 0, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" },
+ { 15, 1, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" },
+ { 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Prestonia)" },
+ { 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_ | _MP_ , 0, "Xeon (Gallatin)" },
+ { 15, 3, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" },
+ { 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" },
+ { 15, 4, -1, 15, -1, 1, -1, -1, IRWIN, XEON_ , 0, "Xeon (Irwindale)" },
+ { 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_ | _MP_ , 0, "Xeon (Cranford)" },
+ { 15, 4, -1, 15, -1, 1, -1, -1, POTOMAC, XEON_ , 0, "Xeon (Potomac)" },
+ { 15, 6, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Dempsey)" },
+
+ /* Pentium Ds */
+ { 15, 4, 4, 15, -1, 1, -1, -1, NC, 0 , 0, "Pentium D (SmithField)" },
+ { 15, 4, -1, 15, -1, 1, -1, -1, PENTIUM_D, 0 , 0, "Pentium D (SmithField)" },
+ { 15, 4, 7, 15, -1, 1, -1, -1, NC, 0 , 0, "Pentium D (SmithField)" },
+ { 15, 6, -1, 15, -1, 1, -1, -1, PENTIUM_D, 0 , 0, "Pentium D (Presler)" },
+
+ /* Celeron and Celeron Ds */
+ { 15, 1, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron (Willamette)" },
+ { 15, 2, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron (Northwood)" },
+ { 15, 3, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Prescott)" },
+ { 15, 4, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Prescott)" },
+ { 15, 6, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Cedar Mill)" },
+
+ /* -------------------------------------------------- */
+ /* Intel Core microarchitecture - P6-based */
+
+ { 6, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium M" },
+ { 6, 9, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Unknown Pentium M" },
+ { 6, 9, -1, -1, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium M (Banias)" },
+ { 6, 9, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Pentium M (Banias)" },
+ { 6, 9, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "Celeron M" },
+ { 6, 13, -1, -1, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium M (Dothan)" },
+ { 6, 13, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Pentium M (Dothan)" },
+ { 6, 13, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "Celeron M" },
+
+ { 6, 12, -1, -1, -1, -1, -1, -1, NC, ATOM_ , 0, "Unknown Atom" },
+ { 6, 12, -1, -1, -1, -1, -1, -1, DIAMONDVILLE, ATOM_, 0, "Atom (Diamondville)" },
+ { 6, 12, -1, -1, -1, -1, -1, -1, SILVERTHORNE, ATOM_, 0, "Atom (Silverthorne)" },
+ { 6, 12, -1, -1, -1, -1, -1, -1, CEDARVIEW, ATOM_ , 0, "Atom (Cedarview)" },
+ { 6, 6, -1, -1, -1, -1, -1, -1, CEDARVIEW, ATOM_ , 0, "Atom (Cedarview)" },
+ { 6, 12, -1, -1, -1, -1, -1, -1, PINEVIEW, ATOM_ , 0, "Atom (Pineview)" },
+
+ /* -------------------------------------------------- */
+
+ { 6, 14, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Yonah" },
+ { 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, 0 , 0, "Yonah (Core Solo)" },
+ { 6, 14, -1, -1, -1, 2, -1, -1, CORE_DUO, 0 , 0, "Yonah (Core Duo)" },
+ { 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, MOBILE_, 0, "Yonah (Core Solo)" },
+ { 6, 14, -1, -1, -1, 2, -1, -1, CORE_DUO , MOBILE_, 0, "Yonah (Core Duo)" },
+ { 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, 0 , 0, "Yonah (Core Solo)" },
+
+ { 6, 15, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Core 2" },
+ { 6, 15, -1, -1, -1, 2, 4096, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo)" },
+ { 6, 15, -1, -1, -1, 2, 1024, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo) 1024K" },
+ { 6, 15, -1, -1, -1, 2, 512, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo) 512K" },
+ { 6, 15, -1, -1, -1, 4, -1, -1, QUAD_CORE, 0 , 0, "Kentsfield (Core 2 Quad)" },
+ { 6, 15, -1, -1, -1, 4, 4096, -1, QUAD_CORE, 0 , 0, "Kentsfield (Core 2 Quad)" },
+ { 6, 15, -1, -1, -1, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" },
+ { 6, 15, -1, -1, -1, 2, 2048, -1, CORE_DUO, 0 , 0, "Allendale (Core 2 Duo)" },
+ { 6, 15, -1, -1, -1, 2, -1, -1, MOBILE_CORE_DUO, 0, 0, "Merom (Core 2 Duo)" },
+ { 6, 15, -1, -1, -1, 2, 2048, -1, MEROM, 0 , 0, "Merom (Core 2 Duo) 2048K" },
+ { 6, 15, -1, -1, -1, 2, 4096, -1, MEROM, 0 , 0, "Merom (Core 2 Duo) 4096K" },
+
+ { 6, 15, -1, -1, 15, 1, -1, -1, NC, CELERON_ , 0, "Conroe-L (Celeron)" },
+ { 6, 6, -1, -1, 22, 1, -1, -1, NC, CELERON_ , 0, "Conroe-L (Celeron)" },
+ { 6, 15, -1, -1, 15, 2, -1, -1, NC, CELERON_ , 0, "Conroe-L (Allendale)" },
+ { 6, 6, -1, -1, 22, 2, -1, -1, NC, CELERON_ , 0, "Conroe-L (Allendale)" },
+
+
+ { 6, 6, -1, -1, 22, 1, -1, -1, NC, 0 , 0, "Unknown Core ?" },
+ { 6, 7, -1, -1, 23, 1, -1, -1, NC, 0 , 0, "Unknown Core ?" },
+ { 6, 6, -1, -1, 22, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" },
+ { 6, 7, -1, -1, 23, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" },
+
+ { 6, 7, -1, -1, 23, 1, -1, -1, CORE_SOLO , 0, 0, "Unknown Core 45nm" },
+ { 6, 7, -1, -1, 23, 1, -1, -1, CORE_DUO , 0, 0, "Unknown Core 45nm" },
+ { 6, 7, -1, -1, 23, 2, 1024, -1, WOLFDALE , 0, 0, "Celeron Wolfdale 1M" },
+ { 6, 7, -1, -1, 23, 2, 2048, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 2M" },
+ { 6, 7, -1, -1, 23, 2, 3072, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 3M" },
+ { 6, 7, -1, -1, 23, 2, 6144, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 6M" },
+ { 6, 7, -1, -1, 23, 1, -1, -1, MOBILE_CORE_DUO , 0, 0, "Penryn (Core 2 Duo)" },
+ { 6, 7, -1, -1, 23, 2, 1024, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo)" },
+ { 6, 7, -1, -1, 23, 2, 3072, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo) 3M" },
+ { 6, 7, -1, -1, 23, 2, 6144, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo) 6M" },
+ { 6, 7, -1, -1, 23, 4, 2048, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 2M"},
+ { 6, 7, -1, -1, 23, 4, 3072, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 3M"},
+ { 6, 7, -1, -1, 23, 4, 6144, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 6M"},
+
+ /* Core microarchitecture-based Xeons: */
+ { 6, 14, -1, -1, 14, 1, -1, -1, NC, XEON_ , 0, "Xeon LV" },
+ { 6, 15, -1, -1, 15, 2, 4096, -1, NC, XEON_ , _5100, "Xeon (Woodcrest)" },
+ { 6, 15, -1, -1, 15, 2, 2048, -1, NC, XEON_ , _3000, "Xeon (Conroe/2M)" },
+ { 6, 15, -1, -1, 15, 2, 4096, -1, NC, XEON_ , _3000, "Xeon (Conroe/4M)" },
+ { 6, 15, -1, -1, 15, 4, 4096, -1, NC, XEON_ , X3200, "Xeon (Kentsfield)" },
+ { 6, 15, -1, -1, 15, 4, 4096, -1, NC, XEON_ , _5300, "Xeon (Clovertown)" },
+ { 6, 7, -1, -1, 23, 2, 6144, -1, NC, XEON_ , _3100, "Xeon (Wolfdale)" },
+ { 6, 7, -1, -1, 23, 2, 6144, -1, NC, XEON_ , _5200, "Xeon (Wolfdale DP)" },
+ { 6, 7, -1, -1, 23, 4, 6144, -1, NC, XEON_ , _5400, "Xeon (Harpertown)" },
+ { 6, 7, -1, -1, 23, 4, 3072, -1, NC, XEON_ , X3300, "Xeon (Yorkfield/3M)" },
+ { 6, 7, -1, -1, 23, 4, 6144, -1, NC, XEON_ , X3300, "Xeon (Yorkfield/6M)" },
+
+ /* Nehalem CPUs (45nm): */
+ { 6, 10, -1, -1, 26, 4, -1, -1, GAINESTOWN, XEON_ , 0, "Gainestown (Xeon)" },
+ { 6, 10, -1, -1, 26, 4, -1, 4096, GAINESTOWN, XEON_ , 0, "Gainestown 4M (Xeon)" },
+ { 6, 10, -1, -1, 26, 4, -1, 8192, GAINESTOWN, XEON_ , 0, "Gainestown 8M (Xeon)" },
+ { 6, 10, -1, -1, 26, 4, -1, -1, NC, XEON_ | _7 , 0, "Bloomfield (Xeon)" },
+ { 6, 10, -1, -1, 26, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Bloomfield (Core i7)" },
+ { 6, 10, -1, -1, 30, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Lynnfield (Core i7)" },
+ { 6, 5, -1, -1, 37, 4, -1, 8192, NC, CORE_ | _I_ | _5 , 0, "Lynnfield (Core i5)" },
+
+ /* Westmere CPUs (32nm): */
+ { 6, 5, -1, -1, 37, 2, -1, -1, NC, 0 , 0, "Unknown Core i3/i5" },
+ { 6, 12, -1, -1, 44, -1, -1, -1, WESTMERE, XEON_ , 0, "Westmere (Xeon)" },
+ { 6, 12, -1, -1, 44, -1, -1, 12288, WESTMERE, XEON_ , 0, "Gulftown (Xeon)" },
+ { 6, 12, -1, -1, 44, 4, -1, 12288, NC, CORE_ | _I_ | _7 , 0, "Gulftown (Core i7)" },
+ { 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_ | _I_ | _5 , 0, "Clarkdale (Core i5)" },
+ { 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_ | _I_ | _3 , 0, "Clarkdale (Core i3)" },
+ { 6, 5, -1, -1, 37, 2, -1, -1, NC, PENTIUM_ , 0, "Arrandale" },
+ { 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_ | _I_ | _7 , 0, "Arrandale (Core i7)" },
+ { 6, 5, -1, -1, 37, 2, -1, 3072, NC, CORE_ | _I_ | _5 , 0, "Arrandale (Core i5)" },
+ { 6, 5, -1, -1, 37, 2, -1, 3072, NC, CORE_ | _I_ | _3 , 0, "Arrandale (Core i3)" },
+
+ /* Sandy Bridge CPUs (32nm): */
+ { 6, 10, -1, -1, 42, -1, -1, -1, NC, 0 , 0, "Unknown Sandy Bridge" },
+ { 6, 10, -1, -1, 42, -1, -1, -1, NC, XEON_ , 0, "Sandy Bridge (Xeon)" },
+ { 6, 10, -1, -1, 42, -1, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Sandy Bridge (Core i7)" },
+ { 6, 10, -1, -1, 42, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Sandy Bridge (Core i7)" },
+ { 6, 10, -1, -1, 42, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Sandy Bridge (Core i5)" },
+ { 6, 10, -1, -1, 42, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Sandy Bridge (Core i3)" },
+ { 6, 10, -1, -1, 42, 2, -1, -1, NC, PENTIUM_ , 0, "Sandy Bridge (Pentium)" },
+ { 6, 10, -1, -1, 42, 1, -1, -1, NC, CELERON_ , 0, "Sandy Bridge (Celeron)" },
+ { 6, 10, -1, -1, 42, 2, -1, -1, NC, CELERON_ , 0, "Sandy Bridge (Celeron)" },
+ { 6, 13, -1, -1, 45, -1, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Sandy Bridge-E" },
+ { 6, 13, -1, -1, 45, -1, -1, -1, NC, XEON_ , 0, "Sandy Bridge-E (Xeon)" },
+
+ /* Ivy Bridge CPUs (22nm): */
+ { 6, 10, -1, -1, 58, -1, -1, -1, NC, XEON_ , 0, "Ivy Bridge (Xeon)" },
+ { 6, 10, -1, -1, 58, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Ivy Bridge (Core i7)" },
+ { 6, 10, -1, -1, 58, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Ivy Bridge (Core i5)" },
+ { 6, 10, -1, -1, 58, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Ivy Bridge (Core i3)" },
+ { 6, 10, -1, -1, 58, 2, -1, -1, NC, PENTIUM_ , 0, "Ivy Bridge (Pentium)" },
+ { 6, 10, -1, -1, 58, 1, -1, -1, NC, CELERON_ , 0, "Ivy Bridge (Celeron)" },
+ { 6, 10, -1, -1, 58, 2, -1, -1, NC, CELERON_ , 0, "Ivy Bridge (Celeron)" },
+ { 6, 14, -1, -1, 62, -1, -1, -1, NC, 0 , 0, "Ivy Bridge-E" },
+
+ /* Haswell CPUs (22nm): */
+ { 6, 12, -1, -1, 60, -1, -1, -1, NC, XEON_ , 0, "Haswell (Xeon)" },
+ { 6, 12, -1, -1, 60, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Haswell (Core i7)" },
+ { 6, 5, -1, -1, 69, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Haswell (Core i7)" },
+ { 6, 6, -1, -1, 70, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Haswell (Core i7)" },
+ { 6, 12, -1, -1, 60, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Haswell (Core i5)" },
+ { 6, 5, -1, -1, 69, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Haswell (Core i5)" },
+ { 6, 12, -1, -1, 60, 2, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Haswell (Core i5)" },
+ { 6, 5, -1, -1, 69, 2, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Haswell (Core i5)" },
+ { 6, 12, -1, -1, 60, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Haswell (Core i3)" },
+ { 6, 5, -1, -1, 69, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Haswell (Core i3)" },
+ { 6, 12, -1, -1, 60, 2, -1, -1, NC, PENTIUM_ , 0, "Haswell (Pentium)" },
+ { 6, 12, -1, -1, 60, 2, -1, -1, NC, CELERON_ , 0, "Haswell (Celeron)" },
+ { 6, 12, -1, -1, 60, 1, -1, -1, NC, CELERON_ , 0, "Haswell (Celeron)" },
+ { 6, 15, -1, -1, 63, -1, -1, -1, NC, 0 , 0, "Haswell-E" },
+
+ /* Broadwell CPUs (14nm): */
+ { 6, 7, -1, -1, 71, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Broadwell (Core i7)" },
+ { 6, 7, -1, -1, 71, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Broadwell (Core i5)" },
+ { 6, 13, -1, -1, 61, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Broadwell-U (Core i7)" },
+ { 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Broadwell-U (Core i7)" },
+ { 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Broadwell-U (Core i5)" },
+ { 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Broadwell-U (Core i3)" },
+ { 6, 13, -1, -1, 61, 2, -1, -1, NC, PENTIUM_ , 0, "Broadwell-U (Pentium)" },
+ { 6, 13, -1, -1, 61, 2, -1, -1, NC, CELERON_ , 0, "Broadwell-U (Celeron)" },
+ { 6, 13, -1, -1, 61, 2, -1, -1, NA, 0 , 0, "Broadwell-U (Core M)" },
+ { 6, 15, -1, -1, 79, -1, -1, -1, NC, XEON_ , 0, "Broadwell-E (Xeon)" },
+ { 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Broadwell-E (Core i3)" },
+ { 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Broadwell-E (Core i5)" },
+ { 6, 15, -1, -1, 79, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Broadwell-E (Core i5)" },
+ { 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Broadwell-E (Core i7)" },
+ { 6, 15, -1, -1, 79, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Broadwell-E (Core i7)" },
+
+ /* Skylake CPUs (14nm): */
+ { 6, 14, -1, -1, 94, -1, -1, -1, NC, XEON_ , 0, "Skylake (Xeon)" },
+ { 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Skylake (Core i7)" },
+ { 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Skylake (Core i5)" },
+ { 6, 14, -1, -1, 94, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Skylake (Core i3)" },
+ { 6, 14, -1, -1, 94, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" },
+ { 6, 14, -1, -1, 78, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" },
+ { 6, 14, -1, -1, 94, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" },
+ { 6, 14, -1, -1, 78, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" },
+ { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_ | _M_ | _7 , 0, "Skylake (Core m7)" },
+ { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_ | _M_ | _5 , 0, "Skylake (Core m5)" },
+ { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_ | _M_ | _3 , 0, "Skylake (Core m3)" },
+ { 6, 5, -1, -1, 85, 8, -1, -1, NC, XEON_, 0, "Skylake (Xeon Scalable)" },
+
+ /* Kaby Lake CPUs (14nm): */
+ { 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Kaby Lake (Core i7)" },
+ { 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Kaby Lake (Core i5)" },
+ { 6, 14, -1, -1, 158, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Kaby Lake (Core i3)" },
+ { 6, 14, -1, -1, 158, 2, -1, -1, NC, PENTIUM_ , 0, "Kaby Lake (Pentium)" },
+ { 6, 14, -1, -1, 158, 2, -1, -1, NC, CELERON_ , 0, "Kaby Lake (Celeron)" },
+ { 6, 14, -1, -1, 158, 2, -1, -1, NC, CORE_ | _M_ | _3 , 0, "Kaby Lake (Core m3)" },
+
+ /* Coffee Lake CPUs (14nm): */
+ { 6, 14, -1, -1, 158, 6, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Coffee Lake (Core i7)" },
+ { 6, 14, -1, -1, 158, 6, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Coffee Lake (Core i5)" },
+ { 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Coffee Lake (Core i3)" },
+
+ /* Itaniums */
+ { 7, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Itanium" },
+ { 15, -1, -1, 16, -1, 1, -1, -1, NC, 0 , 0, "Itanium 2" },
+};
+
+
static void load_intel_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{
const struct feature_map_t matchtable_edx1[] =
@@ -321,6 +613,8 @@ static void decode_intel_deterministic_cache_info(struct cpu_raw_data_t* raw,
}
else
{
+ warnf("deterministic_cache: unknown level/typenumber combo (%d/%d), cannot\n", level, typenumber);
+ warnf("deterministic_cache: recognize cache type\n");
continue;
}
ways = ((raw->intel_fn4[ecx][1] >> 22) & 0x3ff) + 1;
@@ -491,6 +785,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
code = matchtable[i].c;
break;
}
+ debugf(2, "intel matchtable result is %d\n", code);
if(bits & XEON_)
{
if(match_pattern(bs, "W35##") || match_pattern(bs, "[ELXW]75##"))
@@ -583,6 +878,104 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
return result;
}
+static intel_model_t get_model_code(struct cpu_id_t* data)
+{
+ int i = 0;
+ int l = (int) strlen(data->brand_str);
+ const char* bs = data->brand_str;
+ int mod_flags = 0, model_no = 0, ndigs = 0;
+ /* If the CPU is a Core ix, then just return the model number generation: */
+ if((i = match_pattern(bs, "Core(TM) i[357]")) != 0)
+ {
+ i += 11;
+ if(i + 4 >= l)
+ {
+ return UNKNOWN;
+ }
+ if(bs[i] == '2')
+ {
+ return _2xxx;
+ }
+ if(bs[i] == '3')
+ {
+ return _3xxx;
+ }
+ return UNKNOWN;
+ }
+
+ /* For Core2-based Xeons: */
+ while(i < l - 3)
+ {
+ if(bs[i] == 'C' && bs[i + 1] == 'P' && bs[i + 2] == 'U')
+ {
+ break;
+ }
+ i++;
+ }
+ if(i >= l - 3)
+ {
+ return UNKNOWN;
+ }
+ i += 3;
+ while(i < l - 4 && bs[i] == ' ')
+ {
+ i++;
+ }
+ if(i >= l - 4)
+ {
+ return UNKNOWN;
+ }
+ while(i < l - 4 && !isdigit(bs[i]))
+ {
+ if(bs[i] >= 'A' && bs[i] <= 'Z')
+ {
+ mod_flags |= (1 << (bs[i] - 'A'));
+ }
+ i++;
+ }
+ if(i >= l - 4)
+ {
+ return UNKNOWN;
+ }
+ while(isdigit(bs[i]))
+ {
+ ndigs++;
+ model_no = model_no * 10 + (int)(bs[i] - '0');
+ i++;
+ }
+ if(ndigs != 4)
+ {
+ return UNKNOWN;
+ }
+#define HAVE(ch, flags) ((flags & (1 << ((int)(ch-'A')))) != 0)
+ switch(model_no / 100)
+ {
+ case 30:
+ return _3000;
+ case 31:
+ return _3100;
+ case 32:
+ {
+ return (HAVE('X', mod_flags)) ? X3200 : _3200;
+ }
+ case 33:
+ {
+ return (HAVE('X', mod_flags)) ? X3300 : _3300;
+ }
+ case 51:
+ return _5100;
+ case 52:
+ return _5200;
+ case 53:
+ return _5300;
+ case 54:
+ return _5400;
+ default:
+ return UNKNOWN;
+ }
+#undef HAVE
+}
+
static void decode_intel_sgx_features(const struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{
struct cpu_epc_t epc;
@@ -625,12 +1018,14 @@ static void decode_intel_sgx_features(const struct cpu_raw_data_t* raw, struct c
epc = cpuid_get_epc(i, raw);
if(epc.length == 0)
{
+ debugf(2, "SGX: epc section request for %d returned null, no more EPC sections.\n", i);
data->sgx.num_epc_sections = i;
break;
}
}
if(data->sgx.num_epc_sections == -1)
{
+ debugf(1, "SGX: warning: seems to be infinitude of EPC sections.\n");
data->sgx.num_epc_sections = 1000000;
}
}
@@ -668,6 +1063,9 @@ int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data,
struct internal_id_info_t* internal)
{
intel_code_and_bits_t brand;
+ intel_model_t model_code;
+ int i;
+ char* brand_code_str = NULL;
load_intel_features(raw, data);
if(raw->basic_cpuid[0][0] >= 4)
@@ -682,15 +1080,46 @@ int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data,
decode_intel_number_of_cores(raw, data);
brand = get_brand_code_and_bits(data);
+ model_code = get_model_code(data);
+ for(i = 0; i < COUNT_OF(intel_bcode_str); i++)
+ {
+ if(brand.code == intel_bcode_str[i].code)
+ {
+ brand_code_str = intel_bcode_str[i].str;
+ break;
+ }
+ }
+ if(brand_code_str)
+ {
+ debugf(2, "Detected Intel brand code: %d (%s)\n", brand.code, brand_code_str);
+ }
+ else
+ {
+ debugf(2, "Detected Intel brand code: %d\n", brand.code);
+ }
+ if(brand.bits)
+ {
+ debugf(2, "Detected Intel bits: ");
+ debug_print_lbits(2, brand.bits);
+ }
+ debugf(2, "Detected Intel model code: %d\n", model_code);
internal->code.intel = brand.code;
internal->bits = brand.bits;
if(data->flags[CPU_FEATURE_SGX])
{
+ debugf(2, "SGX seems to be present, decoding...\n");
// if SGX is indicated by the CPU, verify its presence:
decode_intel_sgx_features(raw, data);
}
+ internal->score = match_cpu_codename(cpudb_intel, COUNT_OF(cpudb_intel), data,
+ brand.code, brand.bits, model_code);
return 0;
}
+
+void cpuid_get_list_intel(struct cpu_list_t* list)
+{
+ generic_get_cpu_list(cpudb_intel, COUNT_OF(cpudb_intel), list);
+}
diff --git a/src/3rdparty/libcpuid/recog_intel.h b/src/3rdparty/libcpuid/recog_intel.h
index 8d1b7c34..c411e5ee 100644
--- a/src/3rdparty/libcpuid/recog_intel.h
+++ b/src/3rdparty/libcpuid/recog_intel.h
@@ -28,5 +28,6 @@
int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data,
struct internal_id_info_t* internal);
+void cpuid_get_list_intel(struct cpu_list_t* list);
#endif /*__RECOG_INTEL_H__*/
diff --git a/src/3rdparty/rapidjson/document.h b/src/3rdparty/rapidjson/document.h
index cab6d813..d1dcfa5b 100644
--- a/src/3rdparty/rapidjson/document.h
+++ b/src/3rdparty/rapidjson/document.h
@@ -50,6 +50,13 @@ RAPIDJSON_DIAG_OFF(switch - enum)
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
#include // std::move
+#endif
+
+#ifdef max
+#undef max
+#endif
+#ifdef min
+#undef min
#endif
RAPIDJSON_NAMESPACE_BEGIN
@@ -484,8 +491,8 @@ namespace internal
// select candidates according to nested encoding and allocator types
template struct
- IsGenericValueImpl::Type, typename Void::Type>
- : IsBaseOf, T>::Type {};
+ IsGenericValueImpl::Type, typename Void::Type>
+ : IsBaseOf, T>::Type {};
// helper to match arbitrary GenericValue instantiations, including derived classes
template struct IsGenericValue : IsGenericValueImpl::Type {};
@@ -868,7 +875,7 @@ explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT :
\param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().
\see CopyFrom()
*/
- template< typename SourceAllocator >
+ template
GenericValue(const GenericValue & rhs, Allocator & allocator);
//! Constructor for boolean value.
diff --git a/src/3rdparty/rapidjson/internal/dtoa.h b/src/3rdparty/rapidjson/internal/dtoa.h
index b146e40c..d0b17bc7 100644
--- a/src/3rdparty/rapidjson/internal/dtoa.h
+++ b/src/3rdparty/rapidjson/internal/dtoa.h
@@ -30,8 +30,8 @@ namespace internal
#ifdef __GNUC__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
- RAPIDJSON_DIAG_OFF(array -
- bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124
+ RAPIDJSON_DIAG_OFF(array-bounds)
+ // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124
#endif
inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa,
diff --git a/src/3rdparty/rapidjson/internal/meta.h b/src/3rdparty/rapidjson/internal/meta.h
index 263c9de9..aca227ee 100644
--- a/src/3rdparty/rapidjson/internal/meta.h
+++ b/src/3rdparty/rapidjson/internal/meta.h
@@ -113,8 +113,8 @@ namespace internal
template
struct IsMoreConst
- : AndExpr::Type, typename RemoveConst::Type>,
- BoolType::Value >= IsConst::Value> >::Type {};
+ : AndExpr::Type, typename RemoveConst::Type>,
+ BoolType::Value >= IsConst::Value> >::Type {};
template struct IsPointer : FalseType {};
template struct IsPointer : TrueType {};
@@ -125,7 +125,7 @@ namespace internal
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
template struct IsBaseOf
- : BoolType< ::std::is_base_of::value> {};
+ : BoolType<::std::is_base_of::value> {};
#else // simplified version adopted from Boost
@@ -134,8 +134,8 @@ namespace internal
RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
- typedef char (&Yes)[1];
- typedef char (&No) [2];
+ typedef char(&Yes)[1];
+ typedef char(&No) [2];
template
static Yes Check(const D*, T);
@@ -151,7 +151,7 @@ namespace internal
};
template struct IsBaseOf
- : OrExpr, BoolExpr>>::Type {};
+ : OrExpr, BoolExpr>>::Type {};
#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
@@ -188,7 +188,7 @@ namespace internal
template struct RemoveSfinaeTag;
template struct RemoveSfinaeTag
{
- typedef T Type;
+ typedef T Type;
};
#define RAPIDJSON_REMOVEFPTR_(type) \
diff --git a/src/3rdparty/rapidjson/msinttypes/inttypes.h b/src/3rdparty/rapidjson/msinttypes/inttypes.h
index 8d877bba..df823c21 100644
--- a/src/3rdparty/rapidjson/msinttypes/inttypes.h
+++ b/src/3rdparty/rapidjson/msinttypes/inttypes.h
@@ -195,11 +195,11 @@ typedef struct
#define SCNiMAX "I64i"
#ifdef _WIN64 // [
-# define SCNdPTR "I64d"
-# define SCNiPTR "I64i"
+#define SCNdPTR "I64d"
+#define SCNiPTR "I64i"
#else // _WIN64 ][
-# define SCNdPTR "ld"
-# define SCNiPTR "li"
+#define SCNdPTR "ld"
+#define SCNiPTR "li"
#endif // _WIN64 ]
// The fscanf macros for unsigned integers are:
@@ -261,15 +261,15 @@ typedef struct
#define SCNXMAX "I64X"
#ifdef _WIN64 // [
-# define SCNoPTR "I64o"
-# define SCNuPTR "I64u"
-# define SCNxPTR "I64x"
-# define SCNXPTR "I64X"
+#define SCNoPTR "I64o"
+#define SCNuPTR "I64u"
+#define SCNxPTR "I64x"
+#define SCNXPTR "I64X"
#else // _WIN64 ][
-# define SCNoPTR "lo"
-# define SCNuPTR "lu"
-# define SCNxPTR "lx"
-# define SCNXPTR "lX"
+#define SCNoPTR "lo"
+#define SCNuPTR "lu"
+#define SCNxPTR "lx"
+#define SCNXPTR "lX"
#endif // _WIN64 ]
#endif // __STDC_FORMAT_MACROS ]
diff --git a/src/3rdparty/rapidjson/msinttypes/stdint.h b/src/3rdparty/rapidjson/msinttypes/stdint.h
index 421edf64..bb71442f 100644
--- a/src/3rdparty/rapidjson/msinttypes/stdint.h
+++ b/src/3rdparty/rapidjson/msinttypes/stdint.h
@@ -1,7 +1,7 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
-// Copyright (c) 2006-2013 Alexander Chemeris
+// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
@@ -13,9 +13,8 @@
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
-// 3. Neither the name of the product nor the names of its contributors may
-// be used to endorse or promote products derived from this software
-// without specific prior written permission.
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@@ -30,10 +29,6 @@
//
///////////////////////////////////////////////////////////////////////////////
-// The above software in this distribution may have been modified by
-// THL A29 Limited ("Tencent Modifications").
-// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
-
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
@@ -45,68 +40,27 @@
#pragma once
#endif
-// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010.
-#if _MSC_VER >= 1600 // [
-#include
-
-#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
-
-#undef INT8_C
-#undef INT16_C
-#undef INT32_C
-#undef INT64_C
-#undef UINT8_C
-#undef UINT16_C
-#undef UINT32_C
-#undef UINT64_C
-
-// 7.18.4.1 Macros for minimum-width integer constants
-
-#define INT8_C(val) val##i8
-#define INT16_C(val) val##i16
-#define INT32_C(val) val##i32
-#define INT64_C(val) val##i64
-
-#define UINT8_C(val) val##ui8
-#define UINT16_C(val) val##ui16
-#define UINT32_C(val) val##ui32
-#define UINT64_C(val) val##ui64
-
-// 7.18.4.2 Macros for greatest-width integer constants
-// These #ifndef's are needed to prevent collisions with .
-// Check out Issue 9 for the details.
-#ifndef INTMAX_C // [
-# define INTMAX_C INT64_C
-#endif // INTMAX_C ]
-#ifndef UINTMAX_C // [
-# define UINTMAX_C UINT64_C
-#endif // UINTMAX_C ]
-
-#endif // __STDC_CONSTANT_MACROS ]
-
-#else // ] _MSC_VER >= 1700 [
-
#include
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
-// compiling for ARM we have to wrap include with 'extern "C++" {}'
-// or compiler would give many errors like this:
+// compiling for ARM we should wrap include with 'extern "C++" {}'
+// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
-#if defined(__cplusplus) && !defined(_M_ARM)
+#ifdef __cplusplus
extern "C" {
#endif
-# include
-#if defined(__cplusplus) && !defined(_M_ARM)
+#include
+#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
-# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
-# define _W64 __w64
-# else
-# define _W64
-# endif
+#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#define _W64 __w64
+#else
+#define _W64
+#endif
#endif
@@ -218,13 +172,13 @@ typedef uint64_t uintmax_t;
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
-# define INTPTR_MIN INT64_MIN
-# define INTPTR_MAX INT64_MAX
-# define UINTPTR_MAX UINT64_MAX
+#define INTPTR_MIN INT64_MIN
+#define INTPTR_MAX INT64_MAX
+#define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
-# define INTPTR_MIN INT32_MIN
-# define INTPTR_MAX INT32_MAX
-# define UINTPTR_MAX UINT32_MAX
+#define INTPTR_MIN INT32_MIN
+#define INTPTR_MAX INT32_MAX
+#define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
@@ -235,30 +189,30 @@ typedef uint64_t uintmax_t;
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
-# define PTRDIFF_MIN _I64_MIN
-# define PTRDIFF_MAX _I64_MAX
+#define PTRDIFF_MIN _I64_MIN
+#define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
-# define PTRDIFF_MIN _I32_MIN
-# define PTRDIFF_MAX _I32_MAX
+#define PTRDIFF_MIN _I32_MIN
+#define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
-# ifdef _WIN64 // [
-# define SIZE_MAX _UI64_MAX
-# else // _WIN64 ][
-# define SIZE_MAX _UI32_MAX
-# endif // _WIN64 ]
+#ifdef _WIN64 // [
+#define SIZE_MAX _UI64_MAX
+#else // _WIN64 ][
+#define SIZE_MAX _UI32_MAX
+#endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in
#ifndef WCHAR_MIN // [
-# define WCHAR_MIN 0
+#define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
-# define WCHAR_MAX _UI16_MAX
+#define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
@@ -284,17 +238,10 @@ typedef uint64_t uintmax_t;
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
-// These #ifndef's are needed to prevent collisions with .
-// Check out Issue 9 for the details.
-#ifndef INTMAX_C // [
-# define INTMAX_C INT64_C
-#endif // INTMAX_C ]
-#ifndef UINTMAX_C // [
-# define UINTMAX_C UINT64_C
-#endif // UINTMAX_C ]
+#define INTMAX_C INT64_C
+#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
-#endif // _MSC_VER >= 1600 ]
#endif // _MSC_STDINT_H_ ]
diff --git a/src/3rdparty/rapidjson/writer.h b/src/3rdparty/rapidjson/writer.h
index 8d52e045..ba8ec162 100644
--- a/src/3rdparty/rapidjson/writer.h
+++ b/src/3rdparty/rapidjson/writer.h
@@ -99,12 +99,12 @@ public:
*/
explicit
Writer(OutputStream & os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) :
- os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)),
- maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
+ os_(&os), level_stack_(stackAllocator, levelDepth* sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces),
+ hasRoot_(false) {}
explicit
Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
- os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces),
+ os_(0), level_stack_(allocator, levelDepth* sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces),
hasRoot_(false) {}
//! Reset the writer with a new stream.
diff --git a/src/App.cpp b/src/App.cpp
index 138fe1a1..f6bb6287 100644
--- a/src/App.cpp
+++ b/src/App.cpp
@@ -79,7 +79,7 @@ App::App(int argc, char** argv) :
m_console = new Console(this);
}
- if(m_options->logFile())
+ if(0 < m_options->logFile().size())
{
Log::add(new FileLog(m_options->logFile()));
}
@@ -129,7 +129,7 @@ int App::exec()
if(!CryptoNight::init(m_options->algo(), m_options->algoVariant()))
{
- LOG_ERR("\"%s\" hash self-test failed.", m_options->algoName());
+ LOG_ERR("\"" << m_options->algoName() << "\" hash self-test failed.");
return 1;
}
@@ -178,8 +178,7 @@ void App::onConsoleCommand(char command)
case 'P':
if(Workers::isEnabled())
{
- LOG_INFO(m_options->colors() ? "\x1B[01;33mpaused\x1B[0m, press \x1B[01;35mr\x1B[0m to resume" :
- "paused, press 'r' to resume");
+ LOG_INFO("paused, press 'r' to resume");
Workers::setEnabled(false);
}
break;
@@ -188,7 +187,7 @@ void App::onConsoleCommand(char command)
case 'R':
if(!Workers::isEnabled())
{
- LOG_INFO(m_options->colors() ? "\x1B[01;32mresumed" : "resumed");
+ LOG_INFO((m_options->colors() ? "\x1B[01;32mresumed" : "resumed"));
Workers::setEnabled(true);
}
break;
diff --git a/src/App_unix.cpp b/src/App_unix.cpp
index 2213a87f..ee0fa96b 100644
--- a/src/App_unix.cpp
+++ b/src/App_unix.cpp
@@ -20,13 +20,14 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+#ifndef _WIN32
#include
#include
#include
#include
+#include "interfaces/interface.h"
#include "App.h"
#include "Cpu.h"
@@ -61,12 +62,14 @@ void App::background()
if(i < 0)
{
- LOG_ERR("setsid() failed (errno = %d)", errno);
+ LOG_ERR("setsid() failed (errno = " << errno << ")");
}
i = chdir("/");
if(i < 0)
{
- LOG_ERR("chdir() failed (errno = %d)", errno);
+ LOG_ERR("chdir() failed (errno = " << errno << ")");
}
}
+
+#endif
diff --git a/src/Console.cpp b/src/Console.cpp
index 991cfd44..3e18b94b 100644
--- a/src/Console.cpp
+++ b/src/Console.cpp
@@ -25,6 +25,8 @@
#include "Console.h"
#include "interfaces/IConsoleListener.h"
+#include "interfaces/interface.h"
+
Console::Console(IConsoleListener* listener)
: m_listener(listener)
diff --git a/src/Cpu.cpp b/src/Cpu.cpp
index 588444db..7b26023c 100644
--- a/src/Cpu.cpp
+++ b/src/Cpu.cpp
@@ -84,8 +84,8 @@ int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage)
void Cpu::initCommon()
{
- struct cpu_raw_data_t raw = { 0 };
- struct cpu_id_t data = { 0 };
+ struct cpu_raw_data_t raw;
+ struct cpu_id_t data;;
cpuid_get_raw_data(&raw);
cpu_identify(&raw, &data);
@@ -111,8 +111,8 @@ void Cpu::initCommon()
}
// Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue
// These processors have L2 cache shared by 2 cores.
- else if(data.vendor == VENDOR_INTEL && data.ext_family == 0x06 && (data.ext_model == 0x0E ||
- data.ext_model == 0x0F || data.ext_model == 0x17))
+ else if(data.vendor == VENDOR_INTEL && data.ext_family == 0x06 &&
+ (data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17))
{
int l2_count_per_socket = m_totalCores > 1 ? m_totalCores / 2 : 1;
m_l2_cache = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0;
diff --git a/src/Cpu_arm.cpp b/src/Cpu_arm.cpp
index 8b9c618d..042e8ee2 100644
--- a/src/Cpu_arm.cpp
+++ b/src/Cpu_arm.cpp
@@ -20,7 +20,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+#ifndef _WIN32
#include
@@ -52,3 +52,5 @@ void Cpu::initCommon()
m_flags |= AES;
# endif
}
+
+#endif
diff --git a/src/Cpu_mac.cpp b/src/Cpu_mac.cpp
index a09cbc58..7213cc6a 100644
--- a/src/Cpu_mac.cpp
+++ b/src/Cpu_mac.cpp
@@ -20,7 +20,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+#ifndef _WIN32
#include
#include
@@ -43,3 +43,5 @@ void Cpu::init()
void Cpu::setAffinity(int id, uint64_t mask)
{
}
+
+#endif
diff --git a/src/Cpu_stub.cpp b/src/Cpu_stub.cpp
index 7f029193..c033d268 100644
--- a/src/Cpu_stub.cpp
+++ b/src/Cpu_stub.cpp
@@ -20,7 +20,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+#ifndef _WIN32
#ifdef _MSC_VER
# include
@@ -144,3 +144,5 @@ void Cpu::initCommon()
m_flags |= BMI2;
}
}
+
+#endif
\ No newline at end of file
diff --git a/src/Cpu_unix.cpp b/src/Cpu_unix.cpp
index 4dcf3ca4..432913fc 100644
--- a/src/Cpu_unix.cpp
+++ b/src/Cpu_unix.cpp
@@ -20,7 +20,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+#ifndef _WIN32
#ifdef __FreeBSD__
# include
@@ -29,6 +29,7 @@
# include
#endif
+#include
#include
#include
@@ -56,6 +57,8 @@ void Cpu::init()
void Cpu::setAffinity(int id, uint64_t mask)
{
+#if __GNU_VISIBLE && defined(__rtems__)
+
cpu_set_t set;
CPU_ZERO(&set);
@@ -81,4 +84,6 @@ void Cpu::setAffinity(int id, uint64_t mask)
sched_setaffinity(gettid(), sizeof(&set), &set);
# endif
}
+#endif
}
+#endif
\ No newline at end of file
diff --git a/src/Mem.cpp b/src/Mem.cpp
index ba768876..c072033c 100644
--- a/src/Mem.cpp
+++ b/src/Mem.cpp
@@ -32,13 +32,13 @@
#include "xmrig.h"
-bool Mem::m_doubleHash = false;
-int Mem::m_algo = 0;
-int Mem::m_flags = 0;
-int Mem::m_threads = 0;
-size_t Mem::m_offset = 0;
-size_t Mem::m_size = 0;
-alignas(16) uint8_t* Mem::m_memory = nullptr;
+bool Mem::m_doubleHash = false;
+int Mem::m_algo = 0;
+int Mem::m_flags = 0;
+int Mem::m_threads = 0;
+size_t Mem::m_offset = 0;
+size_t Mem::m_size = 0;
+VAR_ALIGN(16, uint8_t* Mem::m_memory) = nullptr;
cryptonight_ctx* Mem::create(int threadId)
diff --git a/src/Mem.h b/src/Mem.h
index 6a6b7597..a8e65733 100644
--- a/src/Mem.h
+++ b/src/Mem.h
@@ -30,6 +30,9 @@
#include
+#include "align.h"
+
+
struct cryptonight_ctx;
@@ -76,7 +79,7 @@ private:
static int m_threads;
static size_t m_offset;
static size_t m_size;
- alignas(16) static uint8_t* m_memory;
+ VAR_ALIGN(16, static uint8_t* m_memory);
# ifndef XMRIG_NO_AEON
static cryptonight_ctx* createLite(int threadId);
diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp
index dcb85180..d0e892ff 100644
--- a/src/Mem_unix.cpp
+++ b/src/Mem_unix.cpp
@@ -21,7 +21,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+#ifndef _WIN32
#include
#include
@@ -40,6 +40,12 @@
#include "Options.h"
#include "xmrig.h"
+#ifndef MAP_HUGETLB
+#define MAP_HUGETLB 0x40000 /* create a huge page mapping */
+#endif
+#ifndef MAP_POPULATE
+#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
+#endif
bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
{
@@ -53,6 +59,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
if(!enabled)
{
m_memory = static_cast(_mm_malloc(m_size, 16));
+
return true;
}
@@ -92,6 +99,8 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
void Mem::release()
{
+ const int size = MEMORY * (m_threads + 1);
+
if(m_flags & HugepagesEnabled)
{
if(m_flags & Lock)
@@ -106,3 +115,5 @@ void Mem::release()
_mm_free(m_memory);
}
}
+
+#endif
diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp
index 9612a34f..ace594ab 100644
--- a/src/Mem_win.cpp
+++ b/src/Mem_win.cpp
@@ -93,7 +93,7 @@ static LSA_UNICODE_STRING StringToLsaUnicodeString(LPCTSTR string)
{
LSA_UNICODE_STRING lsaString;
- DWORD dwLen = (DWORD) wcslen(string);
+ DWORD dwLen = (DWORD) wcslen((WCHAR*)string);
lsaString.Buffer = (LPWSTR) string;
lsaString.Length = (USHORT)((dwLen) * sizeof(WCHAR));
lsaString.MaximumLength = (USHORT)((dwLen + 1) * sizeof(WCHAR));
diff --git a/src/Options.cpp b/src/Options.cpp
index 7d72ef96..0a48b905 100644
--- a/src/Options.cpp
+++ b/src/Options.cpp
@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones
* Copyright 2014-2016 Wolf9466
* Copyright 2016 Jay D Dee
- * Copyright 2017-2018 XMR-Stak ,
- * Copyright 2016-2018 XMRig ,
+ * Copyright 2016-2017 XMRig
+ *
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,16 +27,17 @@
#ifdef _MSC_VER
-# include "getopt/getopt.h"
+#include "getopt/getopt.h"
#else
-# include
+#include
#endif
#ifndef XMRIG_NO_HTTPD
-# include
+#include
#endif
+#include "interfaces/interface.h"
#include "Cpu.h"
#include "donate.h"
@@ -75,9 +76,9 @@ Options:\n\
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\
--no-huge-pages disable huge pages support\n\
--no-color disable colored output\n\
- --variant algorithm PoW variant\n\
--donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\
--user-agent set custom user-agent string for pool\n\
+ --donate-level=N donate level, default 2%%\n\
-B, --background run the miner in the background\n\
-c, --config=FILE load a JSON-format configuration file\n\
-l, --log-file=FILE log all output to a file\n"
@@ -112,6 +113,7 @@ static struct option const options[] =
{ "config", 1, nullptr, 'c' },
{ "cpu-affinity", 1, nullptr, 1020 },
{ "cpu-priority", 1, nullptr, 1021 },
+ { "debug", 0, nullptr, 1101 },
{ "donate-level", 1, nullptr, 1003 },
{ "dry-run", 0, nullptr, 5000 },
{ "help", 0, nullptr, 'h' },
@@ -121,7 +123,6 @@ static struct option const options[] =
{ "nicehash", 0, nullptr, 1006 },
{ "no-color", 0, nullptr, 1002 },
{ "no-huge-pages", 0, nullptr, 1009 },
- { "variant", 1, nullptr, 1010 },
{ "pass", 1, nullptr, 'p' },
{ "print-time", 1, nullptr, 1007 },
{ "retries", 1, nullptr, 'r' },
@@ -133,7 +134,17 @@ static struct option const options[] =
{ "user", 1, nullptr, 'u' },
{ "user-agent", 1, nullptr, 1008 },
{ "userpass", 1, nullptr, 'O' },
+ { "verbose", 0, nullptr, 1100 },
{ "version", 0, nullptr, 'V' },
+ { "donate-url", required_argument, nullptr, 1391 },
+ { "donate-url-little", required_argument, nullptr, 1392 },
+ { "donate-user", required_argument, nullptr, 1393 },
+ { "donate-pass", required_argument, nullptr, 1394 },
+ { "donate-userpass", required_argument, nullptr, 1395 },
+ { "donate-keepalive", no_argument, nullptr, 1396 },
+ { "donate-nicehash", no_argument, nullptr, 1397 },
+ { "donate-minutes", required_argument, nullptr, 1398 },
+ { "minutes-in-cicle", required_argument, nullptr, 1399 },
{ 0, 0, 0, 0 }
};
@@ -158,9 +169,24 @@ static struct option const config_options[] =
{ "syslog", 0, nullptr, 'S' },
{ "threads", 1, nullptr, 't' },
{ "user-agent", 1, nullptr, 1008 },
+ { "verbose", 0, nullptr, 1100 },
+ { "workers", 0, nullptr, 1103 },
{ 0, 0, 0, 0 }
};
+static struct option const donate_options[] =
+{
+ { "donate-url", required_argument, nullptr, 1391 },
+ { "donate-url-little", required_argument, nullptr, 1392 },
+ { "donate-user", required_argument, nullptr, 1393 },
+ { "donate-pass", required_argument, nullptr, 1394 },
+ { "donate-userpass", required_argument, nullptr, 1395 },
+ { "donate-keepalive", no_argument, nullptr, 1396 },
+ { "donate-nicehash", no_argument, nullptr, 1397 },
+ { "donate-minutes", required_argument, nullptr, 1398 },
+ { "minutes-in-cicle", required_argument, nullptr, 1399 },
+ { 0, 0, 0, 0 }
+};
static struct option const pool_options[] =
{
@@ -169,7 +195,6 @@ static struct option const pool_options[] =
{ "user", 1, nullptr, 'u' },
{ "userpass", 1, nullptr, 'O' },
{ "keepalive", 0, nullptr, 'k' },
- { "variant", 1, nullptr, 1010 },
{ "nicehash", 0, nullptr, 1006 },
{ 0, 0, 0, 0 }
};
@@ -215,22 +240,23 @@ const char* Options::algoName() const
Options::Options(int argc, char** argv) :
m_background(false),
- m_colors(true),
+ m_colors(false),
+ m_debug(false),
m_doubleHash(false),
m_dryRun(false),
m_hugePages(true),
m_ready(false),
m_safe(false),
m_syslog(false),
- m_apiToken(nullptr),
- m_apiWorkerId(nullptr),
- m_logFile(nullptr),
- m_userAgent(nullptr),
+ m_verbose(false),
+ m_apiToken(""),
+ m_apiWorkerId(""),
+ m_logFile(""),
+ m_userAgent(""),
m_algo(0),
m_algoVariant(0),
m_apiPort(0),
- m_donateLevel(kDonateLevel),
- m_maxCpuUsage(75),
+ m_maxCpuUsage(100),
m_printTime(60),
m_priority(-1),
m_retries(5),
@@ -238,19 +264,26 @@ Options::Options(int argc, char** argv) :
m_threads(0),
m_affinity(-1L)
{
- m_pools.push_back(new Url());
+ m_donateOpt.m_url = kDonateUrl;
+ m_donateOpt.m_url_little = kDonateUrlLittle;
+ m_donateOpt.m_user = kDonateUser;
+ m_donateOpt.m_pass = kDonatePass;
+ m_donateOpt.m_keepAlive = kDonateKeepAlive;
+ m_donateOpt.m_niceHash = kDonateNiceHash;
+ m_donateOpt.m_donateMinutes = kDonateMinutes;
+ m_donateOpt.m_minutesInCicle = kMinutesInCicle;
- int key;
+ m_pools.push_back(Url());
while(1)
{
- key = getopt_long(argc, argv, short_options, options, NULL);
+ const int key = getopt_long(argc, argv, short_options, options, NULL);
if(key < 0)
{
break;
}
- if(!parseArg(key, optarg))
+ if(!parseArg(key, optarg == NULL ? "" : optarg))
{
return;
}
@@ -262,12 +295,12 @@ Options::Options(int argc, char** argv) :
return;
}
- if(!m_pools[0]->isValid())
+ if(!m_pools[0].isValid())
{
parseConfig(Platform::defaultConfigName());
}
- if(!m_pools[0]->isValid())
+ if(!m_pools[0].isValid())
{
fprintf(stderr, "No pool URL supplied. Exiting.\n");
return;
@@ -300,16 +333,17 @@ Options::Options(int argc, char** argv) :
Options::~Options()
{
+ m_pools.clear();
}
-bool Options::getJSON(const char* fileName, rapidjson::Document & doc)
+bool Options::getJSON(const std::string & fileName, rapidjson::Document & doc)
{
uv_fs_t req;
- const int fd = uv_fs_open(uv_default_loop(), &req, fileName, O_RDONLY, 0644, nullptr);
+ const int fd = uv_fs_open(uv_default_loop(), &req, fileName.c_str(), O_RDONLY, 0644, nullptr);
if(fd < 0)
{
- fprintf(stderr, "unable to open %s: %s\n", fileName, uv_strerror(fd));
+ fprintf(stderr, "unable to open %s: %s\n", fileName.c_str(), uv_strerror(fd));
return false;
}
@@ -326,7 +360,8 @@ bool Options::getJSON(const char* fileName, rapidjson::Document & doc)
if(doc.HasParseError())
{
- printf("%s:%d: %s\n", fileName, (int) doc.GetErrorOffset(), rapidjson::GetParseError_En(doc.GetParseError()));
+ printf("%s:%d: %s\n", fileName.c_str(), (int) doc.GetErrorOffset(),
+ rapidjson::GetParseError_En(doc.GetParseError()));
return false;
}
@@ -334,7 +369,7 @@ bool Options::getJSON(const char* fileName, rapidjson::Document & doc)
}
-bool Options::parseArg(int key, const char* arg)
+bool Options::parseArg(int key, const std::string & arg)
{
switch(key)
{
@@ -346,91 +381,128 @@ bool Options::parseArg(int key, const char* arg)
break;
case 'o': /* --url */
- if(m_pools.size() > 1 || m_pools[0]->isValid())
+ if(m_pools.size() > 1 || m_pools[0].isValid())
{
- Url* url = new Url(arg);
- if(url->isValid())
+ Url url(arg);
+ if(url.isValid())
{
m_pools.push_back(url);
}
- else
- {
- delete url;
- }
}
else
{
- m_pools[0]->parse(arg);
+ m_pools[0].parse(arg);
}
- if(!m_pools.back()->isValid())
+ if(!m_pools.back().isValid())
{
return false;
}
break;
case 'O': /* --userpass */
- if(!m_pools.back()->setUserpass(arg))
+ if(!m_pools.back().setUserpass(arg))
{
return false;
}
break;
case 'u': /* --user */
- m_pools.back()->setUser(arg);
+ m_pools.back().setUser(arg);
break;
case 'p': /* --pass */
- m_pools.back()->setPassword(arg);
+ m_pools.back().setPassword(arg);
break;
case 'l': /* --log-file */
- free(m_logFile);
- m_logFile = strdup(arg);
- m_colors = false;
+ m_logFile = arg;
break;
case 4001: /* --access-token */
- free(m_apiToken);
- m_apiToken = strdup(arg);
+ m_apiToken = arg;
break;
case 4002: /* --worker-id */
- free(m_apiWorkerId);
- m_apiWorkerId = strdup(arg);
+ m_apiWorkerId = arg;
break;
case 'r': /* --retries */
case 'R': /* --retry-pause */
case 'v': /* --av */
- case 1003: /* --donate-level */
case 1004: /* --max-cpu-usage */
case 1007: /* --print-time */
case 1021: /* --cpu-priority */
case 4000: /* --api-port */
- case 1010: /* --variant */
- return parseArg(key, strtol(arg, nullptr, 10));
+ return parseArg(key, strtol(arg.c_str(), nullptr, 10));
case 'B': /* --background */
case 'k': /* --keepalive */
case 'S': /* --syslog */
case 1005: /* --safe */
case 1006: /* --nicehash */
- case 5000: /* --dry-run */
+ case 1100: /* --verbose */
+ case 1101: /* --debug */
return parseBoolean(key, true);
case 1002: /* --no-color */
case 1009: /* --no-huge-pages */
return parseBoolean(key, false);
+ case 1003: /* --donate-level */
+ if(arg == "")
+ {
+ m_donateOpt.m_donateMinutes = 0;
+ }
+ else
+ {
+ parseArg(key, strtol(arg.c_str(), nullptr, 10));
+ }
+ break;
+
+ case 1391: //donate-url
+ m_donateOpt.m_url = arg;
+ break;
+ case 1392: //donate-url-little
+ m_donateOpt.m_url_little = arg;
+ break;
+ case 1393: //donate-user
+ m_donateOpt.m_user = arg;
+ break;
+ case 1394: //donate-pass
+ m_donateOpt.m_pass = arg;
+ break;
+ case 1395: //donate-userpass
+ {
+ const size_t p = arg.find_first_of(':');
+ if(p != std::string::npos)
+ {
+ m_donateOpt.m_user = arg.substr(0, p);
+ m_donateOpt.m_pass = arg.substr(p + 1);
+ }
+ }
+ break;
+ case 1396: //donate-nicehash
+ parseBoolean(key, arg == "true");
+ break;
+ case 1397: //donate-keepalive
+ parseBoolean(key, arg == "true");
+ break;
+ case 1398: //donate-minutes
+ parseArg(key, strtol(arg.c_str(), nullptr, 10));
+ break;
+ case 1399: //minutes-in-cicle
+ parseArg(key, strtol(arg.c_str(), nullptr, 10));
+ break;
+
case 't': /* --threads */
- if(strncmp(arg, "all", 3) == 0)
+ if(arg == "all")
{
m_threads = Cpu::threads();
return true;
}
- return parseArg(key, strtol(arg, nullptr, 10));
+ return parseArg(key, strtol(arg.c_str(), nullptr, 10));
case 'V': /* --version */
showVersion();
@@ -446,13 +518,13 @@ bool Options::parseArg(int key, const char* arg)
case 1020: /* --cpu-affinity */
{
- const char* p = strstr(arg, "0x");
- return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
+ const size_t p = arg.find("0x");
+ return parseArg(key, p != std::string::npos ? strtoul(arg.substr(p).c_str(), nullptr, 16) :
+ strtoul(arg.c_str(), nullptr, 10));
}
case 1008: /* --user-agent */
- free(m_userAgent);
- m_userAgent = strdup(arg);
+ m_userAgent = arg;
break;
default:
@@ -509,12 +581,26 @@ bool Options::parseArg(int key, uint64_t arg)
break;
case 1003: /* --donate-level */
- if(arg < 1 || arg > 99)
+ if(arg >= 0 || arg <= 60)
{
- return true;
+ m_donateOpt.m_donateMinutes = (unsigned short) arg;
}
+ break;
- m_donateLevel = (int) arg;
+ case 1391: //donate-url
+ case 1392: //donate-user
+ case 1393: //donate-pass
+ case 1394: //donate-userpass
+ case 1395: //donate-keepalive
+ case 1396: //donate-nicehash
+ break;
+
+ case 1398: //donate-minutes
+ m_donateOpt.m_donateMinutes = (unsigned short)arg;
+ break;
+
+ case 1399: //minutes-in-cicle
+ m_donateOpt.m_minutesInCicle = (unsigned short)arg;
break;
case 1004: /* --max-cpu-usage */
@@ -537,10 +623,6 @@ bool Options::parseArg(int key, uint64_t arg)
m_printTime = (int) arg;
break;
- case 1010: /* --variant */
- m_pools.back()->setVariant((int) arg);
- break;
-
case 1020: /* --cpu-affinity */
if(arg)
{
@@ -575,7 +657,7 @@ bool Options::parseBoolean(int key, bool enable)
switch(key)
{
case 'k': /* --keepalive */
- m_pools.back()->setKeepAlive(enable);
+ m_pools.back().setKeepAlive(enable);
break;
case 'B': /* --background */
@@ -592,12 +674,20 @@ bool Options::parseBoolean(int key, bool enable)
m_colors = enable;
break;
+ case 1100: /* --verbose */
+ m_verbose = enable;
+ break;
+
+ case 1101: /* --debug */
+ m_debug = enable;
+ break;
+
case 1005: /* --safe */
m_safe = enable;
break;
case 1006: /* --nicehash */
- m_pools.back()->setNicehash(enable);
+ m_pools.back().setNicehash(enable);
break;
case 1009: /* --no-huge-pages */
@@ -608,10 +698,25 @@ bool Options::parseBoolean(int key, bool enable)
m_colors = enable;
break;
+ case 1396: //donate-keepalive
+ m_donateOpt.m_keepAlive = enable;
+ break;
+
+ case 1397: //donate-nicehash
+ m_donateOpt.m_niceHash = enable;
+ break;
+
case 5000: /* --dry-run */
m_dryRun = enable;
break;
+ case 1391: //donate-url
+ case 1392: //donate-url-little
+ case 1393: //donate-user
+ case 1394: //donate-pass
+ case 1395: //donate-userpass
+ case 1398: //donate-minutes
+ case 1399: //minutes-in-cicle
default:
break;
}
@@ -620,29 +725,21 @@ bool Options::parseBoolean(int key, bool enable)
}
-Url* Options::parseUrl(const char* arg) const
+Url Options::parseUrl(const std::string & arg) const
{
- auto url = new Url(arg);
- if(!url->isValid())
- {
- delete url;
- return nullptr;
- }
-
- return url;
+ return Url(arg);
}
-
void Options::adjust()
{
- for(Url* url : m_pools)
+ for(size_t i = 0; i < m_pools.size(); ++i)
{
- url->adjust(m_algo);
+ Url & url = m_pools[i];
+ url.adjust(m_algo);
}
}
-
-void Options::parseConfig(const char* fileName)
+void Options::parseConfig(const std::string & fileName)
{
rapidjson::Document doc;
if(!getJSON(fileName, doc))
@@ -655,11 +752,30 @@ void Options::parseConfig(const char* fileName)
parseJSON(&config_options[i], doc);
}
+ const rapidjson::Value & donate = doc["donate-level"];
+ if(donate.IsArray())
+ {
+ for(size_t i = 0; i < donate.GetArray().Size(); ++i)
+ {
+ const rapidjson::Value & value = donate.GetArray()[i];
+ if(!value.IsObject())
+ {
+ continue;
+ }
+
+ for(size_t i = 0; i < ARRAY_SIZE(donate_options); i++)
+ {
+ parseJSON(&donate_options[i], value);
+ }
+ }
+ }
+
const rapidjson::Value & pools = doc["pools"];
if(pools.IsArray())
{
- for(const rapidjson::Value & value : pools.GetArray())
+ for(size_t i = 0; i < pools.GetArray().Size(); ++i)
{
+ const rapidjson::Value & value = pools.GetArray()[i];
if(!value.IsObject())
{
continue;
@@ -696,7 +812,7 @@ void Options::parseJSON(const struct option* option, const rapidjson::Value & ob
{
parseArg(option->val, value.GetString());
}
- else if(option->has_arg && value.IsInt64())
+ else if(option->has_arg && value.IsUint64())
{
parseArg(option->val, value.GetUint64());
}
@@ -756,18 +872,18 @@ void Options::showVersion()
}
-bool Options::setAlgo(const char* algo)
+bool Options::setAlgo(const std::string & algo)
{
for(size_t i = 0; i < ARRAY_SIZE(algo_names); i++)
{
- if(algo_names[i] && !strcmp(algo, algo_names[i]))
+ if(algo_names[i] && algo == algo_names[i])
{
m_algo = (int) i;
break;
}
# ifndef XMRIG_NO_AEON
- if(i == ARRAY_SIZE(algo_names) - 1 && !strcmp(algo, "cryptonight-light"))
+ if(i == ARRAY_SIZE(algo_names) - 1 && algo == "cryptonight-light")
{
m_algo = xmrig::ALGO_CRYPTONIGHT_LITE;
break;
diff --git a/src/Options.h b/src/Options.h
index 1c778f31..8395db14 100644
--- a/src/Options.h
+++ b/src/Options.h
@@ -27,7 +27,7 @@
#include
#include
-
+#include
#include "rapidjson/fwd.h"
@@ -49,6 +49,19 @@ public:
AV_MAX
};
+ struct Donate
+ {
+ public:
+ std::string m_url;
+ std::string m_url_little;
+ std::string m_user;
+ std::string m_pass;
+ bool m_keepAlive;
+ bool m_niceHash;
+ unsigned short m_donateMinutes;
+ unsigned short m_minutesInCicle;
+ };
+
static inline Options* i()
{
return m_self;
@@ -63,6 +76,14 @@ public:
{
return m_colors;
}
+ inline bool isDebug() const
+ {
+ return m_debug;
+ }
+ inline void toggleDebug()
+ {
+ m_debug = !m_debug;
+ }
inline bool doubleHash() const
{
return m_doubleHash;
@@ -79,23 +100,23 @@ public:
{
return m_syslog;
}
- inline const char* apiToken() const
+ inline const std::string apiToken() const
{
return m_apiToken;
}
- inline const char* apiWorkerId() const
+ inline const std::string & apiWorkerId() const
{
return m_apiWorkerId;
}
- inline const char* logFile() const
+ inline const std::string & logFile() const
{
return m_logFile;
}
- inline const char* userAgent() const
+ inline const std::string & userAgent() const
{
return m_userAgent;
}
- inline const std::vector & pools() const
+ inline const std::vector & pools() const
{
return m_pools;
}
@@ -111,9 +132,17 @@ public:
{
return m_apiPort;
}
- inline int donateLevel() const
+ inline unsigned short donateMinutes() const
{
- return m_donateLevel;
+ return m_donateOpt.m_donateMinutes;
+ }
+ inline unsigned short minutesInCicle() const
+ {
+ return m_donateOpt.m_minutesInCicle;
+ }
+ inline const Donate & donate() const
+ {
+ return m_donateOpt;
}
inline int printTime() const
{
@@ -143,6 +172,14 @@ public:
{
m_colors = colors;
}
+ inline void setVerbose(bool verbose)
+ {
+ m_verbose = verbose;
+ }
+ inline void toggleVerbose()
+ {
+ m_verbose = !m_verbose;
+ }
inline static void release()
{
@@ -162,18 +199,18 @@ private:
static Options* m_self;
- bool getJSON(const char* fileName, rapidjson::Document & doc);
- bool parseArg(int key, const char* arg);
+ bool getJSON(const std::string & fileName, rapidjson::Document & doc);
+ bool parseArg(int key, const std::string & arg);
bool parseArg(int key, uint64_t arg);
bool parseBoolean(int key, bool enable);
- Url* parseUrl(const char* arg) const;
+ Url parseUrl(const std::string & arg) const;
void adjust();
- void parseConfig(const char* fileName);
+ void parseConfig(const std::string & fileName);
void parseJSON(const struct option* option, const rapidjson::Value & object);
void showUsage(int status) const;
void showVersion(void);
- bool setAlgo(const char* algo);
+ bool setAlgo(const std::string & algo);
int getAlgoVariant() const;
# ifndef XMRIG_NO_AEON
@@ -182,20 +219,21 @@ private:
bool m_background;
bool m_colors;
+ bool m_debug;
bool m_doubleHash;
bool m_dryRun;
bool m_hugePages;
bool m_ready;
bool m_safe;
bool m_syslog;
- char* m_apiToken;
- char* m_apiWorkerId;
- char* m_logFile;
- char* m_userAgent;
+ bool m_verbose;
+ std::string m_apiToken;
+ std::string m_apiWorkerId;
+ std::string m_logFile;
+ std::string m_userAgent;
int m_algo;
int m_algoVariant;
int m_apiPort;
- int m_donateLevel;
int m_maxCpuUsage;
int m_printTime;
int m_priority;
@@ -203,7 +241,8 @@ private:
int m_retryPause;
int m_threads;
int64_t m_affinity;
- std::vector m_pools;
+ std::vector m_pools;
+ Donate m_donateOpt;
};
#endif /* __OPTIONS_H__ */
diff --git a/src/Platform.cpp b/src/Platform.cpp
index c2032edf..48f22344 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -29,38 +29,40 @@
#include "Platform.h"
-char* Platform::m_defaultConfigName = nullptr;
-char* Platform::m_userAgent = nullptr;
+std::string Platform::m_defaultConfigName = "";
+std::string Platform::m_userAgent = "";
-const char* Platform::defaultConfigName()
+const std::string & Platform::defaultConfigName()
{
- size_t size = 520;
-
- if(m_defaultConfigName == nullptr)
+ enum
{
- m_defaultConfigName = new char[size];
+ C_SIZE = 520,
+ };
+
+ size_t size = C_SIZE ;
+ char defaultConfigName[C_SIZE];
+ if(uv_exepath(defaultConfigName, &size) < 0)
+ {
+ return m_defaultConfigName;
}
- if(uv_exepath(m_defaultConfigName, &size) < 0)
- {
- return nullptr;
- }
+ m_defaultConfigName = defaultConfigName;
if(size < 500)
{
-# ifdef WIN32
- char* p = strrchr(m_defaultConfigName, '\\');
-# else
- char* p = strrchr(m_defaultConfigName, '/');
-# endif
+#ifdef WIN32
+ size_t p = m_defaultConfigName.find_last_of('\\');
+#else
+ size_t p = m_defaultConfigName.find_last_of('/');
+#endif
- if(p)
+ if(p != std::string::npos)
{
- strcpy(p + 1, "config.json");
- return m_defaultConfigName;
+ m_defaultConfigName.resize(p + 1);
+ m_defaultConfigName.append("config.json");
}
}
- return nullptr;
+ return m_defaultConfigName;
}
diff --git a/src/Platform.h b/src/Platform.h
index 3d203f5b..72339894 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -24,24 +24,25 @@
#ifndef __PLATFORM_H__
#define __PLATFORM_H__
+#include
class Platform
{
public:
- static const char* defaultConfigName();
- static void init(const char* userAgent);
+ static const std::string & defaultConfigName();
+ static void init(const std::string & userAgent);
static void release();
static void setProcessPriority(int priority);
static void setThreadPriority(int priority);
- static inline const char* userAgent()
+ static inline const std::string & userAgent()
{
return m_userAgent;
}
private:
- static char* m_defaultConfigName;
- static char* m_userAgent;
+ static std::string m_defaultConfigName;
+ static std::string m_userAgent;
};
diff --git a/src/Platform_mac.cpp b/src/Platform_mac.cpp
index 9fc37227..f054d553 100644
--- a/src/Platform_mac.cpp
+++ b/src/Platform_mac.cpp
@@ -20,7 +20,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+#ifndef _WIN32
#include
#include
@@ -32,39 +32,39 @@
#include "version.h"
#ifdef XMRIG_NVIDIA_PROJECT
-# include "nvidia/cryptonight.h"
+#include "nvidia/cryptonight.h"
#endif
-static inline char* createUserAgent()
+static inline std::string createUserAgent()
{
const size_t max = 160;
- char* buf = new char[max];
+ char buf[max];
-# ifdef XMRIG_NVIDIA_PROJECT
+#ifdef XMRIG_NVIDIA_PROJECT
const int cudaVersion = cuda_get_runtime_version();
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s CUDA/%d.%d clang/%d.%d.%d", APP_NAME,
APP_VERSION, uv_version_string(), cudaVersion / 1000, cudaVersion % 100, __clang_major__, __clang_minor__,
__clang_patchlevel__);
-# else
+#else
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s clang/%d.%d.%d", APP_NAME, APP_VERSION,
uv_version_string(), __clang_major__, __clang_minor__, __clang_patchlevel__);
-# endif
+#endif
return buf;
}
-void Platform::init(const char* userAgent)
+void Platform::init(const std::string & userAgent)
{
- m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
+ m_userAgent = (0 < userAgent.size()) ? userAgent : createUserAgent();
}
void Platform::release()
{
- delete [] m_userAgent;
+ m_userAgent.clear();
}
@@ -111,3 +111,4 @@ void Platform::setThreadPriority(int priority)
setpriority(PRIO_PROCESS, 0, prio);
}
+#endif
diff --git a/src/Platform_unix.cpp b/src/Platform_unix.cpp
index aa4233e0..6a0ae64e 100644
--- a/src/Platform_unix.cpp
+++ b/src/Platform_unix.cpp
@@ -20,6 +20,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
+#ifndef _WIN32
#include
#include
@@ -27,60 +28,58 @@
#include
#include
#include
+#include
+#include "log/Log.h"
#include "Platform.h"
#include "version.h"
#ifdef XMRIG_NVIDIA_PROJECT
-# include "nvidia/cryptonight.h"
+#include "nvidia/cryptonight.h"
#endif
-static inline char* createUserAgent()
+static inline std::string createUserAgent()
{
const size_t max = 160;
- char* buf = new char[max];
+ char buf[max];
int length = snprintf(buf, max, "%s/%s (Linux ", APP_NAME, APP_VERSION);
-# if defined(__x86_64__)
+#if defined(__x86_64__)
length += snprintf(buf + length, max - length, "x86_64) libuv/%s", uv_version_string());
-# else
+#else
length += snprintf(buf + length, max - length, "i686) libuv/%s", uv_version_string());
-# endif
+#endif
-# ifdef XMRIG_NVIDIA_PROJECT
+#ifdef XMRIG_NVIDIA_PROJECT
const int cudaVersion = cuda_get_runtime_version();
length += snprintf(buf + length, max - length, " CUDA/%d.%d", cudaVersion / 1000, cudaVersion % 100);
-# endif
+#endif
-# ifdef __GNUC__
+#ifdef __GNUC__
length += snprintf(buf + length, max - length, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
-# endif
+#endif
return buf;
}
-void Platform::init(const char* userAgent)
+void Platform::init(const std::string & userAgent)
{
- m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
+ m_userAgent = (0 < userAgent.size()) ? userAgent : createUserAgent();
}
-
void Platform::release()
{
- delete [] m_userAgent;
+ m_userAgent.clear();
}
-
void Platform::setProcessPriority(int priority)
{
}
-
-
void Platform::setThreadPriority(int priority)
{
if(priority == -1)
@@ -117,7 +116,7 @@ void Platform::setThreadPriority(int priority)
setpriority(PRIO_PROCESS, 0, prio);
-# ifdef SCHED_IDLE
+#ifdef SCHED_IDLE
if(priority == 0)
{
sched_param param;
@@ -125,8 +124,13 @@ void Platform::setThreadPriority(int priority)
if(sched_setscheduler(0, SCHED_IDLE, ¶m) != 0)
{
- sched_setscheduler(0, SCHED_BATCH, ¶m);
+ const int err = sched_setscheduler(0, SCHED_BATCH, ¶m);
+ LOG_WARN("SCHED_BATCH priority: " << err << ".");
}
}
+#else
+ LOG_INFO("NONE priority.");
# endif
}
+
+#endif
diff --git a/src/Platform_win.cpp b/src/Platform_win.cpp
index 02267b44..973cfd41 100644
--- a/src/Platform_win.cpp
+++ b/src/Platform_win.cpp
@@ -26,12 +26,13 @@
#include
#include
+#include "log/Log.h"
#include "Platform.h"
#include "version.h"
#ifdef XMRIG_NVIDIA_PROJECT
-# include "nvidia/cryptonight.h"
+#include "nvidia/cryptonight.h"
#endif
@@ -56,46 +57,45 @@ static inline OSVERSIONINFOEX winOsVersion()
}
-static inline char* createUserAgent()
+static inline std::string createUserAgent()
{
const auto osver = winOsVersion();
const size_t max = 160;
- char* buf = new char[max];
+ char buf[max];
int length = snprintf(buf, max, "%s/%s (Windows NT %lu.%lu", APP_NAME, APP_VERSION, osver.dwMajorVersion,
osver.dwMinorVersion);
-# if defined(__x86_64__) || defined(_M_AMD64)
+#if defined(__x86_64__) || defined(_M_AMD64)
length += snprintf(buf + length, max - length, "; Win64; x64) libuv/%s", uv_version_string());
-# else
+#else
length += snprintf(buf + length, max - length, ") libuv/%s", uv_version_string());
-# endif
+#endif
-# ifdef XMRIG_NVIDIA_PROJECT
+#ifdef XMRIG_NVIDIA_PROJECT
const int cudaVersion = cuda_get_runtime_version();
length += snprintf(buf + length, max - length, " CUDA/%d.%d", cudaVersion / 1000, cudaVersion % 100);
-# endif
+#endif
-# ifdef __GNUC__
+#ifdef __GNUC__
length += snprintf(buf + length, max - length, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
-# elif _MSC_VER
+#elif _MSC_VER
length += snprintf(buf + length, max - length, " msvc/%d", MSVC_VERSION);
-# endif
+#endif
return buf;
}
-void Platform::init(const char* userAgent)
+void Platform::init(const std::string & userAgent)
{
- m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
+ m_userAgent = (0 < userAgent.size()) ? userAgent : createUserAgent();
}
void Platform::release()
{
- delete [] m_defaultConfigName;
- delete [] m_userAgent;
+ m_userAgent.clear();
}
diff --git a/src/Summary.cpp b/src/Summary.cpp
index 05e27f50..d96c460d 100644
--- a/src/Summary.cpp
+++ b/src/Summary.cpp
@@ -51,10 +51,7 @@ static void print_versions()
# endif
- Log::i()->text(Options::i()->colors() ?
- "\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s" :
- " * VERSIONS: XMRig/%s libuv/%s%s",
- APP_VERSION, uv_version_string(), buf);
+ PRINT_MSG(" * VERSIONS: XMRig/" << APP_VERSION << " libuv/" << uv_version_string() << buf);
}
@@ -62,14 +59,16 @@ static void print_memory()
{
if(Options::i()->colors())
{
+ /*
Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s",
Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable",
Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled");
+ */
}
else
{
- Log::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable",
- Mem::isHugepagesEnabled() ? "enabled" : "disabled");
+ PRINT_MSG(" * HUGE PAGES: " << (Mem::isHugepagesAvailable() ? "available" : "unavailable") << ", " <<
+ (Mem::isHugepagesEnabled() ? "enabled" : "disabled"));
}
}
@@ -78,22 +77,25 @@ static void print_cpu()
{
if(Options::i()->colors())
{
+ /*
Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI",
Cpu::brand(),
Cpu::sockets(),
Cpu::isX64() ? "\x1B[01;32m" : "\x1B[01;31m-",
Cpu::hasAES() ? "\x1B[01;32m" : "\x1B[01;31m-");
-# ifndef XMRIG_NO_LIBCPUID
+ # ifndef XMRIG_NO_LIBCPUID
Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0,
Cpu::l3() / 1024.0);
-# endif
+ # endif
+ */
}
else
{
- Log::i()->text(" * CPU: %s (%d) %sx64 %sAES-NI", Cpu::brand(), Cpu::sockets(),
- Cpu::isX64() ? "" : "-", Cpu::hasAES() ? "" : "-");
+ PRINT_MSG(" * CPU: " << Cpu::brand() << " (" << Cpu::threads() << "@" << Cpu::sockets() << ") " <<
+ (Cpu::isX64() ? "" : "-") << "64 " <<
+ (Cpu::hasAES() ? "" : "-") << "AES-NI");
# ifndef XMRIG_NO_LIBCPUID
- Log::i()->text(" * CPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0);
+ PRINT_MSG(" * CPU L2/L3: " << (Cpu::l2() / 1024.0) << " MB/" << Cpu::l3() / 1024.0 << " MB");
# endif
}
}
@@ -111,36 +113,29 @@ static void print_threads()
buf[0] = '\0';
}
- Log::i()->text(Options::i()->colors() ?
- "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" :
- " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s",
- Options::i()->threads(),
- Options::i()->algoName(),
- Options::i()->algoVariant(),
- Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "",
- Options::i()->donateLevel(),
- buf);
+ PRINT_MSG(" * THREADS: " << Options::i()->threads() << ", " << Options::i()->algoName() << ", av=" <<
+ Options::i()->algoVariant() << ", donate-minutes=" << Options::i()->donateMinutes() <<
+ ((Options::i()->donateMinutes() > 0) ? ("/" +
+ Log::ToString(Options::i()->minutesInCicle()) + " (" + Log::ToString((100 *
+ Options::i()->donateMinutes()) /
+ Options::i()->minutesInCicle()) + "%)") : "") << buf);
}
static void print_pools()
{
- const std::vector & pools = Options::i()->pools();
+ const std::vector & pools = Options::i()->pools();
for(size_t i = 0; i < pools.size(); ++i)
{
- Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s:%d" :
- " * POOL #%d: %s:%d",
- i + 1,
- pools[i]->host(),
- pools[i]->port());
+ PRINT_MSG(" * POOL #" << (i + 1) << ": " << pools[i].host() << ":" << pools[i].port());
}
# ifdef APP_DEBUG
for(size_t i = 0; i < pools.size(); ++i)
{
- Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i]->host(), pools[i]->port(),
- pools[i]->user(), pools[i]->password(), pools[i]->isKeepAlive(), pools[i]->isNicehash());
+ PRINT_MSG(pools[i].host() << ":" << pools[i].port() << ", user: " << pools[i].user() << ", pass: " <<
+ pools[i].password() << ", ka: " << pools[i].isKeepAlive() << ", nicehash: " << pools[i].isNicehash());
}
# endif
}
@@ -154,8 +149,17 @@ static void print_api()
return;
}
- Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT: \x1B[01;36m%d" :
- " * API PORT: %d", Options::i()->apiPort());
+ if(Options::i()->colors())
+ {
+ /*TODO LOG
+ Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT: \x1B[01;36m%d" :
+ " * API PORT: %d", Options::i()->apiPort());
+ */
+ }
+ else
+ {
+ PRINT_MSG(" * API PORT: " << Options::i()->apiPort());
+ }
}
#endif
@@ -164,11 +168,13 @@ static void print_commands()
{
if(Options::i()->colors())
{
+ /*
Log::i()->text("\x1B[01;32m * \x1B[01;37mCOMMANDS: \x1B[01;35mh\x1B[01;37mashrate, \x1B[01;35mp\x1B[01;37mause, \x1B[01;35mr\x1B[01;37mesume");
+ */
}
else
{
- Log::i()->text(" * COMMANDS: 'h' hashrate, 'p' pause, 'r' resume");
+ PRINT_MSG(" * COMMANDS: 'h' hashrate, 'p' pause, 'r' resume");
}
}
diff --git a/src/api/Api.cpp b/src/api/Api.cpp
index ed1f1a85..5ab4a831 100644
--- a/src/api/Api.cpp
+++ b/src/api/Api.cpp
@@ -21,6 +21,7 @@
* along with this program. If not, see .
*/
+#ifndef XMRIG_NO_API
#include
@@ -47,15 +48,15 @@ void Api::release()
}
-char* Api::get(const char* url, int* status)
+std::string Api::get(const std::string & url, int* status)
{
if(!m_state)
{
- return nullptr;
+ return "";
}
uv_mutex_lock(&m_mutex);
- char* buf = m_state->get(url, status);
+ std::string buf = m_state->get(url, status);
uv_mutex_unlock(&m_mutex);
return buf;
@@ -86,3 +87,5 @@ void Api::tick(const NetworkState & network)
m_state->tick(network);
uv_mutex_unlock(&m_mutex);
}
+
+#endif
diff --git a/src/api/Api.h b/src/api/Api.h
index b81543ef..660c7a25 100644
--- a/src/api/Api.h
+++ b/src/api/Api.h
@@ -26,7 +26,9 @@
#include
+#include
+#include "interfaces/interface.h"
class ApiState;
class Hashrate;
@@ -39,7 +41,7 @@ public:
static bool start();
static void release();
- static char* get(const char* url, int* status);
+ static std::string get(const std::string & url, int* status);
static void tick(const Hashrate* hashrate);
static void tick(const NetworkState & results);
diff --git a/src/api/ApiState.cpp b/src/api/ApiState.cpp
index fcf0dd27..aba2f4e7 100644
--- a/src/api/ApiState.cpp
+++ b/src/api/ApiState.cpp
@@ -31,7 +31,6 @@
# include "unistd.h"
#endif
-
#include "api/ApiState.h"
#include "Cpu.h"
#include "Mem.h"
@@ -50,14 +49,14 @@ extern "C"
#include "crypto/c_keccak.h"
}
-
static inline double normalize(double d)
{
+#ifndef _WIN32
if(!isnormal(d))
{
return 0.0;
}
-
+#endif
return floor(d * 100.0) / 100.0;
}
@@ -70,9 +69,9 @@ ApiState::ApiState()
memset(m_totalHashrate, 0, sizeof(m_totalHashrate));
memset(m_workerId, 0, sizeof(m_workerId));
- if(Options::i()->apiWorkerId())
+ if(0 < Options::i()->apiWorkerId().size())
{
- strncpy(m_workerId, Options::i()->apiWorkerId(), sizeof(m_workerId) - 1);
+ strncpy(m_workerId, Options::i()->apiWorkerId().c_str(), sizeof(m_workerId) - 1);
}
else
{
@@ -89,7 +88,7 @@ ApiState::~ApiState()
}
-char* ApiState::get(const char* url, int* status) const
+std::string ApiState::get(const std::string & url, int* status) const
{
rapidjson::Document doc;
doc.SetObject();
@@ -126,14 +125,14 @@ void ApiState::tick(const NetworkState & network)
}
-char* ApiState::finalize(rapidjson::Document & doc) const
+std::string ApiState::finalize(rapidjson::Document & doc) const
{
rapidjson::StringBuffer buffer(0, 4096);
rapidjson::PrettyWriter writer(buffer);
writer.SetMaxDecimalPlaces(10);
doc.Accept(writer);
- return strdup(buffer.GetString());
+ return buffer.GetString();
}
@@ -162,7 +161,9 @@ void ApiState::genId()
memcpy(input + addrSize, APP_KIND, strlen(APP_KIND));
keccak(input, static_cast(inSize), hash, sizeof(hash));
- Job::toHex(hash, 8, m_id);
+
+ char* hashChar = (char*)hash;
+ Job::toHex(std::string(hashChar, 8), m_id);
delete [] input;
break;
@@ -237,11 +238,13 @@ void ApiState::getMiner(rapidjson::Document & doc) const
doc.AddMember("version", APP_VERSION, allocator);
doc.AddMember("kind", APP_KIND, allocator);
- doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
+ doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent().c_str()), allocator);
doc.AddMember("cpu", cpu, allocator);
doc.AddMember("algo", rapidjson::StringRef(Options::i()->algoName()), allocator);
doc.AddMember("hugepages", Mem::isHugepagesEnabled(), allocator);
- doc.AddMember("donate_level", Options::i()->donateLevel(), allocator);
+
+ doc.AddMember("donate_minutes_per_cicle", Options::i()->donateMinutes(), allocator);
+ doc.AddMember("minutes_per_cicle", Options::i()->minutesInCicle(), allocator);
}
diff --git a/src/api/ApiState.h b/src/api/ApiState.h
index 63442cb7..54c60ab1 100644
--- a/src/api/ApiState.h
+++ b/src/api/ApiState.h
@@ -28,6 +28,7 @@
#include "api/NetworkState.h"
#include "rapidjson/fwd.h"
+#include
class Hashrate;
@@ -38,12 +39,12 @@ public:
ApiState();
~ApiState();
- char* get(const char* url, int* status) const;
+ std::string get(const std::string & url, int* status) const;
void tick(const Hashrate* hashrate);
void tick(const NetworkState & results);
private:
- char* finalize(rapidjson::Document & doc) const;
+ std::string finalize(rapidjson::Document & doc) const;
void genId();
void getConnection(rapidjson::Document & doc) const;
void getHashrate(rapidjson::Document & doc) const;
diff --git a/src/api/Httpd.cpp b/src/api/Httpd.cpp
index ad646355..ce551ffb 100644
--- a/src/api/Httpd.cpp
+++ b/src/api/Httpd.cpp
@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones
* Copyright 2014-2016 Wolf9466
* Copyright 2016 Jay D Dee
- * Copyright 2017-2018 XMR-Stak ,
- * Copyright 2016-2018 XMRig ,
+ * Copyright 2016-2017 XMRig
+ *
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,24 +21,21 @@
* along with this program. If not, see .
*/
-
+#ifndef XMRIG_NO_HTTPD
#include
#include
-
#include "api/Api.h"
#include "api/Httpd.h"
#include "log/Log.h"
-
-Httpd::Httpd(int port, const char* accessToken) :
+Httpd::Httpd(int port, const std::string & accessToken) :
m_accessToken(accessToken),
m_port(port),
m_daemon(nullptr)
{
}
-
bool Httpd::start()
{
if(!m_port)
@@ -46,22 +43,8 @@ bool Httpd::start()
return false;
}
- unsigned int flags = 0;
- if(MHD_is_feature_supported(MHD_FEATURE_EPOLL))
- {
- flags = MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY;
- }
- else
- {
- flags = MHD_USE_SELECT_INTERNALLY;
- }
-
- if(MHD_is_feature_supported(MHD_FEATURE_IPv6))
- {
- flags |= MHD_USE_DUAL_STACK;
- }
-
- m_daemon = MHD_start_daemon(flags, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
+ m_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, m_port, nullptr, nullptr, &Httpd::handler, this,
+ MHD_OPTION_END);
if(!m_daemon)
{
LOG_ERR("HTTP Daemon failed to start.");
@@ -72,25 +55,25 @@ bool Httpd::start()
}
-int Httpd::auth(const char* header)
+int Httpd::auth(const std::string & header)
{
- if(!m_accessToken)
+ if(m_accessToken.empty())
{
return MHD_HTTP_OK;
}
- if(m_accessToken && !header)
+ if(0 < m_accessToken.size() && header.empty())
{
return MHD_HTTP_UNAUTHORIZED;
}
- const size_t size = strlen(header);
- if(size < 8 || strlen(m_accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0)
+ const size_t size = header.size();
+ if(size < 8 || m_accessToken.size() != size - 7 || "Bearer " == header.substr(0, 7))
{
return MHD_HTTP_FORBIDDEN;
}
- return strncmp(m_accessToken, header + 7, strlen(m_accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
+ return (m_accessToken == header.substr(7)) ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
}
@@ -112,15 +95,16 @@ int Httpd::done(MHD_Connection* connection, int status, MHD_Response* rsp)
}
-int Httpd::handler(void* cls, struct MHD_Connection* connection, const char* url, const char* method,
- const char* version, const char* upload_data, size_t* upload_data_size, void** con_cls)
+int Httpd::handlerStd(void* cls, struct MHD_Connection* connection, const std::string & url,
+ const std::string & method, const std::string & version, const std::string & upload_data,
+ size_t* upload_data_size, void** con_cls)
{
- if(strcmp(method, "OPTIONS") == 0)
+ if(method == "OPTIONS")
{
return done(connection, MHD_HTTP_OK, nullptr);
}
- if(strcmp(method, "GET") != 0)
+ if(method != "GET")
{
return MHD_NO;
}
@@ -132,12 +116,21 @@ int Httpd::handler(void* cls, struct MHD_Connection* connection, const char* url
return done(connection, status, nullptr);
}
- char* buf = Api::get(url, &status);
- if(buf == nullptr)
+ std::string buf = Api::get(url, &status);
+ if(buf.empty())
{
return MHD_NO;
}
- MHD_Response* rsp = MHD_create_response_from_buffer(strlen(buf), (void*) buf, MHD_RESPMEM_MUST_FREE);
+ MHD_Response* rsp = MHD_create_response_from_buffer(buf.size(), (void*) buf.c_str(), MHD_RESPMEM_MUST_FREE);
return done(connection, status, rsp);
}
+
+int Httpd::handler(void* cls, MHD_Connection* connection, const char* url, const char* method,
+ const char* version, const char* upload_data, size_t* upload_data_size,
+ void** con_cls)
+{
+ return handlerStd(cls, connection, url, method, version, upload_data, upload_data_size, con_cls);
+}
+
+#endif
diff --git a/src/api/Httpd.h b/src/api/Httpd.h
index 17ce3faf..18da026b 100644
--- a/src/api/Httpd.h
+++ b/src/api/Httpd.h
@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones
* Copyright 2014-2016 Wolf9466
* Copyright 2016 Jay D Dee
- * Copyright 2017-2018 XMR-Stak ,
- * Copyright 2016-2018 XMRig ,
+ * Copyright 2016-2017 XMRig
+ *
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,29 +24,32 @@
#ifndef __HTTPD_H__
#define __HTTPD_H__
-
#include
-
struct MHD_Connection;
struct MHD_Daemon;
struct MHD_Response;
-
class Httpd
{
public:
- Httpd(int port, const char* accessToken);
+ Httpd(int port, const std::string & accessToken);
bool start();
private:
- int auth(const char* header);
+ int auth(const std::string & header);
static int done(MHD_Connection* connection, int status, MHD_Response* rsp);
- static int handler(void* cls, MHD_Connection* connection, const char* url, const char* method,
- const char* version, const char* upload_data, size_t* upload_data_size, void** con_cls);
+ static int handlerStd(void* cls, MHD_Connection* connection, const std::string & url,
+ const std::string & method,
+ const std::string & version, const std::string & upload_data, size_t* upload_data_size,
+ void** con_cls);
- const char* m_accessToken;
+ static int handler(void* cls, MHD_Connection* connection, const char* url, const char* method,
+ const char* version, const char* upload_data, size_t* upload_data_size,
+ void** con_cls);
+
+ const std::string & m_accessToken;
const int m_port;
MHD_Daemon* m_daemon;
};
diff --git a/src/api/NetworkState.cpp b/src/api/NetworkState.cpp
index 79023d6a..d2f25bc8 100644
--- a/src/api/NetworkState.cpp
+++ b/src/api/NetworkState.cpp
@@ -27,6 +27,8 @@
#include
#include
+#include "interfaces/interface.h"
+
#include "api/NetworkState.h"
#include "net/SubmitResult.h"
@@ -76,9 +78,9 @@ uint32_t NetworkState::latency() const
}
-void NetworkState::add(const SubmitResult & result, const char* error)
+void NetworkState::add(const SubmitResult & result, const std::string & error)
{
- if(error)
+ if(0 < error.size())
{
rejected++;
return;
@@ -98,9 +100,9 @@ void NetworkState::add(const SubmitResult & result, const char* error)
}
-void NetworkState::setPool(const char* host, int port, const char* ip)
+void NetworkState::setPool(const std::string & host, int port, const std::string & ip)
{
- snprintf(pool, sizeof(pool) - 1, "%s:%d", host, port);
+ snprintf(pool, sizeof(pool) - 1, "%s:%d", host.c_str(), port);
m_active = true;
m_connectionTime = uv_now(uv_default_loop());
diff --git a/src/api/NetworkState.h b/src/api/NetworkState.h
index 2688cd86..dfbe6c2d 100644
--- a/src/api/NetworkState.h
+++ b/src/api/NetworkState.h
@@ -27,6 +27,7 @@
#include
#include
+#include
class SubmitResult;
@@ -40,12 +41,12 @@ public:
int connectionTime() const;
uint32_t avgTime() const;
uint32_t latency() const;
- void add(const SubmitResult & result, const char* error);
- void setPool(const char* host, int port, const char* ip);
+ void add(const SubmitResult & result, const std::string & error);
+ void setPool(const std::string & host, int port, const std::string & ip);
void stop();
char pool[256];
- std::array topDiff { { } };
+ std::array topDiff;
uint32_t diff;
uint64_t accepted;
uint64_t failures;
diff --git a/src/config.json b/src/config.json
index 7813d4b9..ad08a09c 100644
--- a/src/config.json
+++ b/src/config.json
@@ -1,11 +1,29 @@
{
"algo": "cryptonight", // cryptonight (default) or cryptonight-lite
+ "user-agent": "", // custom user-agent
"av": 0, // algorithm variation, 0 auto select
"background": false, // true to run the miner in the background
- "colors": true, // false to disable colored output
+ "colors": false, // true to enable colored output
"cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1
"cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest)
- "donate-level": 5, // donate level, mininum 1%
+/* Default donate setting: */
+ "donate-level": 3, // default donate minutes (3 minutes each 1 hour)
+/* Custom donate settings:
+ "donate-level": [
+ {
+// "donate-url": "fee.xmrig.com:443", // custom donate pool for cryptonight
+// "donate-url-little": "fee.xmrig.com:3333", // custom donate pool for cryptonight-little
+// "donate-user": "", // custom donate user
+// "donate-pass": "", // custom donate pass
+// "donate-keepalive": false, // custom donate keepalive
+// "donate-nicehash": true, // custom donate nicehash
+ "donate-minutes": 3, // custom donate minutes for each cicle
+ "minutes-in-cicle": 60 // custom total minutes in a cicle (60 => 1 hour)
+ // that is [(57 minutes) to pool + (3 minutes) to donate...] and repeat all until miner ends.
+ }
+ ],
+*/
+ "debug": false,
"log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log"
"max-cpu-usage": 75, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option.
"print-time": 60, // print hashrate report every N seconds
@@ -16,11 +34,14 @@
"threads": null, // number of miner threads
"pools": [
{
- "url": "pool.minemonero.pro:5555", // URL of mining server
- "user": "", // username for mining server
- "pass": "x", // password for mining server
- "keepalive": true, // send keepalived for prevent timeout (need pool support)
- "nicehash": false // enable nicehash/xmrig-proxy support
+ "url": "pool.minemonero.pro:3333", // --------------- URL of mining server
+ /* "url": "pool.minemonero.pro:443@localhost:8080",*/ // --------------- URL of mining server over HTTP (CONNECT) proxy
+ /* "url": "pool.minemonero.pro:7777#secret_keystream",*/ // URL of mining xmrig-proxy with encrypted support
+ /* "url": "pool.minemonero.pro:8080#secret_keystream@localhost:8080",*/ // URL of mining xmrig-proxy with encrypted support over HTTP (CONNECT) proxy
+ "user": "%HOST_NAME%_%IP_ADD%+100", // username for mining server using meta-data (%HOST_NAME%, %IP_ADD%, etc.)
+ "pass": "x", // password for mining server
+ "keepalive": true, // send keepalived for prevent timeout (need pool support)
+ "nicehash": false // enable nicehash/xmrig-proxy support
}
],
"api": {
diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h
index b3586811..9003dd01 100644
--- a/src/crypto/CryptoNight.h
+++ b/src/crypto/CryptoNight.h
@@ -29,6 +29,8 @@
#include
#include
+#include "align.h"
+#include "interfaces/interface.h"
#define AEON_MEMORY 1048576
#define AEON_MASK 0xFFFF0
@@ -41,9 +43,9 @@
struct cryptonight_ctx
{
- alignas(16) uint8_t state0[200];
- alignas(16) uint8_t state1[200];
- alignas(16) uint8_t* memory;
+ VAR_ALIGN(16, uint8_t state0[200]);
+ VAR_ALIGN(16, uint8_t state1[200]);
+ VAR_ALIGN(16, uint8_t* memory);
};
diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h
index 0bd0b66e..e952f88c 100644
--- a/src/crypto/CryptoNight_arm.h
+++ b/src/crypto/CryptoNight_arm.h
@@ -463,6 +463,7 @@ inline void cryptonight_double_hash(const void* __restrict__ input, size_t size,
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
+
VARIANT1_1(&l0[idx0 & MASK]);
VARIANT1_1(&l1[idx1 & MASK]);
diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h
index 56e4bac7..d6a2c890 100644
--- a/src/crypto/CryptoNight_x86.h
+++ b/src/crypto/CryptoNight_x86.h
@@ -77,7 +77,7 @@ void (* const extra_hashes[4])(const void*, size_t, char*) = {do_blake_hash, do_
-#if defined(__x86_64__) || defined(_M_AMD64)
+#if (defined(__x86_64__) || defined(_M_AMD64)) && __cplusplus > 199711L
# define EXTRACT64(X) _mm_cvtsi128_si64(X)
# ifdef __GNUC__
@@ -90,7 +90,7 @@ static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi)
# else
#define __umul128 _umul128
# endif
-#elif defined(__i386__) || defined(_M_IX86)
+#elif defined(__i386__) || defined(_M_IX86) || __cplusplus <= 199711L
# define HI32(X) \
_mm_srli_si128((X), 4)
@@ -318,6 +318,17 @@ static inline void cn_implode_scratchpad(const __m128i* input, __m128i* output)
_mm_store_si128(output + 11, xout7);
}
+#if ! defined _WIN64 && defined _WIN32
+#if defined(_MSC_VER) && _MSC_VER < 1900
+static inline __m128i _mm_set_epi64x(const uint64_t __a, const uint64_t __b)
+{
+ __m128i ret;
+ ret.m128i_u64[1] = __a;
+ ret.m128i_u64[0] = __b;
+ return ret;
+}
+#endif
+#endif
template
inline void cryptonight_single_hash(const void* __restrict__ input, size_t size, void* __restrict__ output,
@@ -352,7 +363,9 @@ inline void cryptonight_single_hash(const void* __restrict__ input, size_t size,
cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0));
}
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
+
VARIANT1_1(&l0[idx0 & MASK]);
+
idx0 = EXTRACT64(cx);
bx0 = cx;
@@ -429,6 +442,7 @@ inline void cryptonight_double_hash(const void* __restrict__ input, size_t size,
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
+
VARIANT1_1(&l0[idx0 & MASK]);
VARIANT1_1(&l1[idx1 & MASK]);
diff --git a/src/crypto/c_skein.c b/src/crypto/c_skein.c
index 68c182f7..d35a56b5 100644
--- a/src/crypto/c_skein.c
+++ b/src/crypto/c_skein.c
@@ -654,7 +654,7 @@ static SkeinHashReturn Update(hashState* state, const SkeinBitSequence* data, Sk
b = (u08b_t)((data[bCnt - 1] & (0 - mask)) | mask); /* apply bit padding on final byte */
Skein_512_Update(&state->u.ctx_512, data, bCnt - 1); /* process all but the final byte */
- Skein_512_Update(&state->u.ctx_512, &b, 1); /* process the (masked) partial byte */
+ Skein_512_Update(&state->u.ctx_512, &b, 1); /* process the (masked) partial byte */
Skein_Set_Bit_Pad_Flag(state->u.h); /* set tweak flag for the final call */
return SKEIN_SUCCESS;
@@ -697,8 +697,7 @@ void xmr_skein(const SkeinBitSequence* data, SkeinBitSequence* hashval)
// Skein_512_Init(&state.u.ctx_512, (size_t)XMR_HASHBITLEN);
state.u.ctx_512.h.hashBitLen = XMR_HASHBITLEN;
memcpy(state.u.ctx_512.X, SKEIN_512_IV_256, sizeof(state.u.ctx_512.X));
- Skein_512_Ctxt_t* ctx = &(state.u.ctx_512);
- Skein_Start_New_Type(ctx, MSG);
+ Skein_Start_New_Type(&state.u.ctx_512, MSG);
// Update
if((XMR_DATABITLEN & 7) == 0) /* partial bytes? */
diff --git a/src/crypto/soft_aes.h b/src/crypto/soft_aes.h
index f067b1c7..68a6d947 100644
--- a/src/crypto/soft_aes.h
+++ b/src/crypto/soft_aes.h
@@ -37,6 +37,8 @@
#include
+#include "align.h"
+
#define saes_data(w) {\
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
@@ -86,8 +88,8 @@
#define saes_u2(p) saes_b2w( p, saes_f3(p), saes_f2(p), p)
#define saes_u3(p) saes_b2w( p, p, saes_f3(p), saes_f2(p))
-alignas(16) const uint32_t saes_table[4][256] = { saes_data(saes_u0), saes_data(saes_u1), saes_data(saes_u2), saes_data(saes_u3) };
-alignas(16) const uint8_t saes_sbox[256] = saes_data(saes_h0);
+VAR_ALIGN(16, const uint32_t saes_table[4][256]) = { saes_data(saes_u0), saes_data(saes_u1), saes_data(saes_u2), saes_data(saes_u3) };
+VAR_ALIGN(16, const uint8_t saes_sbox[256]) = saes_data(saes_h0);
static inline __m128i soft_aesenc(const uint32_t* in, __m128i key)
{
@@ -117,7 +119,7 @@ static inline uint32_t sub_word(uint32_t key)
saes_sbox[key & 0xff];
}
-#if defined(__clang__) || defined(XMRIG_ARM)
+#if defined(__clang__) || defined(XMRIG_ARM) || __cplusplus <= 199711L
static inline uint32_t _rotr(uint32_t value, uint32_t amount)
{
return (value >> amount) | (value << ((32 - amount) & 31));
diff --git a/src/donate.h b/src/donate.h
index 3a000948..9af6b8e6 100644
--- a/src/donate.h
+++ b/src/donate.h
@@ -28,16 +28,28 @@
/*
* Dev donation.
*
- * Percentage of your hashing power that you want to donate to the developer, can be 0 if you don't want to do that.
- * Example of how it works for the default setting of 1:
- * You miner will mine into your usual pool for 99 minutes, then switch to the developer's pool for 1 minute.
- * Switching is instant, and only happens after a successful connection, so you never loose any hashes.
+ * Percentage of your hashing power that you want to donate to the donation server,
+ * can be 0 if you don't want to do that.
*
* If you plan on changing this setting to 0 please consider making a one off donation to my wallet:
- * XMR: 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD
- * BTC: 1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT
+ * XMR: 433hhduFBtwVXtQiTTTeqyZsB36XaBLJB6bcQfnqqMs5RJitdpi8xBN21hWiEfuPp2hytmf1cshgK5Grgo6QUvLZCP2QSMi
+ *
+ * How it works:
+ * Other connections switch to donation pool until the first 60 minutes, kDonateLevel minutes each hour
+ * with overime compensation; but the period can be customizable. In proxy no way to use precise donation time!
+ * You can check actual donation via API.
*/
-constexpr const int kDonateLevel = 5;
+enum
+{
+ kDonateMinutes = 3,
+ kMinutesInCicle = 60,
+ kDonateKeepAlive = false,
+ kDonateNiceHash = true,
+};
+static const char* kDonateUrl = "fee.xmrig.com:443";
+static const char* kDonateUrlLittle = "fee.xmrig.com:3333";
+static const char* kDonateUser = "";
+static const char* kDonatePass = "x";
#endif /* __DONATE_H__ */
diff --git a/src/interfaces/IClientListener.h b/src/interfaces/IClientListener.h
index 4f240a8b..1d4236d9 100644
--- a/src/interfaces/IClientListener.h
+++ b/src/interfaces/IClientListener.h
@@ -38,10 +38,10 @@ class IClientListener
public:
virtual ~IClientListener() {}
- virtual void onClose(Client* client, int failures) = 0;
- virtual void onJobReceived(Client* client, const Job & job) = 0;
- virtual void onLoginSuccess(Client* client) = 0;
- virtual void onResultAccepted(Client* client, const SubmitResult & result, const char* error) = 0;
+ virtual void onClose(Client* client, int failures) = 0;
+ virtual void onJobReceived(Client* client, const Job & job) = 0;
+ virtual void onLoginSuccess(Client* client) = 0;
+ virtual void onResultAccepted(Client* client, const SubmitResult & result, const std::string & error) = 0;
};
diff --git a/src/interfaces/IConsoleListener.h b/src/interfaces/IConsoleListener.h
index 51aaf50c..af624ace 100644
--- a/src/interfaces/IConsoleListener.h
+++ b/src/interfaces/IConsoleListener.h
@@ -24,6 +24,7 @@
#ifndef __ICONSOLELISTENER_H__
#define __ICONSOLELISTENER_H__
+#include "interfaces/interface.h"
class IConsoleListener
{
diff --git a/src/interfaces/ILogBackend.h b/src/interfaces/ILogBackend.h
index a5e11438..bdd7f23f 100644
--- a/src/interfaces/ILogBackend.h
+++ b/src/interfaces/ILogBackend.h
@@ -7,6 +7,7 @@
* Copyright 2016-2017 XMRig
*
*
+ * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -23,17 +24,25 @@
#ifndef __ILOGBACKEND_H__
#define __ILOGBACKEND_H__
-
-#include
-
+#include "interfaces/interface.h"
+#include
class ILogBackend
{
public:
+ enum Level
+ {
+ ERR,
+ WARNING,
+ NOTICE,
+ INFO,
+ DEBUG
+ };
+
virtual ~ILogBackend() {}
- virtual void message(int level, const char* fmt, va_list args) = 0;
- virtual void text(const char* fmt, va_list args) = 0;
+ virtual void message(Level level, const std::string & txt) = 0;
+ virtual void text(const std::string & txt) = 0;
};
diff --git a/src/interfaces/IStrategy.h b/src/interfaces/IStrategy.h
index 0d148666..bbf9c523 100644
--- a/src/interfaces/IStrategy.h
+++ b/src/interfaces/IStrategy.h
@@ -24,10 +24,9 @@
#ifndef __ISTRATEGY_H__
#define __ISTRATEGY_H__
-
+#include "interfaces/interface.h"
#include
-
class JobResult;
diff --git a/src/interfaces/IStrategyListener.h b/src/interfaces/IStrategyListener.h
index 4093aac6..8fb7469c 100644
--- a/src/interfaces/IStrategyListener.h
+++ b/src/interfaces/IStrategyListener.h
@@ -24,26 +24,23 @@
#ifndef __ISTRATEGYLISTENER_H__
#define __ISTRATEGYLISTENER_H__
-
#include
-
+#include
class Client;
class IStrategy;
class Job;
class SubmitResult;
-
class IStrategyListener
{
public:
virtual ~IStrategyListener() {}
- virtual void onActive(Client* client) = 0;
- virtual void onJob(Client* client, const Job & job) = 0;
- virtual void onPause(IStrategy* strategy) = 0;
- virtual void onResultAccepted(Client* client, const SubmitResult & result, const char* error) = 0;
+ virtual void onActive(Client* client) = 0;
+ virtual void onJob(Client* client, const Job & job) = 0;
+ virtual void onPause(IStrategy* strategy) = 0;
+ virtual void onResultAccepted(Client* client, const SubmitResult & result, const std::string & error) = 0;
};
-
#endif // __ISTRATEGYLISTENER_H__
diff --git a/src/interfaces/interface.h b/src/interfaces/interface.h
new file mode 100644
index 00000000..987b75d4
--- /dev/null
+++ b/src/interfaces/interface.h
@@ -0,0 +1,64 @@
+/* XMRig - enWILLYado
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#ifndef __INTERFACE_H__
+#define __INTERFACE_H__
+
+#if __cplusplus <= 199711L
+#define override
+#define nullptr NULL
+#endif
+
+#ifdef _WIN32
+#if defined(_MSC_VER) && _MSC_VER < 1900
+
+// VS
+#include
+#include
+#include
+#define snprintf c99_snprintf
+#define vsnprintf c99_vsnprintf
+
+__inline int c99_vsnprintf(char* outBuf, size_t size, const char* format, va_list ap)
+{
+ int count = -1;
+
+ if(size != 0)
+ {
+ count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
+ }
+ if(count == -1)
+ {
+ count = _vscprintf(format, ap);
+ }
+
+ return count;
+}
+
+__inline int c99_snprintf(char* outBuf, size_t size, const char* format, ...)
+{
+ int count;
+ va_list ap;
+
+ va_start(ap, format);
+ count = c99_vsnprintf(outBuf, size, format, ap);
+ va_end(ap);
+
+ return count;
+}
+#endif
+#endif
+
+#endif // __INTERFACE_H__
diff --git a/src/log/ConsoleLog.cpp b/src/log/ConsoleLog.cpp
index abcbef72..904cd860 100644
--- a/src/log/ConsoleLog.cpp
+++ b/src/log/ConsoleLog.cpp
@@ -21,143 +21,98 @@
* along with this program. If not, see .
*/
-
#include
#include
#include
#include
#include
-#ifdef WIN32
-# include
-# include
-#endif
-
+#include
#include "log/ConsoleLog.h"
#include "log/Log.h"
-#include "Options.h"
-
ConsoleLog::ConsoleLog(bool colors) :
- m_colors(colors),
- m_stream(nullptr)
+ m_colors(colors)
{
- if(uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0)
+}
+
+void ConsoleLog::message(Level level, const std::string & text)
+{
+ if(!isWritable())
{
- Options::i()->setColors(false);
- m_colors = false;
return;
}
- uv_tty_set_mode(&m_tty, UV_TTY_MODE_NORMAL);
- m_uvBuf.base = m_buf;
- m_stream = reinterpret_cast(&m_tty);
-
-# ifdef WIN32
- HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
- if(handle != INVALID_HANDLE_VALUE)
- {
- DWORD mode = 0;
- if(GetConsoleMode(handle, &mode))
- {
- mode &= ~ENABLE_QUICK_EDIT_MODE;
- SetConsoleMode(handle, mode | ENABLE_EXTENDED_FLAGS);
- }
- }
-# endif
-}
-
-
-void ConsoleLog::message(int level, const char* fmt, va_list args)
-{
+ //
+ //
time_t now = time(nullptr);
tm stime;
-# ifdef _WIN32
+#ifdef _WIN32
localtime_s(&stime, &now);
-# else
+#else
localtime_r(&now, &stime);
-# endif
+#endif
- const char* color = nullptr;
+ char buf[25];
+ int size = snprintf(buf, sizeof(buf), "[%d-%02d-%02d %02d:%02d:%02d] ",
+ stime.tm_year + 1900,
+ stime.tm_mon + 1,
+ stime.tm_mday,
+ stime.tm_hour,
+ stime.tm_min,
+ stime.tm_sec);
+
+ //
+ //
+ std::string colorIni, colorEnd;
if(m_colors)
{
+ colorEnd = Log::CL_N();
switch(level)
{
- case Log::ERR:
- color = Log::kCL_RED;
+ case ILogBackend::ERR:
+ colorIni = Log::CL_RED();
break;
- case Log::WARNING:
- color = Log::kCL_YELLOW;
+ case ILogBackend::WARNING:
+ colorIni = Log::CL_YELLOW();
break;
- case Log::NOTICE:
- color = Log::kCL_WHITE;
+ case ILogBackend::NOTICE:
+ colorIni = Log::CL_WHITE();
break;
- case Log::DEBUG:
- color = Log::kCL_GRAY;
+ case ILogBackend::DEBUG:
+ colorIni = Log::CL_GRAY();
break;
default:
- color = "";
break;
}
}
- snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n",
- stime.tm_year + 1900,
- stime.tm_mon + 1,
- stime.tm_mday,
- stime.tm_hour,
- stime.tm_min,
- stime.tm_sec,
- m_colors ? color : "",
- fmt,
- m_colors ? Log::kCL_N : ""
- );
-
- print(args);
+ print(std::string(buf, size) + colorIni + text + colorEnd);
}
-
-void ConsoleLog::text(const char* fmt, va_list args)
+void ConsoleLog::text(const std::string & txt)
{
- snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_colors ? Log::kCL_N : "");
-
- print(args);
-}
-
-
-bool ConsoleLog::isWritable() const
-{
- if(!m_stream || uv_is_writable(m_stream) != 1)
- {
- return false;
- }
-
- const uv_handle_type type = uv_guess_handle(1);
- return type == UV_TTY || type == UV_NAMED_PIPE;
-}
-
-
-void ConsoleLog::print(va_list args)
-{
- m_uvBuf.len = vsnprintf(m_buf, sizeof(m_buf) - 1, m_fmt, args);
- if(m_uvBuf.len <= 0)
+ if(!isWritable())
{
return;
}
- if(!isWritable())
- {
- fputs(m_buf, stdout);
- fflush(stdout);
- }
- else
- {
- uv_try_write(m_stream, &m_uvBuf, 1);
- }
+ print(txt);
+}
+
+bool ConsoleLog::isWritable() const
+{
+ return std::cout.good();
+}
+
+void ConsoleLog::print(const std::string & txt)
+{
+ std::cout << txt << std::endl;
+ std::cout.flush();
}
diff --git a/src/log/ConsoleLog.h b/src/log/ConsoleLog.h
index 2eefe6b8..a0c78ebb 100644
--- a/src/log/ConsoleLog.h
+++ b/src/log/ConsoleLog.h
@@ -36,19 +36,14 @@ class ConsoleLog : public ILogBackend
public:
ConsoleLog(bool colors);
- void message(int level, const char* fmt, va_list args) override;
- void text(const char* fmt, va_list args) override;
+ void message(Level level, const std::string & txt) override;
+ void text(const std::string & txt) override;
private:
bool isWritable() const;
- void print(va_list args);
+ void print(const std::string & txt);
bool m_colors;
- char m_buf[512];
- char m_fmt[256];
- uv_buf_t m_uvBuf;
- uv_stream_t* m_stream;
- uv_tty_t m_tty;
};
#endif /* __CONSOLELOG_H__ */
diff --git a/src/log/FileLog.cpp b/src/log/FileLog.cpp
index ddd224c8..d32fe0b2 100644
--- a/src/log/FileLog.cpp
+++ b/src/log/FileLog.cpp
@@ -28,36 +28,37 @@
#include
#include
+#include
+#include
+#include "log/Log.h"
#include "log/FileLog.h"
-
-FileLog::FileLog(const char* fileName)
+FileLog::FileLog(const std::string & fileName)
+ : m_file_name(fileName)
{
- uv_fs_t req;
- m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
- uv_fs_req_cleanup(&req);
}
-
-void FileLog::message(int level, const char* fmt, va_list args)
+void FileLog::message(Level level, const std::string & txt)
{
- if(m_file < 0)
+ if(!isWritable())
{
return;
}
+ //
+ //
time_t now = time(nullptr);
tm stime;
-# ifdef _WIN32
+#ifdef _WIN32
localtime_s(&stime, &now);
-# else
+#else
localtime_r(&now, &stime);
-# endif
+#endif
- char* buf = new char[512];
- int size = snprintf(buf, 23, "[%d-%02d-%02d %02d:%02d:%02d] ",
+ char buf[25];
+ int size = snprintf(buf, sizeof(buf), "[%d-%02d-%02d %02d:%02d:%02d] ",
stime.tm_year + 1900,
stime.tm_mon + 1,
stime.tm_mday,
@@ -65,34 +66,30 @@ void FileLog::message(int level, const char* fmt, va_list args)
stime.tm_min,
stime.tm_sec);
- size = vsnprintf(buf + size, 512 - size - 1, fmt, args) + size;
- buf[size] = '\n';
-
- write(buf, size + 1);
+ //
+ //
+ write(std::string(buf, size) + txt);
}
-
-void FileLog::text(const char* fmt, va_list args)
+void FileLog::text(const std::string & txt)
{
- message(0, fmt, args);
+ if(!isWritable())
+ {
+ return;
+ }
+
+ write(txt);
}
-
-
-void FileLog::onWrite(uv_fs_t* req)
+bool FileLog::isWritable() const
{
- delete [] static_cast(req->data);
-
- uv_fs_req_cleanup(req);
- delete req;
+ return (m_file_name != "") && std::ofstream(m_file_name, std::ios_base::app).good();
}
-
-void FileLog::write(char* data, size_t size)
+void FileLog::write(const std::string & txt)
{
- uv_buf_t buf = uv_buf_init(data, (unsigned int) size);
- uv_fs_t* req = new uv_fs_t;
- req->data = buf.base;
+ std::ofstream outfile;
- uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, 0, FileLog::onWrite);
+ outfile.open(m_file_name, std::ios_base::app);
+ outfile << txt << std::endl;
}
diff --git a/src/log/FileLog.h b/src/log/FileLog.h
index 5ba85013..bac31282 100644
--- a/src/log/FileLog.h
+++ b/src/log/FileLog.h
@@ -24,27 +24,21 @@
#ifndef __FILELOG_H__
#define __FILELOG_H__
-
-#include
-
-
#include "interfaces/ILogBackend.h"
-
class FileLog : public ILogBackend
{
public:
- FileLog(const char* fileName);
+ FileLog(const std::string & fileName);
- void message(int level, const char* fmt, va_list args) override;
- void text(const char* fmt, va_list args) override;
+ void message(Level level, const std::string & txt) override;
+ void text(const std::string & txt) override;
private:
- static void onWrite(uv_fs_t* req);
+ bool isWritable() const;
+ void write(const std::string & txt);
- void write(char* data, size_t size);
-
- int m_file;
+ const std::string m_file_name;
};
#endif /* __FILELOG_H__ */
diff --git a/src/log/Log.cpp b/src/log/Log.cpp
index 8a299eb5..d2b465a1 100644
--- a/src/log/Log.cpp
+++ b/src/log/Log.cpp
@@ -28,50 +28,35 @@
#include
#include
-
#include "interfaces/ILogBackend.h"
#include "log/Log.h"
-
Log* Log::m_self = nullptr;
-
-void Log::message(Log::Level level, const char* fmt, ...)
+void Log::message(ILogBackend::Level level, const std::string & text)
{
- va_list args;
- va_list copy;
- va_start(args, fmt);
-
- for(ILogBackend* backend : m_backends)
+ for(size_t i = 0; i < m_backends.size(); ++i)
{
- va_copy(copy, args);
- backend->message(level, fmt, copy);
- va_end(copy);
+ auto backend = m_backends[i];
+ backend->message(level, text);
}
}
-
-void Log::text(const char* fmt, ...)
+void Log::text(const std::string & text)
{
- va_list args;
- va_list copy;
- va_start(args, fmt);
-
- for(ILogBackend* backend : m_backends)
+ for(size_t i = 0; i < m_backends.size(); ++i)
{
- va_copy(copy, args);
- backend->text(fmt, copy);
- va_end(copy);
+ auto backend = m_backends[i];
+ backend->text(text);
}
- va_end(args);
}
-
Log::~Log()
{
- for(auto backend : m_backends)
+ for(size_t i = 0; i < m_backends.size(); ++i)
{
+ auto backend = m_backends[i];
delete backend;
}
}
diff --git a/src/log/Log.h b/src/log/Log.h
index 7f109b71..c0af6cfa 100644
--- a/src/log/Log.h
+++ b/src/log/Log.h
@@ -24,36 +24,45 @@
#ifndef __LOG_H__
#define __LOG_H__
-
-#include
#include
+#include
-
-class ILogBackend;
-
+#include "interfaces/ILogBackend.h"
class Log
{
public:
- enum Level
+
+ static const std::string & CL_N()
+ {
+ static const std::string kCL_N = "\x1B[0m";
+ return kCL_N;
+ }
+ static const std::string & CL_RED()
+ {
+ static const std::string kCL_RED = "\x1B[31m";
+ return kCL_RED;
+ }
+ static const std::string & CL_YELLOW()
+ {
+ static const std::string kCL_YELLOW = "\x1B[33m";
+ return kCL_YELLOW;
+ }
+ static const std::string & CL_WHITE()
+ {
+ static const std::string kCL_WHITE = "\x1B[01;37m";
+ return kCL_WHITE;
+ }
+ static const std::string & CL_GRAY()
{
- ERR,
- WARNING,
- NOTICE,
- INFO,
- DEBUG
- };
- constexpr static const char* kCL_N = "\x1B[0m";
- constexpr static const char* kCL_RED = "\x1B[31m";
- constexpr static const char* kCL_YELLOW = "\x1B[33m";
- constexpr static const char* kCL_WHITE = "\x1B[01;37m";
-
-# ifdef WIN32
- constexpr static const char* kCL_GRAY = "\x1B[01;30m";
-# else
- constexpr static const char* kCL_GRAY = "\x1B[90m";
-# endif
+#ifdef WIN32
+ static const std::string kCL_GRAY = "\x1B[01;30m";
+#else
+ static const std::string kCL_GRAY = "\x1B[90m";
+#endif
+ return kCL_GRAY;
+ }
static inline Log* i()
{
@@ -75,9 +84,22 @@ public:
delete m_self;
}
- void message(Level level, const char* fmt, ...);
- void text(const char* fmt, ...);
+ void message(ILogBackend::Level level, const std::string & text);
+ void text(const std::string & text);
+ static inline std::string TO_STRING(const std::basic_ostream & i)
+ {
+ const std::ostringstream & stream = static_cast(i);
+ return stream.str();
+ }
+
+ template
+ static inline std::string ToString(const T & i)
+ {
+ std::stringstream stream;
+ stream << i;
+ return stream.str();
+ }
private:
inline Log() {}
~Log();
@@ -87,23 +109,25 @@ private:
};
-#define LOG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__)
-#define LOG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__)
-#define LOG_NOTICE(x, ...) Log::i()->message(Log::NOTICE, x, ##__VA_ARGS__)
-#define LOG_INFO(x, ...) Log::i()->message(Log::INFO, x, ##__VA_ARGS__)
+#define PRINT_MSG(x) Log::i()->text(Log::TO_STRING(std::ostringstream() << " " << x))
+
+#define LOG_ERR(x) Log::i()->message(ILogBackend::ERR, Log::TO_STRING(std::ostringstream() << " " << x))
+#define LOG_WARN(x) Log::i()->message(ILogBackend::WARNING, Log::TO_STRING(std::ostringstream() << " " << x))
+#define LOG_NOTICE(x) Log::i()->message(ILogBackend::NOTICE, Log::TO_STRING(std::ostringstream() << " " << x))
+#define LOG_INFO(x) Log::i()->message(ILogBackend::INFO, Log::TO_STRING(std::ostringstream() << " " << x))
#ifdef APP_DEBUG
-# define LOG_DEBUG(x, ...) Log::i()->message(Log::DEBUG, x, ##__VA_ARGS__)
+#define LOG_DEBUG(x) Log::i()->message(ILogBackend::DEBUG, Log::TO_STRING(std::ostringstream() << " " << x))
#else
-# define LOG_DEBUG(x, ...)
+#define LOG_DEBUG(x)
#endif
#if defined(APP_DEBUG) || defined(APP_DEVEL)
-# define LOG_DEBUG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__)
-# define LOG_DEBUG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__)
+#define LOG_DEBUG_ERR(x) Log::i()->message(ILogBackend::ERR, Log::TO_STRING(std::ostringstream() << " " << x))
+#define LOG_DEBUG_WARN(x) Log::i()->message(ILogBackend::WARNING, Log::TO_STRING(std::ostringstream() << " " << x))
#else
-# define LOG_DEBUG_ERR(x, ...)
-# define LOG_DEBUG_WARN(x, ...)
+#define LOG_DEBUG_ERR(x)
+#define LOG_DEBUG_WARN(x)
#endif
#endif /* __LOG_H__ */
diff --git a/src/log/SysLog.cpp b/src/log/SysLog.cpp
index a29ecd5f..91126ea4 100644
--- a/src/log/SysLog.cpp
+++ b/src/log/SysLog.cpp
@@ -21,6 +21,7 @@
* along with this program. If not, see .
*/
+#ifdef HAVE_SYSLOG_H
#include
@@ -34,14 +35,15 @@ SysLog::SysLog()
openlog(APP_ID, LOG_PID, LOG_USER);
}
-
-void SysLog::message(int level, const char* fmt, va_list args)
+void SysLog::text(const std::string & txt)
{
- vsyslog(level, fmt, args);
+ message(INFO, txt);
}
-void SysLog::text(const char* fmt, va_list args)
+void SysLog::message(Level level, const std::string & txt)
{
- message(LOG_INFO, fmt, args);
+ syslog(level == INFO ? LOG_INFO : LOG_NOTICE, "%s", txt.c_str());
}
+
+#endif
\ No newline at end of file
diff --git a/src/log/SysLog.h b/src/log/SysLog.h
index 13c13f78..771e36d2 100644
--- a/src/log/SysLog.h
+++ b/src/log/SysLog.h
@@ -33,8 +33,8 @@ class SysLog : public ILogBackend
public:
SysLog();
- void message(int level, const char* fmt, va_list args) override;
- void text(const char* fmt, va_list args) override;
+ void message(Level level, const std::string & txt) override;
+ void text(const std::string & txt) override;
};
#endif /* __SYSLOG_BACKEND_H__ */
diff --git a/src/net/Client.cpp b/src/net/Client.cpp
index 200469ac..f669c152 100644
--- a/src/net/Client.cpp
+++ b/src/net/Client.cpp
@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones
* Copyright 2014-2016 Wolf9466
* Copyright 2016 Jay D Dee
- * Copyright 2017-2018 XMR-Stak ,
- * Copyright 2016-2018 XMRig ,
+ * Copyright 2016-2018 XMRig
+ *
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,26 +37,26 @@
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
-
#ifdef XMRIG_PROXY_PROJECT
-# include "proxy/JobResult.h"
+#include "proxy/JobResult.h"
#else
-# include "net/JobResult.h"
+#include "net/JobResult.h"
#endif
#ifdef _MSC_VER
-# define strncasecmp(x,y,z) _strnicmp(x,y,z)
+#define strncasecmp(x,y,z) _strnicmp(x,y,z)
#endif
int64_t Client::m_sequence = 1;
-Client::Client(int id, const char* agent, IClientListener* listener) :
+Client::Client(int id, const std::string & agent, IClientListener* listener) :
m_ipv6(false),
m_nicehash(false),
m_quiet(false),
+ m_encrypted(false),
m_agent(agent),
m_listener(listener),
m_id(id),
@@ -68,8 +68,8 @@ Client::Client(int id, const char* agent, IClientListener* listener) :
m_stream(nullptr),
m_socket(nullptr)
{
- memset(m_ip, 0, sizeof(m_ip));
memset(&m_hints, 0, sizeof(m_hints));
+ memset(m_keystream, 0, sizeof(m_keystream));
m_resolver.data = this;
@@ -80,10 +80,10 @@ Client::Client(int id, const char* agent, IClientListener* listener) :
m_recvBuf.base = m_buf;
m_recvBuf.len = sizeof(m_buf);
-# ifndef XMRIG_PROXY_PROJECT
+#ifndef XMRIG_PROXY_PROJECT
m_keepAliveTimer.data = this;
uv_timer_init(uv_default_loop(), &m_keepAliveTimer);
-# endif
+#endif
}
@@ -104,20 +104,30 @@ void Client::connect()
*
* @param url
*/
-void Client::connect(const Url* url)
+void Client::connect(const Url & url)
{
setUrl(url);
resolve(m_url.host());
}
-void Client::setUrl(const Url* url)
+void Client::setUrl(const Url & url)
{
- if(!url || !url->isValid())
+ if(false == url.isValid())
{
return;
}
+ if(url.hasKeystream())
+ {
+ url.copyKeystream(m_keystream, sizeof(m_keystream));
+ m_encrypted = true;
+ }
+ else
+ {
+ m_encrypted = false;
+ }
+
m_url = url;
}
@@ -131,7 +141,7 @@ void Client::tick(uint64_t now)
if(m_state == ConnectedState)
{
- LOG_DEBUG_ERR("[%s:%u] timeout", m_url.host(), m_url.port());
+ LOG_DEBUG_ERR("[" << m_url.host() << ":" << m_url.port() << "] timeout");
close();
}
@@ -142,12 +152,11 @@ void Client::tick(uint64_t now)
}
}
-
bool Client::disconnect()
{
-# ifndef XMRIG_PROXY_PROJECT
+#ifndef XMRIG_PROXY_PROJECT
uv_timer_stop(&m_keepAliveTimer);
-# endif
+#endif
m_expire = 0;
m_failures = -1;
@@ -158,24 +167,29 @@ bool Client::disconnect()
int64_t Client::submit(const JobResult & result)
{
-# ifdef XMRIG_PROXY_PROJECT
- const char* nonce = result.nonce;
- const char* data = result.result;
-# else
- char nonce[9];
- char data[65];
+#ifdef XMRIG_PROXY_PROJECT
+ const std::string nonce = result.nonce;
+ const std::string data = result.result;
+#else
+ char nonce_buffer[9];
+ char data_buffer[65];
- Job::toHex(reinterpret_cast(&result.nonce), 4, nonce);
- nonce[8] = '\0';
+ char* nonceChar = (char*)(&result.nonce);
+ Job::toHex(std::string(nonceChar, 4), nonce_buffer);
+ nonce_buffer[8] = '\0';
- Job::toHex(result.result, 32, data);
- data[64] = '\0';
-# endif
+ char* resultChar = (char*)(&result.result);
+ Job::toHex(std::string(resultChar, 32), data_buffer);
+ data_buffer[64] = '\0';
+
+ const std::string nonce = nonce_buffer;
+ const std::string data = data_buffer;
+#endif
const size_t size = snprintf(m_sendBuf, sizeof(m_sendBuf),
"{\"id\":%" PRIu64
",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
- m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data);
+ m_sequence, m_rpcId.data().c_str(), result.jobId.data().c_str(), nonce.c_str(), data.c_str());
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
return send(size);
@@ -200,24 +214,24 @@ bool Client::close()
}
-bool Client::isCriticalError(const char* message)
+bool Client::isCriticalError(const std::string & message)
{
- if(!message)
+ if(message.empty())
{
return false;
}
- if(strncasecmp(message, "Unauthenticated", 15) == 0)
+ if(message == "Unauthenticated")
{
return true;
}
- if(strncasecmp(message, "your IP is banned", 17) == 0)
+ if(message == "your IP is banned")
{
return true;
}
- if(strncasecmp(message, "IP Address currently banned", 27) == 0)
+ if(message == "IP Address currently banned")
{
return true;
}
@@ -267,7 +281,7 @@ bool Client::parseJob(const rapidjson::Value & params, int* code)
{
if(!m_quiet)
{
- LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
+ LOG_WARN("[" << m_url.host() << ":" << m_url.port() << "] duplicate job received, reconnect");
}
close();
@@ -289,6 +303,14 @@ bool Client::parseLogin(const rapidjson::Value & result, int* code)
m_nicehash = m_url.isNicehash();
+ const rapidjson::Value & keystream = result["keystream"];
+ if(true == keystream.IsString())
+ {
+ const std::string newkeystream = keystream.GetString();
+ memcpy(m_keystream, newkeystream.c_str(), std::min(sizeof(m_keystream), newkeystream.size()));
+ m_encrypted = true;
+ }
+
if(result.HasMember("extensions"))
{
parseExtensions(result["extensions"]);
@@ -298,7 +320,7 @@ bool Client::parseLogin(const rapidjson::Value & result, int* code)
}
-int Client::resolve(const char* host)
+int Client::resolve(const std::string & host)
{
setState(HostLookupState);
@@ -310,12 +332,12 @@ int Client::resolve(const char* host)
m_failures = 0;
}
- const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints);
+ const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host.c_str(), NULL, &m_hints);
if(r)
{
if(!m_quiet)
{
- LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r));
+ LOG_ERR("[" << host << ":" << m_url.port() << "] getaddrinfo error: \"" << uv_strerror(r) << "\"");
}
return 1;
}
@@ -324,15 +346,33 @@ int Client::resolve(const char* host)
}
-int64_t Client::send(size_t size)
+int64_t Client::send(size_t size, const bool encrypted)
{
- LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), size, m_sendBuf);
- if(state() != ConnectedState || !uv_is_writable(m_stream))
+ LOG_DEBUG("[" << m_url.host() << ":" << m_url.port() << "] send(" << size << " bytes): \"" << m_sendBuf <<
+ "\"");
+ if((state() != ConnectedState && state() != ProxingState) || !uv_is_writable(m_stream))
{
- LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_url.host(), m_url.port(), m_state);
+ LOG_DEBUG_ERR("[" << m_url.host() << ":" << m_url.port() << "] send failed, invalid state: " << m_state);
return -1;
}
+ if(encrypted && m_encrypted)
+ {
+ // Encrypt
+ for(size_t i = 0; i < std::min(size, sizeof(SendBuf)); ++i)
+ {
+ m_sendBuf[i] ^= m_keystream[i];
+ }
+
+ char* send_encr_hex = static_cast(malloc(size * 2 + 1));
+ memset(send_encr_hex, 0, size * 2 + 1);
+ Job::toHex(std::string(m_sendBuf, size), send_encr_hex);
+ send_encr_hex[size * 2] = '\0';
+ LOG_DEBUG("[" << m_url.host() << ":" << m_url.port() << "] send encr.(" << size << " bytes): \"0x" <<
+ send_encr_hex << "\"");
+ free(send_encr_hex);
+ }
+
uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size);
if(uv_try_write(m_stream, &buf, 1) < 0)
@@ -354,19 +394,19 @@ void Client::connect(const std::vector & ipv4, const std::vector(addr->ai_addr), m_ip, 45);
+ uv_ip6_name(reinterpret_cast(addr->ai_addr), (char*)m_ip.c_str(), 45);
}
else
{
addr = ipv4[ipv4.size() == 1 ? 0 : rand() % ipv4.size()];
- uv_ip4_name(reinterpret_cast(addr->ai_addr), m_ip, 16);
+ uv_ip4_name(reinterpret_cast(addr->ai_addr), (char*)m_ip.c_str(), 16);
}
connect(addr->ai_addr);
}
-void Client::connect(sockaddr* addr)
+void Client::connect(struct sockaddr* addr)
{
setState(ConnectingState);
@@ -382,13 +422,35 @@ void Client::connect(sockaddr* addr)
uv_tcp_init(uv_default_loop(), m_socket);
uv_tcp_nodelay(m_socket, 1);
-# ifndef WIN32
+#ifndef WIN32
uv_tcp_keepalive(m_socket, 1, 60);
-# endif
+#endif
uv_tcp_connect(req, m_socket, reinterpret_cast(addr), Client::onConnect);
}
+void Client::prelogin()
+{
+ if(m_url.isProxyed())
+ {
+ setState(ProxingState);
+ const std::string buffer = std::string("CONNECT ") + m_url.finalHost() + ":" +
+ std::to_string((unsigned long long)(m_url.finalPort())) + " HTTP/1.1\n";
+
+ const size_t size = buffer.size();
+ memcpy(m_sendBuf, buffer.c_str(), size);
+ m_sendBuf[size] = '\n';
+ m_sendBuf[size + 1] = '\0';
+
+ LOG_DEBUG("Prelogin send (" << size << " bytes): \"" << m_sendBuf << "\"");
+ send(size + 1, false);
+ }
+ else
+ {
+ setState(ConnectedState);
+ login();
+ }
+}
void Client::login()
{
@@ -404,9 +466,9 @@ void Client::login()
doc.AddMember("method", "login", allocator);
rapidjson::Value params(rapidjson::kObjectType);
- params.AddMember("login", rapidjson::StringRef(m_url.user()), allocator);
- params.AddMember("pass", rapidjson::StringRef(m_url.password()), allocator);
- params.AddMember("agent", rapidjson::StringRef(m_agent), allocator);
+ params.AddMember("login", rapidjson::StringRef(m_url.user().c_str()), allocator);
+ params.AddMember("pass", rapidjson::StringRef(m_url.password().c_str()), allocator);
+ params.AddMember("agent", rapidjson::StringRef(m_agent.c_str()), allocator);
doc.AddMember("params", params, allocator);
@@ -434,11 +496,12 @@ void Client::parse(char* line, size_t len)
line[len - 1] = '\0';
- LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line);
+ LOG_DEBUG("[" << m_url.host() << ":" << m_url.port() << "] received (" << len << " bytes): \"" << line <<
+ "\"");
if(len < 32 || line[0] != '{')
{
- LOG_ERR("[%s:%u] JSON decode failed", m_url.host(), m_url.port());
+ LOG_ERR("[" << m_url.host() << ":" << m_url.port() << "] JSON decode failed");
return;
}
@@ -447,8 +510,8 @@ void Client::parse(char* line, size_t len)
{
if(!m_quiet)
{
- LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(),
- rapidjson::GetParseError_En(doc.GetParseError()));
+ LOG_ERR("[" << m_url.host() << ":" << m_url.port() << "] JSON decode failed: \"" <<
+ rapidjson::GetParseError_En(doc.GetParseError()) << "\"");
}
return;
@@ -478,8 +541,9 @@ void Client::parseExtensions(const rapidjson::Value & value)
return;
}
- for(const rapidjson::Value & ext : value.GetArray())
+ for(size_t i = 0; i < value.GetArray().Size(); ++i)
{
+ const rapidjson::Value & ext = value.GetArray()[i];
if(!ext.IsString())
{
continue;
@@ -493,25 +557,25 @@ void Client::parseExtensions(const rapidjson::Value & value)
}
-void Client::parseNotification(const char* method, const rapidjson::Value & params,
+void Client::parseNotification(const std::string & method, const rapidjson::Value & params,
const rapidjson::Value & error)
{
if(error.IsObject())
{
if(!m_quiet)
{
- LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), error["message"].GetString(),
- error["code"].GetInt());
+ LOG_ERR("[" << m_url.host() << ":" << m_url.port() << "] error: \"" << error["message"].GetString() <<
+ "\", code: " << error["code"].GetInt());
}
return;
}
- if(!method)
+ if(0 == method.size())
{
return;
}
- if(strcmp(method, "job") == 0)
+ if(method == "job")
{
int code = -1;
if(parseJob(params, &code))
@@ -522,7 +586,7 @@ void Client::parseNotification(const char* method, const rapidjson::Value & para
return;
}
- LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_url.host(), m_url.port(), method);
+ LOG_WARN("[" << m_url.host() << ":" << m_url.port() << "] unsupported method: \"" << method << "\"");
}
@@ -530,7 +594,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value & result, const ra
{
if(error.IsObject())
{
- const char* message = error["message"].GetString();
+ const std::string message = error["message"].GetString();
auto it = m_results.find(id);
if(it != m_results.end())
@@ -541,7 +605,8 @@ void Client::parseResponse(int64_t id, const rapidjson::Value & result, const ra
}
else if(!m_quiet)
{
- LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), message, error["code"].GetInt());
+ LOG_ERR("[" << m_url.host() << ":" << m_url.port() << "] error: \"" << message << "\", code: " <<
+ error["code"].GetInt());
}
if(id == 1 || isCriticalError(message))
@@ -564,7 +629,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value & result, const ra
{
if(!m_quiet)
{
- LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code);
+ LOG_ERR("[" << m_url.host() << ":" << m_url.port() << "] login error code: " << code);
}
close();
@@ -581,7 +646,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value & result, const ra
if(it != m_results.end())
{
it->second.done();
- m_listener->onResultAccepted(this, it->second, nullptr);
+ m_listener->onResultAccepted(this, it->second, "");
m_results.erase(it);
}
}
@@ -590,27 +655,27 @@ void Client::parseResponse(int64_t id, const rapidjson::Value & result, const ra
void Client::ping()
{
send(snprintf(m_sendBuf, sizeof(m_sendBuf),
- "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence,
- m_rpcId.data()));
+ "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n",
+ m_sequence, m_rpcId.data().c_str()));
}
void Client::reconnect()
{
- setState(ConnectingState);
-
-# ifndef XMRIG_PROXY_PROJECT
- if(m_url.isKeepAlive())
- {
- uv_timer_stop(&m_keepAliveTimer);
- }
-# endif
-
if(m_failures == -1)
{
return m_listener->onClose(this, -1);
}
+ setState(ConnectingState);
+
+#ifndef XMRIG_PROXY_PROJECT
+ if(m_url.isKeepAlive())
+ {
+ uv_timer_stop(&m_keepAliveTimer);
+ }
+#endif
+
m_failures++;
m_listener->onClose(this, (int) m_failures);
@@ -620,7 +685,7 @@ void Client::reconnect()
void Client::setState(SocketState state)
{
- LOG_DEBUG("[%s:%u] state: %d", m_url.host(), m_url.port(), state);
+ LOG_DEBUG("[" << m_url.host() << ":" << m_url.port() << "] state: " << state);
if(m_state == state)
{
@@ -635,26 +700,27 @@ void Client::startTimeout()
{
m_expire = 0;
-# ifndef XMRIG_PROXY_PROJECT
+#ifndef XMRIG_PROXY_PROJECT
if(!m_url.isKeepAlive())
{
return;
}
- uv_timer_start(&m_keepAliveTimer, [](uv_timer_t* handle)
- {
- getClient(handle->data)->ping();
- }, kKeepAliveTimeout, 0);
-# endif
+ uv_timer_start(&m_keepAliveTimer, &Client::onTimeout, kKeepAliveTimeout, 0);
+#endif
}
+void Client::onTimeout(uv_timer_t* handle)
+{
+ getClient(handle->data)->ping();
+}
void Client::onAllocBuffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
{
auto client = getClient(handle->data);
buf->base = &client->m_recvBuf.base[client->m_recvBufPos];
- buf->len = client->m_recvBuf.len - client->m_recvBufPos;
+ buf->len = client->m_recvBuf.len - (unsigned long)client->m_recvBufPos;
}
@@ -679,7 +745,8 @@ void Client::onConnect(uv_connect_t* req, int status)
{
if(!client->m_quiet)
{
- LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
+ LOG_ERR("[" << client->m_url.host() << ":" << client->m_url.port() << "] connect error: \"" << uv_strerror(
+ status) << "\"");
}
delete req;
@@ -689,12 +756,11 @@ void Client::onConnect(uv_connect_t* req, int status)
client->m_stream = static_cast(req->handle);
client->m_stream->data = req->data;
- client->setState(ConnectedState);
uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead);
delete req;
- client->login();
+ client->prelogin();
}
@@ -705,25 +771,57 @@ void Client::onRead(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
{
if(nread != UV_EOF && !client->m_quiet)
{
- LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror((int) nread));
+ LOG_ERR("[" << client->m_url.host() << ":" << client->m_url.port() << "] read error: \"" << uv_strerror((
+ int) nread) << "\"");
}
client->close();
return;
}
- if((size_t) nread > (sizeof(m_buf) - 8 - client->m_recvBufPos))
+ if((size_t) nread > (sizeof(Buf) - 8 - client->m_recvBufPos))
{
client->close();
return;
}
+ if(client->state() == ProxingState)
+ {
+ const char* const content = buf->base;
+ LOG_DEBUG("[" << client->m_url.host() << ":" << client->m_url.port() << "] received from proxy (" << nread <<
+ " bytes): \"" << content << "\"");
+
+ if(content == strstr(content, "HTTP/1.1 200"))
+ {
+ LOG_INFO("[" << client->m_url.host() << ":" << client->m_url.port() << "] Proxy connected to " <<
+ client->m_url.finalHost() << ":" << client->m_url.finalPort() << "!");
+ client->setState(ConnectedState);
+ client->login();
+ }
+ return;
+ }
+
client->m_recvBufPos += nread;
char* end;
char* start = client->m_recvBuf.base;
size_t remaining = client->m_recvBufPos;
+ if(client->m_encrypted)
+ {
+ char* read_encr_hex = static_cast(malloc(nread * 2 + 1));
+ memset(read_encr_hex, 0, nread * 2 + 1);
+ Job::toHex(std::string(start, nread), read_encr_hex);
+ LOG_DEBUG("[" << client->m_ip << "] read encr. (" << nread << " bytes): \"0x" << read_encr_hex << "\"");
+ free(read_encr_hex);
+
+ // DeEncrypt
+ for(int i = 0; i < (int)nread; ++i)
+ {
+ start[i] ^= client->m_keystream[i];
+ }
+ }
+
while((end = static_cast(memchr(start, '\n', remaining))) != nullptr)
{
end++;
@@ -755,7 +853,8 @@ void Client::onResolved(uv_getaddrinfo_t* req, int status, struct addrinfo* res)
auto client = getClient(req->data);
if(status < 0)
{
- LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
+ LOG_ERR("[" << client->m_url.host() << ":" << client->m_url.port() << "] DNS error: \"" << uv_strerror(
+ status) << "\"");
return client->reconnect();
}
@@ -780,8 +879,8 @@ void Client::onResolved(uv_getaddrinfo_t* req, int status, struct addrinfo* res)
if(ipv4.empty() && ipv6.empty())
{
- LOG_ERR("[%s:%u] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_url.host(),
- client->m_url.port());
+ LOG_ERR("[" << client->m_url.host() << ":" << client->m_url.port() <<
+ "] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"");
uv_freeaddrinfo(res);
return client->reconnect();
diff --git a/src/net/Client.h b/src/net/Client.h
index 36c369f2..c5ec8e8b 100644
--- a/src/net/Client.h
+++ b/src/net/Client.h
@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones
* Copyright 2014-2016 Wolf9466
* Copyright 2016 Jay D Dee
- * Copyright 2017-2018 XMR-Stak ,
- * Copyright 2016-2018 XMRig ,
+ * Copyright 2016-2017 XMRig
+ *
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,12 +25,11 @@
#define __CLIENT_H__
+#include
#include