mirror of
https://github.com/xmrig/xmrig.git
synced 2025-12-06 23:52:38 -05:00
Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bcfd0cdea | ||
|
|
9396ecf93d | ||
|
|
a4af964696 | ||
|
|
2c8d8ee2ab | ||
|
|
631a8ca802 | ||
|
|
346892e170 | ||
|
|
db03573804 | ||
|
|
e74573f81f | ||
|
|
0e70974d7d | ||
|
|
3a3ee91324 | ||
|
|
4108428872 | ||
|
|
4c3425a958 | ||
|
|
09624c4f9b | ||
|
|
8faef28e7d | ||
|
|
62450f4ed8 | ||
|
|
2c52a5a352 | ||
|
|
7d52bd7454 | ||
|
|
f68b105bd9 | ||
|
|
9ca1a6129b | ||
|
|
7a3df1c0bb | ||
|
|
22a1b8d82d | ||
|
|
0a462fbef5 | ||
|
|
f302b4b0ef | ||
|
|
65fe26dc6c | ||
|
|
e6d4921e21 | ||
|
|
f82d67e76e | ||
|
|
4e671a945d | ||
|
|
e38d277143 | ||
|
|
8eb9b4d37a | ||
|
|
2d45cc64c1 | ||
|
|
b9081e992b | ||
|
|
1424b2975f | ||
|
|
0fa5db8fa3 | ||
|
|
5999dccd57 | ||
|
|
78922a0772 | ||
|
|
bc3914883a | ||
|
|
86dae9e149 | ||
|
|
05b2260393 | ||
|
|
672f6df6c1 | ||
|
|
9dae559b73 | ||
|
|
b9d813c403 | ||
|
|
c48e2e6af8 | ||
|
|
76fba819fe | ||
|
|
6bab624885 | ||
|
|
3730bcd434 | ||
|
|
3b7d30a91d | ||
|
|
c8588903e3 | ||
|
|
0b4fec15dd | ||
|
|
ef8cc28f3f | ||
|
|
8471f7fad3 | ||
|
|
b99dc440af | ||
|
|
9a02007900 | ||
|
|
efc5e5d811 | ||
|
|
dea5be0a57 | ||
|
|
24c290963a | ||
|
|
9dffcdaddd | ||
|
|
3df47052ed | ||
|
|
3b8d081c8c | ||
|
|
05e6f66169 | ||
|
|
11e0d3de3a | ||
|
|
ea367da064 | ||
|
|
a999a56775 | ||
|
|
590252bd5e | ||
|
|
cc2de4f768 | ||
|
|
aeea0e0a6c | ||
|
|
82d698a1e5 | ||
|
|
95b2b5e028 | ||
|
|
eae84d47e7 | ||
|
|
45d12314f4 | ||
|
|
fa11cb623d | ||
|
|
7da04c6a2c | ||
|
|
5c449913af | ||
|
|
af019fed8e | ||
|
|
8872630c46 |
19
CHANGELOG.md
19
CHANGELOG.md
@@ -1,3 +1,22 @@
|
||||
# v6.8.1
|
||||
- [#2064](https://github.com/xmrig/xmrig/pull/2064) Added documentation for config.json CPU options.
|
||||
- [#2066](https://github.com/xmrig/xmrig/issues/2066) Fixed AMD GPUs health data readings on Linux.
|
||||
- [#2067](https://github.com/xmrig/xmrig/pull/2067) Fixed compilation error when RandomX and Argon2 are disabled.
|
||||
- [#2076](https://github.com/xmrig/xmrig/pull/2076) Added support for flexible huge page sizes on Linux.
|
||||
- [#2077](https://github.com/xmrig/xmrig/pull/2077) Fixed `illegal instruction` crash on ARM.
|
||||
|
||||
# v6.8.0
|
||||
- [#2052](https://github.com/xmrig/xmrig/pull/2052) Added DMI/SMBIOS reader.
|
||||
- Added information about memory modules on the miner startup and for online benchmark.
|
||||
- Added new HTTP API endpoint: `GET /2/dmi`.
|
||||
- Added new command line option `--no-dmi` or config option `"dmi"`.
|
||||
- Added new CMake option `-DWITH_DMI=OFF`.
|
||||
- [#2057](https://github.com/xmrig/xmrig/pull/2057) Improved MSR subsystem code quality.
|
||||
- [#2058](https://github.com/xmrig/xmrig/pull/2058) RandomX JIT x86: removed unnecessary instructions.
|
||||
|
||||
# v6.7.2
|
||||
- [#2039](https://github.com/xmrig/xmrig/pull/2039) Fixed solo mining.
|
||||
|
||||
# v6.7.1
|
||||
- [#1995](https://github.com/xmrig/xmrig/issues/1995) Fixed log initialization.
|
||||
- [#1998](https://github.com/xmrig/xmrig/pull/1998) Added hashrate in the benchmark finished message.
|
||||
|
||||
@@ -26,6 +26,7 @@ option(WITH_PROFILING "Enable profiling for developers" OFF)
|
||||
option(WITH_SSE4_1 "Enable SSE 4.1 for Blake2" ON)
|
||||
option(WITH_BENCHMARK "Enable builtin RandomX benchmark and stress test" ON)
|
||||
option(WITH_SECURE_JIT "Enable secure access to JIT memory" OFF)
|
||||
option(WITH_DMI "Enable DMI/SMBIOS reader" ON)
|
||||
|
||||
option(BUILD_STATIC "Build static binary" OFF)
|
||||
option(ARM_TARGET "Force use specific ARM target 8 or 7" 0)
|
||||
@@ -169,7 +170,7 @@ else()
|
||||
endif()
|
||||
|
||||
add_definitions(-DXMRIG_MINER_PROJECT -DXMRIG_JSON_SINGLE_LINE_ARRAY)
|
||||
add_definitions(-D__STDC_FORMAT_MACROS -DUNICODE)
|
||||
add_definitions(-D__STDC_FORMAT_MACROS -DUNICODE -D_FILE_OFFSET_BITS=64)
|
||||
|
||||
find_package(UV REQUIRED)
|
||||
|
||||
@@ -197,6 +198,9 @@ if (WITH_EMBEDDED_CONFIG)
|
||||
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
|
||||
endif()
|
||||
|
||||
include(src/hw/api/api.cmake)
|
||||
include(src/hw/dmi/dmi.cmake)
|
||||
|
||||
include_directories(src)
|
||||
include_directories(src/3rdparty)
|
||||
include_directories(${UV_INCLUDE_DIR})
|
||||
|
||||
@@ -100,13 +100,29 @@ if (WITH_RANDOMX)
|
||||
message("-- WITH_MSR=ON")
|
||||
|
||||
if (XMRIG_OS_WIN)
|
||||
list(APPEND SOURCES_CRYPTO src/crypto/rx/Rx_win.cpp)
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/rx/RxFix_win.cpp
|
||||
src/hw/msr/Msr_win.cpp
|
||||
)
|
||||
elseif (XMRIG_OS_LINUX)
|
||||
list(APPEND SOURCES_CRYPTO src/crypto/rx/Rx_linux.cpp)
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/rx/RxFix_linux.cpp
|
||||
src/hw/msr/Msr_linux.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND HEADERS_CRYPTO src/crypto/rx/msr/MsrItem.h)
|
||||
list(APPEND SOURCES_CRYPTO src/crypto/rx/msr/MsrItem.cpp)
|
||||
list(APPEND HEADERS_CRYPTO
|
||||
src/crypto/rx/RxFix.h
|
||||
src/crypto/rx/RxMsr.h
|
||||
src/hw/msr/Msr.h
|
||||
src/hw/msr/MsrItem.h
|
||||
)
|
||||
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/rx/RxMsr.cpp
|
||||
src/hw/msr/Msr.cpp
|
||||
src/hw/msr/MsrItem.cpp
|
||||
)
|
||||
else()
|
||||
remove_definitions(/DXMRIG_FEATURE_MSR)
|
||||
remove_definitions(/DXMRIG_FIX_RYZEN)
|
||||
|
||||
54
doc/CPU.md
54
doc/CPU.md
@@ -75,6 +75,35 @@ Each number represent one thread and means CPU affinity, this is default format
|
||||
```
|
||||
Internal format, but can be user defined.
|
||||
|
||||
## RandomX options
|
||||
|
||||
#### `init`
|
||||
Thread count to initialize RandomX dataset. Auto-detect (`-1`) or any number greater than 0 to use that many threads.
|
||||
|
||||
#### `init-avx2`
|
||||
Use AVX2 for dataset initialization. Faster on some CPUs. Auto-detect (`-1`), disabled (`0`), always enabled on CPUs that support AVX2 (`1`).
|
||||
|
||||
#### `mode`
|
||||
RandomX mining mode: `auto`, `fast` (2 GB memory), `light` (256 MB memory).
|
||||
|
||||
#### `1gb-pages`
|
||||
Use 1GB hugepages for RandomX dataset (Linux only). Enabled (`true`) or disabled (`false`). It gives 1-3% speedup.
|
||||
|
||||
#### `rdmsr`
|
||||
Restore MSR register values to their original values on exit. Used together with `wrmsr`. Enabled (`true`) or disabled (`false`).
|
||||
|
||||
#### `wrmsr`
|
||||
[MSR mod](https://xmrig.com/docs/miner/randomx-optimization-guide/msr). Enabled (`true`) or disabled (`false`). It gives up to 15% speedup depending on your system.
|
||||
|
||||
#### `cache_qos`
|
||||
[Cache QoS](https://xmrig.com/docs/miner/randomx-optimization-guide/qos). Enabled (`true`) or disabled (`false`). It's useful when you can't or don't want to mine on all CPU cores to make mining hashrate more stable.
|
||||
|
||||
#### `numa`
|
||||
NUMA support (better hashrate on multi-CPU servers and Ryzen Threadripper 1xxx/2xxx). Enabled (`true`) or disabled (`false`).
|
||||
|
||||
#### `scratchpad_prefetch_mode`
|
||||
Which instruction to use in RandomX loop to prefetch data from scratchpad. `1` is default and fastest in most cases. Can be off (`0`), `prefetcht0` instruction (`1`), `prefetchnta` instruction (`2`, a bit faster on Coffee Lake and a few other CPUs), `mov` instruction (`3`).
|
||||
|
||||
## Shared options
|
||||
|
||||
#### `enabled`
|
||||
@@ -83,23 +112,32 @@ Enable (`true`) or disable (`false`) CPU backend, by default `true`.
|
||||
#### `huge-pages`
|
||||
Enable (`true`) or disable (`false`) huge pages support, by default `true`.
|
||||
|
||||
#### `huge-pages-jit`
|
||||
Enable (`true`) or disable (`false`) huge pages support for RandomX JIT code, by default `false`. It gives a very small boost on Ryzen CPUs, but hashrate is unstable between launches. Use with caution.
|
||||
|
||||
#### `hw-aes`
|
||||
Force enable (`true`) or disable (`false`) hardware AES support. Default value `null` means miner autodetect this feature. Usually don't need change this option, this option useful for some rare cases when miner can't detect hardware AES, but it available. If you force enable this option, but your hardware not support it, miner will crash.
|
||||
|
||||
#### `priority`
|
||||
Mining threads priority, value from `1` (lowest priority) to `5` (highest possible priority). Default value `null` means miner don't change threads priority at all.
|
||||
Mining threads priority, value from `1` (lowest priority) to `5` (highest possible priority). Default value `null` means miner don't change threads priority at all. Setting priority higher than 2 can make your PC unresponsive.
|
||||
|
||||
#### `memory-pool` (since v4.3.0)
|
||||
Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm swithing. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages. It helps to avoid loosing huge pages for scratchpads when RandomX dataset is updated and mining threads restart after a 2-3 days of mining.
|
||||
|
||||
#### `yield` (since v5.1.1)
|
||||
Prefer system better system response/stability `true` (default value) or maximum hashrate `false`.
|
||||
|
||||
#### `asm`
|
||||
Enable/configure or disable ASM optimizations. Possible values: `true`, `false`, `"intel"`, `"ryzen"`, `"bulldozer"`.
|
||||
|
||||
#### `argon2-impl` (since v3.1.0)
|
||||
Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards, if you CPU not support required instuctions, miner will crash.
|
||||
Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. This is used in RandomX dataset initialization and also in some other mining algorithms. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards - if your CPU doesn't support required instuctions, miner will crash.
|
||||
|
||||
#### `astrobwt-max-size`
|
||||
AstroBWT algorithm: skip hashes with large stage 2 size, default: `550`, min: `400`, max: `1200`. Optimal value depends on your CPU/GPU
|
||||
|
||||
#### `astrobwt-avx2`
|
||||
AstroBWT algorithm: use AVX2 code. It's faster on some CPUs and slower on other
|
||||
|
||||
#### `max-threads-hint` (since v4.2.0)
|
||||
Maximum CPU threads count (in percentage) hint for autoconfig. [CPU_MAX_USAGE.md](CPU_MAX_USAGE.md)
|
||||
|
||||
#### `memory-pool` (since v4.3.0)
|
||||
Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm swithing. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages.
|
||||
|
||||
#### `yield` (since v5.1.1)
|
||||
Prefer system better system response/stability `true` (default value) or maximum hashrate `false`.
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -39,6 +39,11 @@
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_DMI
|
||||
# include "hw/dmi/DmiReader.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_ALGO_RANDOMX
|
||||
# include "crypto/rx/RxConfig.h"
|
||||
#endif
|
||||
@@ -71,7 +76,7 @@ inline static const char *asmName(Assembly::Id assembly)
|
||||
#endif
|
||||
|
||||
|
||||
static void print_memory(Config *config)
|
||||
static void print_pages(const Config *config)
|
||||
{
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
|
||||
"HUGE PAGES", config->cpu().isHugePages() ? (VirtualMemory::isHugepagesAvailable() ? kHugepagesSupported : RED_BOLD("unavailable")) : RED_BOLD("disabled"));
|
||||
@@ -87,7 +92,7 @@ static void print_memory(Config *config)
|
||||
}
|
||||
|
||||
|
||||
static void print_cpu(Config *)
|
||||
static void print_cpu(const Config *)
|
||||
{
|
||||
const auto info = Cpu::info();
|
||||
|
||||
@@ -116,7 +121,7 @@ static void print_cpu(Config *)
|
||||
}
|
||||
|
||||
|
||||
static void print_memory()
|
||||
static void print_memory(const Config *config)
|
||||
{
|
||||
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
|
||||
const auto freeMem = static_cast<double>(uv_get_free_memory());
|
||||
@@ -124,16 +129,49 @@ static void print_memory()
|
||||
|
||||
const double percent = freeMem > 0 ? ((totalMem - freeMem) / totalMem * 100.0) : 100.0;
|
||||
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%.1f/%.1f GB") BLACK_BOLD(" (%.0f%%)"),
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%.1f/%.1f") CYAN(" GB") BLACK_BOLD(" (%.0f%%)"),
|
||||
"MEMORY",
|
||||
(totalMem - freeMem) / oneGiB,
|
||||
totalMem / oneGiB,
|
||||
percent
|
||||
);
|
||||
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
if (!config->isDMI()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DmiReader reader;
|
||||
if (!reader.read()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool printEmpty = reader.memory().size() <= 8;
|
||||
|
||||
for (const auto &memory : reader.memory()) {
|
||||
if (!memory.isValid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (memory.size()) {
|
||||
Log::print(WHITE_BOLD(" %-13s") "%s: " CYAN_BOLD("%" PRIu64) CYAN(" GB ") WHITE_BOLD("%s @ %" PRIu64 " MHz ") BLACK_BOLD("%s"),
|
||||
"", memory.id().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data());
|
||||
}
|
||||
else if (printEmpty) {
|
||||
Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data());
|
||||
}
|
||||
}
|
||||
|
||||
const auto &board = Cpu::info()->isVM() ? reader.system() : reader.board();
|
||||
|
||||
if (board.isValid()) {
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") " - " WHITE_BOLD("%s"), "MOTHERBOARD", board.vendor().data(), board.product().data());
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
static void print_threads(Config *config)
|
||||
static void print_threads(const Config *config)
|
||||
{
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s%d%%"),
|
||||
"DONATE",
|
||||
@@ -175,14 +213,16 @@ static void print_commands(Config *)
|
||||
|
||||
void xmrig::Summary::print(Controller *controller)
|
||||
{
|
||||
controller->config()->printVersions();
|
||||
print_memory(controller->config());
|
||||
print_cpu(controller->config());
|
||||
print_memory();
|
||||
print_threads(controller->config());
|
||||
controller->config()->pools().print();
|
||||
const auto config = controller->config();
|
||||
|
||||
print_commands(controller->config());
|
||||
config->printVersions();
|
||||
print_pages(config);
|
||||
print_cpu(config);
|
||||
print_memory(config);
|
||||
print_threads(config);
|
||||
config->pools().print();
|
||||
|
||||
print_commands(config);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -42,10 +35,15 @@ public:
|
||||
PciTopology() = default;
|
||||
PciTopology(uint32_t bus, uint32_t device, uint32_t function) : m_valid(true), m_bus(bus), m_device(device), m_function(function) {}
|
||||
|
||||
inline bool isValid() const { return m_valid; }
|
||||
inline uint8_t bus() const { return m_bus; }
|
||||
inline uint8_t device() const { return m_device; }
|
||||
inline uint8_t function() const { return m_function; }
|
||||
inline bool isEqual(const PciTopology &other) const { return m_valid == other.m_valid && toUint32() == other.toUint32(); }
|
||||
inline bool isValid() const { return m_valid; }
|
||||
inline uint8_t bus() const { return m_bus; }
|
||||
inline uint8_t device() const { return m_device; }
|
||||
inline uint8_t function() const { return m_function; }
|
||||
|
||||
inline bool operator!=(const PciTopology &other) const { return !isEqual(other); }
|
||||
inline bool operator<(const PciTopology &other) const { return toUint32() < other.toUint32(); }
|
||||
inline bool operator==(const PciTopology &other) const { return isEqual(other); }
|
||||
|
||||
String toString() const
|
||||
{
|
||||
@@ -60,6 +58,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
inline uint32_t toUint32() const { return m_bus << 16 | m_device << 8 | m_function; }
|
||||
|
||||
bool m_valid = false;
|
||||
uint8_t m_bus = 0;
|
||||
uint8_t m_device = 0;
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -77,7 +71,7 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
|
||||
Value obj(kObjectType);
|
||||
|
||||
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
|
||||
obj.AddMember(StringRef(kHugePages), m_hugePages, allocator);
|
||||
obj.AddMember(StringRef(kHugePages), m_hugePageSize == 0 || m_hugePageSize == kDefaultHugePageSizeKb ? Value(isHugePages()) : Value(static_cast<uint32_t>(m_hugePageSize)), allocator);
|
||||
obj.AddMember(StringRef(kHugePagesJit), m_hugePagesJit, allocator);
|
||||
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator);
|
||||
obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
|
||||
@@ -137,14 +131,14 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value)
|
||||
{
|
||||
if (value.IsObject()) {
|
||||
m_enabled = Json::getBool(value, kEnabled, m_enabled);
|
||||
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
|
||||
m_hugePagesJit = Json::getBool(value, kHugePagesJit, m_hugePagesJit);
|
||||
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
|
||||
m_yield = Json::getBool(value, kYield, m_yield);
|
||||
|
||||
setAesMode(Json::getValue(value, kHwAes));
|
||||
setPriority(Json::getInt(value, kPriority, -1));
|
||||
setHugePages(Json::getValue(value, kHugePages));
|
||||
setMemoryPool(Json::getValue(value, kMemoryPool));
|
||||
setPriority(Json::getInt(value, kPriority, -1));
|
||||
|
||||
# ifdef XMRIG_FEATURE_ASM
|
||||
m_assembly = Json::getValue(value, kAsm);
|
||||
@@ -218,6 +212,19 @@ void xmrig::CpuConfig::setAesMode(const rapidjson::Value &value)
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CpuConfig::setHugePages(const rapidjson::Value &value)
|
||||
{
|
||||
if (value.IsBool()) {
|
||||
m_hugePageSize = value.GetBool() ? kDefaultHugePageSizeKb : 0U;
|
||||
}
|
||||
else if (value.IsUint()) {
|
||||
const uint32_t size = value.GetUint();
|
||||
|
||||
m_hugePageSize = size < kOneGbPageSizeKb ? size : kDefaultHugePageSizeKb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CpuConfig::setMemoryPool(const rapidjson::Value &value)
|
||||
{
|
||||
if (value.IsBool()) {
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -75,8 +69,9 @@ public:
|
||||
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
|
||||
void read(const rapidjson::Value &value);
|
||||
|
||||
inline bool astrobwtAVX2() const { return m_astrobwtAVX2; }
|
||||
inline bool isEnabled() const { return m_enabled; }
|
||||
inline bool isHugePages() const { return m_hugePages; }
|
||||
inline bool isHugePages() const { return m_hugePageSize > 0; }
|
||||
inline bool isHugePagesJit() const { return m_hugePagesJit; }
|
||||
inline bool isShouldSave() const { return m_shouldSave; }
|
||||
inline bool isYield() const { return m_yield; }
|
||||
@@ -84,13 +79,17 @@ public:
|
||||
inline const String &argon2Impl() const { return m_argon2Impl; }
|
||||
inline const Threads<CpuThreads> &threads() const { return m_threads; }
|
||||
inline int astrobwtMaxSize() const { return m_astrobwtMaxSize; }
|
||||
inline bool astrobwtAVX2() const { return m_astrobwtAVX2; }
|
||||
inline int priority() const { return m_priority; }
|
||||
inline size_t hugePageSize() const { return m_hugePageSize * 1024U; }
|
||||
inline uint32_t limit() const { return m_limit; }
|
||||
|
||||
private:
|
||||
constexpr static size_t kDefaultHugePageSizeKb = 2048U;
|
||||
constexpr static size_t kOneGbPageSizeKb = 1048576U;
|
||||
|
||||
void generate();
|
||||
void setAesMode(const rapidjson::Value &value);
|
||||
void setHugePages(const rapidjson::Value &value);
|
||||
void setMemoryPool(const rapidjson::Value &value);
|
||||
|
||||
inline void setPriority(int priority) { m_priority = (priority >= -1 && priority <= 5) ? priority : -1; }
|
||||
@@ -99,13 +98,13 @@ private:
|
||||
Assembly m_assembly;
|
||||
bool m_astrobwtAVX2 = false;
|
||||
bool m_enabled = true;
|
||||
bool m_hugePages = true;
|
||||
bool m_hugePagesJit = false;
|
||||
bool m_shouldSave = false;
|
||||
bool m_yield = true;
|
||||
int m_astrobwtMaxSize = 550;
|
||||
int m_memoryPool = 0;
|
||||
int m_priority = -1;
|
||||
size_t m_hugePageSize = kDefaultHugePageSizeKb;
|
||||
String m_argon2Impl;
|
||||
Threads<CpuThreads> m_threads;
|
||||
uint32_t m_limit = 100;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -86,18 +86,21 @@ public:
|
||||
inline constexpr static bool is64bit() { return false; }
|
||||
# endif
|
||||
|
||||
virtual Arch arch() const = 0;
|
||||
virtual Assembly::Id assembly() const = 0;
|
||||
virtual bool has(Flag feature) const = 0;
|
||||
virtual bool hasAES() const = 0;
|
||||
virtual bool hasAVX() const = 0;
|
||||
virtual bool hasAVX2() const = 0;
|
||||
virtual bool hasBMI2() const = 0;
|
||||
virtual bool hasCatL3() const = 0;
|
||||
virtual bool hasOneGbPages() const = 0;
|
||||
virtual bool hasXOP() const = 0;
|
||||
virtual bool hasCatL3() const = 0;
|
||||
virtual bool isVM() const = 0;
|
||||
virtual bool jccErratum() const = 0;
|
||||
virtual const char *backend() const = 0;
|
||||
virtual const char *brand() const = 0;
|
||||
virtual const std::vector<int32_t> &units() const = 0;
|
||||
virtual CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const = 0;
|
||||
virtual MsrMod msrMod() const = 0;
|
||||
virtual rapidjson::Value toJSON(rapidjson::Document &doc) const = 0;
|
||||
@@ -108,8 +111,6 @@ public:
|
||||
virtual size_t packages() const = 0;
|
||||
virtual size_t threads() const = 0;
|
||||
virtual Vendor vendor() const = 0;
|
||||
virtual Arch arch() const = 0;
|
||||
virtual bool jccErratum() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -190,6 +190,11 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
|
||||
m_flags.set(FLAG_CAT_L3, has_cat_l3());
|
||||
m_flags.set(FLAG_VM, is_vm());
|
||||
|
||||
m_units.resize(m_threads);
|
||||
for (int32_t i = 0; i < static_cast<int32_t>(m_threads); ++i) {
|
||||
m_units[i] = i;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_FEATURE_ASM
|
||||
if (hasAES()) {
|
||||
char vendor[13] = { 0 };
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <support@xmrig.com>
|
||||
* Copyright (c) 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -45,34 +40,36 @@ protected:
|
||||
CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
|
||||
|
||||
inline Assembly::Id assembly() const override { return m_assembly; }
|
||||
inline bool has(Flag flag) const override { return m_flags.test(flag); }
|
||||
inline bool hasAES() const override { return has(FLAG_AES); }
|
||||
inline bool hasAVX() const override { return has(FLAG_AVX); }
|
||||
inline bool hasAVX2() const override { return has(FLAG_AVX2); }
|
||||
inline bool hasBMI2() const override { return has(FLAG_BMI2); }
|
||||
inline bool hasOneGbPages() const override { return has(FLAG_PDPE1GB); }
|
||||
inline bool hasXOP() const override { return has(FLAG_XOP); }
|
||||
inline bool hasCatL3() const override { return has(FLAG_CAT_L3); }
|
||||
inline bool isVM() const override { return has(FLAG_VM); }
|
||||
inline const char *brand() const override { return m_brand; }
|
||||
inline MsrMod msrMod() const override { return m_msrMod; }
|
||||
inline size_t cores() const override { return 0; }
|
||||
inline size_t L2() const override { return 0; }
|
||||
inline size_t L3() const override { return 0; }
|
||||
inline size_t nodes() const override { return 0; }
|
||||
inline size_t packages() const override { return 1; }
|
||||
inline size_t threads() const override { return m_threads; }
|
||||
inline Vendor vendor() const override { return m_vendor; }
|
||||
inline Arch arch() const override { return m_arch; }
|
||||
inline bool jccErratum() const override { return m_jccErratum; }
|
||||
inline Arch arch() const override { return m_arch; }
|
||||
inline Assembly::Id assembly() const override { return m_assembly; }
|
||||
inline bool has(Flag flag) const override { return m_flags.test(flag); }
|
||||
inline bool hasAES() const override { return has(FLAG_AES); }
|
||||
inline bool hasAVX() const override { return has(FLAG_AVX); }
|
||||
inline bool hasAVX2() const override { return has(FLAG_AVX2); }
|
||||
inline bool hasBMI2() const override { return has(FLAG_BMI2); }
|
||||
inline bool hasCatL3() const override { return has(FLAG_CAT_L3); }
|
||||
inline bool hasOneGbPages() const override { return has(FLAG_PDPE1GB); }
|
||||
inline bool hasXOP() const override { return has(FLAG_XOP); }
|
||||
inline bool isVM() const override { return has(FLAG_VM); }
|
||||
inline bool jccErratum() const override { return m_jccErratum; }
|
||||
inline const char *brand() const override { return m_brand; }
|
||||
inline const std::vector<int32_t> &units() const override { return m_units; }
|
||||
inline MsrMod msrMod() const override { return m_msrMod; }
|
||||
inline size_t cores() const override { return 0; }
|
||||
inline size_t L2() const override { return 0; }
|
||||
inline size_t L3() const override { return 0; }
|
||||
inline size_t nodes() const override { return 0; }
|
||||
inline size_t packages() const override { return 1; }
|
||||
inline size_t threads() const override { return m_threads; }
|
||||
inline Vendor vendor() const override { return m_vendor; }
|
||||
|
||||
protected:
|
||||
char m_brand[64 + 6]{};
|
||||
size_t m_threads;
|
||||
Vendor m_vendor = VENDOR_UNKNOWN;
|
||||
Arch m_arch = ARCH_UNKNOWN;
|
||||
bool m_jccErratum = false;
|
||||
char m_brand[64 + 6]{};
|
||||
size_t m_threads;
|
||||
std::vector<int32_t> m_units;
|
||||
Vendor m_vendor = VENDOR_UNKNOWN;
|
||||
|
||||
private:
|
||||
# ifndef XMRIG_ARM
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -50,6 +50,11 @@ extern String cpu_name_arm();
|
||||
xmrig::BasicCpuInfo::BasicCpuInfo() :
|
||||
m_threads(std::thread::hardware_concurrency())
|
||||
{
|
||||
m_units.resize(m_threads);
|
||||
for (int32_t i = 0; i < static_cast<int32_t>(m_threads); ++i) {
|
||||
m_units[i] = i;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_ARMv8
|
||||
memcpy(m_brand, "ARMv8", 5);
|
||||
# else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -125,8 +125,6 @@ static inline bool isCacheExclusive(hwloc_obj_t obj)
|
||||
|
||||
xmrig::HwlocCpuInfo::HwlocCpuInfo()
|
||||
{
|
||||
m_threads = 0;
|
||||
|
||||
hwloc_topology_init(&m_topology);
|
||||
hwloc_topology_load(m_topology);
|
||||
|
||||
@@ -170,7 +168,8 @@ xmrig::HwlocCpuInfo::HwlocCpuInfo()
|
||||
|
||||
findCache(root, 2, 3, [this](hwloc_obj_t found) { this->m_cache[found->attr->cache.depth] += found->attr->cache.size; });
|
||||
|
||||
m_threads = countByType(m_topology, HWLOC_OBJ_PU);
|
||||
setThreads(countByType(m_topology, HWLOC_OBJ_PU));
|
||||
|
||||
m_cores = countByType(m_topology, HWLOC_OBJ_CORE);
|
||||
m_nodes = std::max(hwloc_bitmap_weight(hwloc_topology_get_complete_nodeset(m_topology)), 1);
|
||||
m_packages = countByType(m_topology, HWLOC_OBJ_PACKAGE);
|
||||
@@ -277,10 +276,8 @@ xmrig::CpuThreads xmrig::HwlocCpuInfo::allThreads(const Algorithm &algorithm, ui
|
||||
CpuThreads threads;
|
||||
threads.reserve(m_threads);
|
||||
|
||||
hwloc_obj_t pu = nullptr;
|
||||
|
||||
while ((pu = hwloc_get_next_obj_by_type(m_topology, HWLOC_OBJ_PU, pu)) != nullptr) {
|
||||
threads.add(pu->os_index, 0);
|
||||
for (const int32_t pu : m_units) {
|
||||
threads.add(pu, 0);
|
||||
}
|
||||
|
||||
if (threads.isEmpty()) {
|
||||
@@ -395,3 +392,24 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HwlocCpuInfo::setThreads(size_t threads)
|
||||
{
|
||||
if (!threads) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_threads = threads;
|
||||
|
||||
if (m_units.size() != m_threads) {
|
||||
m_units.resize(m_threads);
|
||||
}
|
||||
|
||||
hwloc_obj_t pu = nullptr;
|
||||
size_t i = 0;
|
||||
|
||||
while ((pu = hwloc_get_next_obj_by_type(m_topology, HWLOC_OBJ_PU, pu)) != nullptr) {
|
||||
m_units[i++] = static_cast<int32_t>(pu->os_index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -66,7 +66,7 @@ protected:
|
||||
private:
|
||||
CpuThreads allThreads(const Algorithm &algorithm, uint32_t limit) const;
|
||||
void processTopLevelCache(hwloc_obj_t obj, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const;
|
||||
|
||||
void setThreads(size_t threads);
|
||||
|
||||
static uint32_t m_features;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018 Riku Voipio <riku.voipio@iki.fi>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -87,16 +87,22 @@ static const id_part arm_part[] = {
|
||||
{ 0xd03, "Cortex-A53" },
|
||||
{ 0xd04, "Cortex-A35" },
|
||||
{ 0xd05, "Cortex-A55" },
|
||||
{ 0xd06, "Cortex-A65" },
|
||||
{ 0xd07, "Cortex-A57" },
|
||||
{ 0xd08, "Cortex-A72" },
|
||||
{ 0xd09, "Cortex-A73" },
|
||||
{ 0xd0a, "Cortex-A75" },
|
||||
{ 0xd0b, "Cortex-A76" },
|
||||
{ 0xd0c, "Neoverse-N1" },
|
||||
{ 0xd0d, "Cortex-A77" },
|
||||
{ 0xd0e, "Cortex-A76AE" },
|
||||
{ 0xd13, "Cortex-R52" },
|
||||
{ 0xd20, "Cortex-M23" },
|
||||
{ 0xd21, "Cortex-M33" },
|
||||
{ 0xd41, "Cortex-A78" },
|
||||
{ 0xd42, "Cortex-A78AE" },
|
||||
{ 0xd4a, "Neoverse-E1" },
|
||||
{ 0xd4b, "Cortex-A78C" },
|
||||
{ -1, nullptr },
|
||||
};
|
||||
|
||||
@@ -150,6 +156,7 @@ static const id_part samsung_part[] = {
|
||||
static const id_part nvidia_part[] = {
|
||||
{ 0x000, "Denver" },
|
||||
{ 0x003, "Denver 2" },
|
||||
{ 0x004, "Carmel" },
|
||||
{ -1, nullptr },
|
||||
};
|
||||
|
||||
@@ -191,23 +198,36 @@ static const id_part intel_part[] = {
|
||||
{ -1, nullptr },
|
||||
};
|
||||
|
||||
static const struct id_part fujitsu_part[] = {
|
||||
{ 0x001, "A64FX" },
|
||||
{ -1, "unknown" },
|
||||
};
|
||||
|
||||
static const id_part hisi_part[] = {
|
||||
{ 0xd01, "Kunpeng-920" }, /* aka tsv110 */
|
||||
{ -1, nullptr },
|
||||
};
|
||||
|
||||
static const id_part apple_part[] = {
|
||||
{ 0x022, "M1" },
|
||||
{ 0x023, "M1" },
|
||||
{ -1, nullptr },
|
||||
};
|
||||
|
||||
|
||||
static const hw_impl hw_implementer[] = {
|
||||
{ 0x41, arm_part, "ARM" },
|
||||
{ 0x42, brcm_part, "Broadcom" },
|
||||
{ 0x43, cavium_part, "Cavium" },
|
||||
{ 0x44, dec_part, "DEC" },
|
||||
{ 0x46, fujitsu_part, "FUJITSU" },
|
||||
{ 0x48, hisi_part, "HiSilicon" },
|
||||
{ 0x4e, nvidia_part, "Nvidia" },
|
||||
{ 0x50, apm_part, "APM" },
|
||||
{ 0x51, qcom_part, "Qualcomm" },
|
||||
{ 0x53, samsung_part, "Samsung" },
|
||||
{ 0x56, marvell_part, "Marvell" },
|
||||
{ 0x61, apple_part, "Apple" },
|
||||
{ 0x66, faraday_part, "Faraday" },
|
||||
{ 0x69, intel_part, "Intel" }
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* XMRig
|
||||
* Copyright 2008-2018 Advanced Micro Devices, Inc.
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2020 Patrick Bollinger <https://github.com/pjbollinger>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2008-2018 Advanced Micro Devices, Inc.
|
||||
* Copyright (c) 2020 Patrick Bollinger <https://github.com/pjbollinger>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -20,10 +20,13 @@
|
||||
|
||||
|
||||
#include "backend/opencl/wrappers/AdlLib.h"
|
||||
#include "3rdparty/fmt/core.h"
|
||||
#include "backend/opencl/wrappers/OclDevice.h"
|
||||
|
||||
|
||||
#include <dirent.h>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@@ -35,18 +38,27 @@ namespace xmrig {
|
||||
bool AdlLib::m_initialized = false;
|
||||
bool AdlLib::m_ready = false;
|
||||
static const std::string kPrefix = "/sys/bus/pci/drivers/amdgpu/";
|
||||
static std::map<PciTopology, std::string> hwmon_cache;
|
||||
|
||||
|
||||
static inline bool sysfs_is_file(const std::string &path)
|
||||
static inline bool sysfs_is_file(const char *path)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
return stat(path.c_str(), &sb) == 0 && ((sb.st_mode & S_IFMT) == S_IFREG);
|
||||
return stat(path, &sb) == 0 && ((sb.st_mode & S_IFMT) == S_IFREG);
|
||||
}
|
||||
|
||||
|
||||
static inline bool sysfs_is_amdgpu(const std::string &path)
|
||||
static inline int dir_filter(const struct dirent *dirp)
|
||||
{
|
||||
return strlen(dirp->d_name) > 5 ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
static bool sysfs_is_amdgpu(const char *path, char *buf, const char *filename)
|
||||
{
|
||||
strcpy(buf, filename);
|
||||
|
||||
if (!sysfs_is_file(path)) {
|
||||
return false;
|
||||
}
|
||||
@@ -63,8 +75,10 @@ static inline bool sysfs_is_amdgpu(const std::string &path)
|
||||
}
|
||||
|
||||
|
||||
uint32_t sysfs_read(const std::string &path)
|
||||
static uint32_t sysfs_read(const char *path, char *buf, const char *filename)
|
||||
{
|
||||
strcpy(buf, filename);
|
||||
|
||||
std::ifstream file(path);
|
||||
if (!file.is_open()) {
|
||||
return 0;
|
||||
@@ -77,18 +91,44 @@ uint32_t sysfs_read(const std::string &path)
|
||||
}
|
||||
|
||||
|
||||
static inline std::string sysfs_prefix(const PciTopology &topology)
|
||||
static size_t sysfs_prefix(char path[PATH_MAX], const PciTopology &topology)
|
||||
{
|
||||
const std::string path = kPrefix + "0000:" + topology.toString().data() + "/hwmon/hwmon";
|
||||
const auto it = hwmon_cache.find(topology);
|
||||
if (it != hwmon_cache.end()) {
|
||||
strcpy(path, it->second.data());
|
||||
|
||||
for (uint32_t i = 1; i < 10; ++i) {
|
||||
const std::string prefix = path + std::to_string(i) + "/";
|
||||
if (sysfs_is_amdgpu(prefix + "name") && (sysfs_read(prefix + "temp1_input") || sysfs_read(prefix + "power1_average"))) {
|
||||
return prefix;
|
||||
}
|
||||
return it->second.size();
|
||||
}
|
||||
|
||||
return {};
|
||||
char *base = fmt::format_to(path, "{}0000:{}/hwmon/", kPrefix, topology.toString());
|
||||
*base = '\0';
|
||||
char *end = nullptr;
|
||||
|
||||
struct dirent **namelist;
|
||||
int n = scandir(path, &namelist, dir_filter, nullptr);
|
||||
if (n < 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
while (n--) {
|
||||
if (!end) {
|
||||
char *tmp = fmt::format_to(base, "{}/", namelist[n]->d_name);
|
||||
end = (sysfs_is_amdgpu(path, tmp, "name") && (sysfs_read(path, tmp, "temp1_input") || sysfs_read(path, tmp, "power1_average"))) ? tmp : nullptr;
|
||||
}
|
||||
|
||||
free(namelist[n]);
|
||||
}
|
||||
|
||||
free(namelist);
|
||||
|
||||
if (end) {
|
||||
*end = '\0';
|
||||
hwmon_cache.insert({ topology, path });
|
||||
|
||||
return end - path;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -124,20 +164,22 @@ AdlHealth xmrig::AdlLib::health(const OclDevice &device)
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto prefix = sysfs_prefix(device.topology());
|
||||
if (prefix.empty()) {
|
||||
static char path[PATH_MAX]{};
|
||||
|
||||
char *buf = path + sysfs_prefix(path, device.topology());
|
||||
if (buf == path) {
|
||||
return {};
|
||||
}
|
||||
|
||||
AdlHealth health;
|
||||
health.clock = sysfs_read(prefix + "freq1_input") / 1000000;
|
||||
health.memClock = sysfs_read(prefix + "freq2_input") / 1000000;
|
||||
health.power = sysfs_read(prefix + "power1_average") / 1000000;
|
||||
health.rpm = sysfs_read(prefix + "fan1_input");
|
||||
health.temperature = sysfs_read(prefix + "temp2_input") / 1000;
|
||||
health.clock = sysfs_read(path, buf, "freq1_input") / 1000000;
|
||||
health.memClock = sysfs_read(path, buf, "freq2_input") / 1000000;
|
||||
health.power = sysfs_read(path, buf, "power1_average") / 1000000;
|
||||
health.rpm = sysfs_read(path, buf, "fan1_input");
|
||||
health.temperature = sysfs_read(path, buf, "temp2_input") / 1000;
|
||||
|
||||
if (!health.temperature) {
|
||||
health.temperature = sysfs_read(prefix + "temp1_input") / 1000;
|
||||
health.temperature = sysfs_read(path, buf, "temp1_input") / 1000;
|
||||
}
|
||||
|
||||
return health;
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -31,7 +25,6 @@
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IBaseListener.h"
|
||||
#include "base/tools/Object.h"
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2018 XMRig <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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,6 +20,9 @@
|
||||
#define XMRIG_IAPILISTENER_H
|
||||
|
||||
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
@@ -33,6 +32,9 @@ class IApiRequest;
|
||||
class IApiListener
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE(IApiListener)
|
||||
|
||||
IApiListener() = default;
|
||||
virtual ~IApiListener() = default;
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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,6 +21,7 @@
|
||||
|
||||
|
||||
#include "3rdparty/rapidjson/fwd.h"
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -38,6 +33,8 @@ class String;
|
||||
class IApiRequest
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE(IApiRequest)
|
||||
|
||||
enum Method {
|
||||
METHOD_DELETE,
|
||||
METHOD_GET,
|
||||
@@ -67,7 +64,8 @@ public:
|
||||
};
|
||||
|
||||
|
||||
virtual ~IApiRequest() = default;
|
||||
IApiRequest() = default;
|
||||
virtual ~IApiRequest() = default;
|
||||
|
||||
virtual bool accept() = 0;
|
||||
virtual bool hasParseError() const = 0;
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -26,6 +20,9 @@
|
||||
#define XMRIG_IBASELISTENER_H
|
||||
|
||||
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
@@ -35,7 +32,10 @@ class Config;
|
||||
class IBaseListener
|
||||
{
|
||||
public:
|
||||
virtual ~IBaseListener() = default;
|
||||
XMRIG_DISABLE_COPY_MOVE(IBaseListener)
|
||||
|
||||
IBaseListener() = default;
|
||||
virtual ~IBaseListener() = default;
|
||||
|
||||
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
|
||||
};
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -84,6 +84,8 @@ public:
|
||||
BenchSeedKey = 1046,
|
||||
BenchHashKey = 1047,
|
||||
BenchTokenKey = 1048,
|
||||
DmiKey = 1049,
|
||||
HugePageSizeKey = 1050,
|
||||
|
||||
// xmrig common
|
||||
CPUPriorityKey = 1021,
|
||||
|
||||
@@ -104,7 +104,7 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result)
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
memcpy(data + 78, result.nonce, 8);
|
||||
# else
|
||||
Cvt::toHex(data + 78, 9, reinterpret_cast<const uint8_t *>(&result.nonce), 4);
|
||||
Cvt::toHex(data + 78, 8, reinterpret_cast<const uint8_t *>(&result.nonce), 4);
|
||||
# endif
|
||||
|
||||
using namespace rapidjson;
|
||||
@@ -227,7 +227,7 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code)
|
||||
m_blockhashingblob = Json::getString(params, "blockhashing_blob");
|
||||
if (m_apiVersion == API_DERO) {
|
||||
const uint64_t offset = Json::getUint64(params, "reserved_offset");
|
||||
Cvt::toHex(m_blockhashingblob.data() + offset * 2, kBlobReserveSize * 2 + 1, Cvt::randomBytes(kBlobReserveSize).data(), kBlobReserveSize);
|
||||
Cvt::toHex(m_blockhashingblob.data() + offset * 2, kBlobReserveSize * 2, Cvt::randomBytes(kBlobReserveSize).data(), kBlobReserveSize);
|
||||
}
|
||||
|
||||
if (blocktemplate.isNull() || !job.setBlob(m_blockhashingblob)) {
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -134,7 +134,7 @@ void xmrig::Pools::load(const IJsonReader &reader)
|
||||
m_data.clear();
|
||||
|
||||
# ifdef XMRIG_FEATURE_BENCHMARK
|
||||
m_benchmark = std::shared_ptr<BenchConfig>(BenchConfig::create(reader.getObject(BenchConfig::kBenchmark)));
|
||||
m_benchmark = std::shared_ptr<BenchConfig>(BenchConfig::create(reader.getObject(BenchConfig::kBenchmark), reader.getBool("dmi", true)));
|
||||
if (m_benchmark) {
|
||||
m_data.emplace_back(m_benchmark);
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -34,6 +34,10 @@
|
||||
#include "base/tools/Cvt.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifdef XMRIG_FEATURE_DMI
|
||||
# include "hw/dmi/DmiReader.h"
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::BenchClient::BenchClient(const std::shared_ptr<BenchConfig> &benchmark, IClientListener* listener) :
|
||||
m_listener(listener),
|
||||
@@ -336,6 +340,15 @@ void xmrig::BenchClient::send(Request request)
|
||||
doc.AddMember("steady_ready_ts", m_readyTime, allocator);
|
||||
doc.AddMember("cpu", Cpu::toJSON(doc), allocator);
|
||||
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
if (m_benchmark->isDMI()) {
|
||||
DmiReader reader;
|
||||
if (reader.read()) {
|
||||
doc.AddMember("dmi", reader.toJSON(doc), allocator);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
FetchRequest req(HTTP_POST, m_ip, BenchConfig::kApiPort, "/1/benchmark", doc, BenchConfig::kApiTLS, true);
|
||||
fetch(tag(), std::move(req), m_httpListener);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -52,8 +52,9 @@ const char *BenchConfig::kApiHost = "127.0.0.1";
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::BenchConfig::BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object) :
|
||||
xmrig::BenchConfig::BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object, bool dmi) :
|
||||
m_algorithm(Json::getString(object, kAlgo)),
|
||||
m_dmi(dmi),
|
||||
m_submit(Json::getBool(object, kSubmit)),
|
||||
m_id(id),
|
||||
m_seed(Json::getString(object, kSeed)),
|
||||
@@ -72,7 +73,7 @@ xmrig::BenchConfig::BenchConfig(uint32_t size, const String &id, const rapidjson
|
||||
}
|
||||
|
||||
|
||||
xmrig::BenchConfig *xmrig::BenchConfig::create(const rapidjson::Value &object)
|
||||
xmrig::BenchConfig *xmrig::BenchConfig::create(const rapidjson::Value &object, bool dmi)
|
||||
{
|
||||
if (!object.IsObject() || object.ObjectEmpty()) {
|
||||
return nullptr;
|
||||
@@ -85,7 +86,7 @@ xmrig::BenchConfig *xmrig::BenchConfig::create(const rapidjson::Value &object)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new BenchConfig(size, id, object);
|
||||
return new BenchConfig(size, id, object, dmi);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -49,10 +49,11 @@ public:
|
||||
static constexpr const uint16_t kApiPort = 18805;
|
||||
# endif
|
||||
|
||||
BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object);
|
||||
BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object, bool dmi);
|
||||
|
||||
static BenchConfig *create(const rapidjson::Value &object);
|
||||
static BenchConfig *create(const rapidjson::Value &object, bool dmi);
|
||||
|
||||
inline bool isDMI() const { return m_dmi; }
|
||||
inline bool isSubmit() const { return m_submit; }
|
||||
inline const Algorithm &algorithm() const { return m_algorithm; }
|
||||
inline const String &id() const { return m_id; }
|
||||
@@ -67,6 +68,7 @@ private:
|
||||
static uint32_t getSize(const char *benchmark);
|
||||
|
||||
Algorithm m_algorithm;
|
||||
bool m_dmi;
|
||||
bool m_submit;
|
||||
String m_id;
|
||||
String m_seed;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2013-2020 Frank Denis <j at pureftpd dot org>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -34,11 +34,6 @@
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
#ifndef XMRIG_SODIUM
|
||||
static std::random_device randomDevice;
|
||||
static std::mt19937 randomEngine(randomDevice());
|
||||
|
||||
|
||||
static char *cvt_bin2hex(char *const hex, const size_t hex_maxlen, const unsigned char *const bin, const size_t bin_len)
|
||||
{
|
||||
size_t i = 0U;
|
||||
@@ -46,7 +41,7 @@ static char *cvt_bin2hex(char *const hex, const size_t hex_maxlen, const unsigne
|
||||
int b;
|
||||
int c;
|
||||
|
||||
if (bin_len >= SIZE_MAX / 2 || hex_maxlen <= bin_len * 2U) {
|
||||
if (bin_len >= SIZE_MAX / 2 || hex_maxlen < bin_len * 2U) {
|
||||
return nullptr; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
|
||||
@@ -60,12 +55,20 @@ static char *cvt_bin2hex(char *const hex, const size_t hex_maxlen, const unsigne
|
||||
hex[i * 2U + 1U] = (char) x;
|
||||
i++;
|
||||
}
|
||||
hex[i * 2U] = 0U;
|
||||
|
||||
if (i * 2U < hex_maxlen) {
|
||||
hex[i * 2U] = 0U;
|
||||
}
|
||||
|
||||
return hex;
|
||||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_SODIUM
|
||||
static std::random_device randomDevice;
|
||||
static std::mt19937 randomEngine(randomDevice());
|
||||
|
||||
|
||||
static int cvt_hex2bin(unsigned char *const bin, const size_t bin_maxlen, const char *const hex, const size_t hex_len, const char *const ignore, size_t *const bin_len, const char **const hex_end)
|
||||
{
|
||||
size_t bin_pos = 0U;
|
||||
@@ -137,7 +140,6 @@ static int cvt_hex2bin(unsigned char *const bin, const size_t bin_maxlen, const
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define sodium_bin2hex cvt_bin2hex
|
||||
#define sodium_hex2bin cvt_hex2bin
|
||||
#endif
|
||||
|
||||
@@ -215,7 +217,7 @@ xmrig::Buffer xmrig::Cvt::fromHex(const char *in, size_t size)
|
||||
|
||||
bool xmrig::Cvt::toHex(char *hex, size_t hex_maxlen, const uint8_t *bin, size_t bin_len)
|
||||
{
|
||||
return sodium_bin2hex(hex, hex_maxlen, bin, bin_len) != nullptr;
|
||||
return cvt_bin2hex(hex, hex_maxlen, bin, bin_len) != nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -273,3 +275,17 @@ xmrig::String xmrig::Cvt::toHex(const uint8_t *in, size_t size)
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Cvt::randomBytes(void *buf, size_t size)
|
||||
{
|
||||
# ifndef XMRIG_SODIUM
|
||||
std::uniform_int_distribution<> dis(0, 255);
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
static_cast<uint8_t *>(buf)[i] = static_cast<char>(dis(randomEngine));
|
||||
}
|
||||
# else
|
||||
randombytes_buf(buf, size);
|
||||
# endif
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -52,6 +52,7 @@ public:
|
||||
static rapidjson::Value toHex(const std::string &data, rapidjson::Document &doc);
|
||||
static rapidjson::Value toHex(const uint8_t *in, size_t size, rapidjson::Document &doc);
|
||||
static String toHex(const uint8_t *in, size_t size);
|
||||
static void randomBytes(void *buf, size_t size);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
],
|
||||
"print-time": 60,
|
||||
"health-print-time": 60,
|
||||
"dmi": true,
|
||||
"retries": 5,
|
||||
"retry-pause": 5,
|
||||
"syslog": false,
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -31,6 +25,12 @@
|
||||
#include "net/Network.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_API
|
||||
# include "base/api/Api.h"
|
||||
# include "hw/api/HwApi.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
@@ -42,8 +42,6 @@ xmrig::Controller::Controller(Process *process) :
|
||||
|
||||
xmrig::Controller::~Controller()
|
||||
{
|
||||
delete m_network;
|
||||
|
||||
VirtualMemory::destroy();
|
||||
}
|
||||
|
||||
@@ -52,9 +50,14 @@ int xmrig::Controller::init()
|
||||
{
|
||||
Base::init();
|
||||
|
||||
VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().isHugePages());
|
||||
VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().hugePageSize());
|
||||
|
||||
m_network = new Network(this);
|
||||
m_network = std::make_shared<Network>(this);
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
m_hwApi = std::make_shared<HwApi>();
|
||||
api()->addListener(m_hwApi.get());
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -64,7 +67,7 @@ void xmrig::Controller::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
m_miner = new Miner(this);
|
||||
m_miner = std::make_shared<Miner>(this);
|
||||
|
||||
network()->connect();
|
||||
}
|
||||
@@ -74,29 +77,26 @@ void xmrig::Controller::stop()
|
||||
{
|
||||
Base::stop();
|
||||
|
||||
delete m_network;
|
||||
m_network = nullptr;
|
||||
m_network.reset();
|
||||
|
||||
m_miner->stop();
|
||||
|
||||
delete m_miner;
|
||||
m_miner = nullptr;
|
||||
m_miner.reset();
|
||||
}
|
||||
|
||||
|
||||
xmrig::Miner *xmrig::Controller::miner() const
|
||||
{
|
||||
assert(m_miner != nullptr);
|
||||
assert(m_miner);
|
||||
|
||||
return m_miner;
|
||||
return m_miner.get();
|
||||
}
|
||||
|
||||
|
||||
xmrig::Network *xmrig::Controller::network() const
|
||||
{
|
||||
assert(m_network != nullptr);
|
||||
assert(m_network);
|
||||
|
||||
return m_network;
|
||||
return m_network.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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,12 +21,15 @@
|
||||
|
||||
|
||||
#include "base/kernel/Base.h"
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HwApi;
|
||||
class Job;
|
||||
class Miner;
|
||||
class Network;
|
||||
@@ -55,8 +52,12 @@ public:
|
||||
void execCommand(char command);
|
||||
|
||||
private:
|
||||
Miner *m_miner = nullptr;
|
||||
Network *m_network = nullptr;
|
||||
std::shared_ptr<Miner> m_miner;
|
||||
std::shared_ptr<Network> m_network;
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
std::shared_ptr<HwApi> m_hwApi;
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -23,9 +23,9 @@
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <cstring>
|
||||
#include <uv.h>
|
||||
#include <cinttypes>
|
||||
|
||||
|
||||
#include "core/config/Config.h"
|
||||
@@ -55,16 +55,19 @@ namespace xmrig {
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_OPENCL
|
||||
static const char *kOcl = "opencl";
|
||||
const char *Config::kOcl = "opencl";
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_FEATURE_CUDA
|
||||
static const char *kCuda = "cuda";
|
||||
const char *Config::kCuda = "cuda";
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||
static const char *kHealthPrintTime = "health-print-time";
|
||||
const char *Config::kHealthPrintTime = "health-print-time";
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_FEATURE_DMI
|
||||
const char *Config::kDMI = "dmi";
|
||||
#endif
|
||||
|
||||
|
||||
@@ -88,6 +91,10 @@ public:
|
||||
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||
uint32_t healthPrintTime = 60;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
bool dmi = true;
|
||||
# endif
|
||||
};
|
||||
|
||||
}
|
||||
@@ -143,6 +150,14 @@ uint32_t xmrig::Config::healthPrintTime() const
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_DMI
|
||||
bool xmrig::Config::isDMI() const
|
||||
{
|
||||
return d_ptr->dmi;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool xmrig::Config::isShouldSave() const
|
||||
{
|
||||
if (!isAutoSave()) {
|
||||
@@ -191,6 +206,10 @@ bool xmrig::Config::read(const IJsonReader &reader, const char *fileName)
|
||||
d_ptr->healthPrintTime = reader.getUint(kHealthPrintTime, d_ptr->healthPrintTime);
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
d_ptr->dmi = reader.getBool(kDMI, d_ptr->dmi);
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -236,6 +255,11 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
|
||||
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||
doc.AddMember(StringRef(kHealthPrintTime), healthPrintTime(), allocator);
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
doc.AddMember(StringRef(kDMI), isDMI(), allocator);
|
||||
# endif
|
||||
|
||||
doc.AddMember(StringRef(kSyslog), isSyslog(), allocator);
|
||||
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -50,6 +50,22 @@ class Config : public BaseConfig
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE(Config);
|
||||
|
||||
# ifdef XMRIG_FEATURE_OPENCL
|
||||
static const char *kOcl;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_CUDA
|
||||
static const char *kCuda;
|
||||
# endif
|
||||
|
||||
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||
static const char *kHealthPrintTime;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
static const char *kDMI;
|
||||
# endif
|
||||
|
||||
Config();
|
||||
~Config() override;
|
||||
|
||||
@@ -70,7 +86,13 @@ public:
|
||||
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||
uint32_t healthPrintTime() const;
|
||||
# else
|
||||
uint32_t healthPrintTime() const { return 0; }
|
||||
uint32_t healthPrintTime() const { return 0; }
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
bool isDMI() const;
|
||||
# else
|
||||
static constexpr inline bool isDMI() { return false; }
|
||||
# endif
|
||||
|
||||
bool isShouldSave() const;
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -23,11 +23,11 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "core/config/ConfigTransform.h"
|
||||
#include "base/kernel/interfaces/IConfig.h"
|
||||
#include "backend/cpu/CpuConfig.h"
|
||||
#include "base/net/stratum/Pool.h"
|
||||
#include "base/net/stratum/Pools.h"
|
||||
#include "core/config/ConfigTransform.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "crypto/cn/CnHash.h"
|
||||
|
||||
|
||||
@@ -51,14 +51,6 @@ static const char *kEnabled = "enabled";
|
||||
static const char *kIntensity = "intensity";
|
||||
static const char *kThreads = "threads";
|
||||
|
||||
#ifdef XMRIG_FEATURE_OPENCL
|
||||
static const char *kOcl = "opencl";
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_FEATURE_CUDA
|
||||
static const char *kCuda = "cuda";
|
||||
#endif
|
||||
|
||||
|
||||
static inline uint64_t intensity(uint64_t av)
|
||||
{
|
||||
@@ -122,7 +114,7 @@ void xmrig::ConfigTransform::finalize(rapidjson::Document &doc)
|
||||
|
||||
# ifdef XMRIG_FEATURE_OPENCL
|
||||
if (m_opencl) {
|
||||
set(doc, kOcl, kEnabled, true);
|
||||
set(doc, Config::kOcl, kEnabled, true);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
@@ -133,9 +125,10 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
|
||||
BaseTransform::transform(doc, key, arg);
|
||||
|
||||
switch (key) {
|
||||
case IConfig::AVKey: /* --av */
|
||||
case IConfig::CPUPriorityKey: /* --cpu-priority */
|
||||
case IConfig::ThreadsKey: /* --threads */
|
||||
case IConfig::AVKey: /* --av */
|
||||
case IConfig::CPUPriorityKey: /* --cpu-priority */
|
||||
case IConfig::ThreadsKey: /* --threads */
|
||||
case IConfig::HugePageSizeKey: /* --hugepage-size */
|
||||
return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
|
||||
case IConfig::HugePagesKey: /* --no-huge-pages */
|
||||
@@ -157,8 +150,10 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
|
||||
case IConfig::YieldKey: /* --cpu-no-yield */
|
||||
return set(doc, CpuConfig::kField, CpuConfig::kYield, false);
|
||||
|
||||
# ifdef XMRIG_ALGO_ARGON2
|
||||
case IConfig::Argon2ImplKey: /* --argon2-impl */
|
||||
return set(doc, CpuConfig::kField, CpuConfig::kArgon2Impl, arg);
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_ASM
|
||||
case IConfig::AssemblyKey: /* --asm */
|
||||
@@ -208,47 +203,54 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
|
||||
break;
|
||||
|
||||
case IConfig::OclCacheKey: /* --opencl-no-cache */
|
||||
return set(doc, kOcl, "cache", false);
|
||||
return set(doc, Config::kOcl, "cache", false);
|
||||
|
||||
case IConfig::OclLoaderKey: /* --opencl-loader */
|
||||
return set(doc, kOcl, "loader", arg);
|
||||
return set(doc, Config::kOcl, "loader", arg);
|
||||
|
||||
case IConfig::OclDevicesKey: /* --opencl-devices */
|
||||
m_opencl = true;
|
||||
return set(doc, kOcl, "devices-hint", arg);
|
||||
return set(doc, Config::kOcl, "devices-hint", arg);
|
||||
|
||||
case IConfig::OclPlatformKey: /* --opencl-platform */
|
||||
if (strlen(arg) < 3) {
|
||||
return set(doc, kOcl, "platform", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
return set(doc, Config::kOcl, "platform", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
}
|
||||
|
||||
return set(doc, kOcl, "platform", arg);
|
||||
return set(doc, Config::kOcl, "platform", arg);
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_CUDA
|
||||
case IConfig::CudaKey: /* --cuda */
|
||||
return set(doc, kCuda, kEnabled, true);
|
||||
return set(doc, Config::kCuda, kEnabled, true);
|
||||
|
||||
case IConfig::CudaLoaderKey: /* --cuda-loader */
|
||||
return set(doc, kCuda, "loader", arg);
|
||||
return set(doc, Config::kCuda, "loader", arg);
|
||||
|
||||
case IConfig::CudaDevicesKey: /* --cuda-devices */
|
||||
set(doc, kCuda, kEnabled, true);
|
||||
return set(doc, kCuda, "devices-hint", arg);
|
||||
set(doc, Config::kCuda, kEnabled, true);
|
||||
return set(doc, Config::kCuda, "devices-hint", arg);
|
||||
|
||||
case IConfig::CudaBFactorKey: /* --cuda-bfactor-hint */
|
||||
return set(doc, kCuda, "bfactor-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
return set(doc, Config::kCuda, "bfactor-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
|
||||
case IConfig::CudaBSleepKey: /* --cuda-bsleep-hint */
|
||||
return set(doc, kCuda, "bsleep-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
return set(doc, Config::kCuda, "bsleep-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
case IConfig::NvmlKey: /* --no-nvml */
|
||||
return set(doc, kCuda, "nvml", false);
|
||||
return set(doc, Config::kCuda, "nvml", false);
|
||||
# endif
|
||||
|
||||
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||
case IConfig::HealthPrintTimeKey: /* --health-print-time */
|
||||
return set(doc, "health-print-time", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
return set(doc, Config::kHealthPrintTime, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
case IConfig::DmiKey: /* --no-dmi */
|
||||
return set(doc, Config::kDMI, false);
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_BENCHMARK
|
||||
@@ -305,6 +307,9 @@ void xmrig::ConfigTransform::transformUint64(rapidjson::Document &doc, int key,
|
||||
case IConfig::CPUPriorityKey: /* --cpu-priority */
|
||||
return set(doc, CpuConfig::kField, CpuConfig::kPriority, arg);
|
||||
|
||||
case IConfig::HugePageSizeKey: /* --hugepage-size */
|
||||
return set(doc, CpuConfig::kField, CpuConfig::kHugePages, arg);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -22,6 +16,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XMRIG_CONFIG_DEFAULT_H
|
||||
#define XMRIG_CONFIG_DEFAULT_H
|
||||
|
||||
@@ -29,6 +24,7 @@
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
// This feature require CMake option: -DWITH_EMBEDDED_CONFIG=ON
|
||||
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
|
||||
const static char *default_config =
|
||||
R"===(
|
||||
@@ -45,9 +41,9 @@ R"===(
|
||||
"restricted": true
|
||||
},
|
||||
"autosave": true,
|
||||
"version": 1,
|
||||
"background": false,
|
||||
"colors": true,
|
||||
"title": true,
|
||||
"randomx": {
|
||||
"init": -1,
|
||||
"init-avx2": -1,
|
||||
@@ -80,6 +76,7 @@ R"===(
|
||||
"cache": true,
|
||||
"loader": null,
|
||||
"platform": "AMD",
|
||||
"adl": true,
|
||||
"cn/0": false,
|
||||
"cn-lite/0": false
|
||||
},
|
||||
@@ -90,7 +87,7 @@ R"===(
|
||||
"cn/0": false,
|
||||
"cn-lite/0": false
|
||||
},
|
||||
"donate-level": 5,
|
||||
"donate-level": 1,
|
||||
"donate-over-proxy": 1,
|
||||
"log-file": null,
|
||||
"pools": [
|
||||
@@ -107,15 +104,27 @@ R"===(
|
||||
"tls": false,
|
||||
"tls-fingerprint": null,
|
||||
"daemon": false,
|
||||
"socks5": null,
|
||||
"self-select": null
|
||||
}
|
||||
],
|
||||
"print-time": 60,
|
||||
"health-print-time": 60,
|
||||
"dmi": true,
|
||||
"retries": 5,
|
||||
"retry-pause": 5,
|
||||
"syslog": false,
|
||||
"tls": {
|
||||
"enabled": false,
|
||||
"protocols": null,
|
||||
"cert": null,
|
||||
"cert_key": null,
|
||||
"ciphers": null,
|
||||
"ciphersuites": null,
|
||||
"dhparam": null
|
||||
},
|
||||
"user-agent": null,
|
||||
"verbose": 0,
|
||||
"watch": true,
|
||||
"pause-on-battery": false
|
||||
}
|
||||
|
||||
@@ -71,6 +71,8 @@ static const option options[] = {
|
||||
{ "nicehash", 0, nullptr, IConfig::NicehashKey },
|
||||
{ "no-color", 0, nullptr, IConfig::ColorKey },
|
||||
{ "no-huge-pages", 0, nullptr, IConfig::HugePagesKey },
|
||||
{ "no-hugepages", 0, nullptr, IConfig::HugePagesKey },
|
||||
{ "hugepage-size", 1, nullptr, IConfig::HugePageSizeKey },
|
||||
{ "pass", 1, nullptr, IConfig::PasswordKey },
|
||||
{ "print-time", 1, nullptr, IConfig::PrintTimeKey },
|
||||
{ "retries", 1, nullptr, IConfig::RetriesKey },
|
||||
@@ -155,7 +157,12 @@ static const option options[] = {
|
||||
# endif
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
{ "no-nvml", 0, nullptr, IConfig::NvmlKey },
|
||||
# endif
|
||||
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||
{ "health-print-time", 1, nullptr, IConfig::HealthPrintTimeKey },
|
||||
# endif
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
{ "no-dmi", 0, nullptr, IConfig::DmiKey },
|
||||
# endif
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
@@ -83,6 +83,9 @@ static inline const std::string &usage()
|
||||
u += " --cpu-memory-pool=N number of 2 MB pages for persistent memory pool, -1 (auto), 0 (disable)\n";
|
||||
u += " --cpu-no-yield prefer maximum hashrate rather than system response/stability\n";
|
||||
u += " --no-huge-pages disable huge pages support\n";
|
||||
# ifdef XMRIG_OS_LINUX
|
||||
u += " --hugepage-size=N custom hugepage size in kB\n";
|
||||
# endif
|
||||
u += " --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer\n";
|
||||
|
||||
# if defined(__x86_64__) || defined(_M_AMD64)
|
||||
@@ -155,7 +158,7 @@ static inline const std::string &usage()
|
||||
|
||||
u += " -l, --log-file=FILE log all output to a file\n";
|
||||
u += " --print-time=N print hashrate report every N seconds\n";
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
# if defined(XMRIG_FEATURE_NVML) || defined(XMRIG_FEATURE_ADL)
|
||||
u += " --health-print-time=N print health report every N seconds\n";
|
||||
# endif
|
||||
u += " --no-color disable colored output\n";
|
||||
@@ -190,6 +193,10 @@ static inline const std::string &usage()
|
||||
u += " --hash=HASH compare benchmark result with specified hash\n";
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
u += " --no-dmi disable DMI/SMBIOS reader\n";
|
||||
# endif
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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,24 +21,16 @@
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
constexpr size_t twoMiB = 2U * 1024U * 1024U;
|
||||
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HugePagesInfo::HugePagesInfo(const VirtualMemory *memory)
|
||||
{
|
||||
if (memory->isOneGbPages()) {
|
||||
size = VirtualMemory::align(memory->size(), oneGiB);
|
||||
total = size / oneGiB;
|
||||
allocated = size / oneGiB;
|
||||
size = VirtualMemory::align(memory->size(), VirtualMemory::kOneGiB);
|
||||
total = size / VirtualMemory::kOneGiB;
|
||||
allocated = size / VirtualMemory::kOneGiB;
|
||||
}
|
||||
else {
|
||||
size = memory->size();
|
||||
total = size / twoMiB;
|
||||
size = VirtualMemory::alignToHugePageSize(memory->size());
|
||||
total = size / VirtualMemory::hugePageSize();
|
||||
allocated = memory->isHugePages() ? total : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
#include "crypto/common/LinuxMemory.h"
|
||||
#include "3rdparty/fmt/core.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
|
||||
|
||||
@@ -37,33 +35,32 @@ constexpr size_t twoMiB = 2U * 1024U * 1024U;
|
||||
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
|
||||
|
||||
|
||||
static inline std::string sysfs_path(uint32_t node, bool oneGbPages, bool nr)
|
||||
static inline std::string sysfs_path(uint32_t node, size_t hugePageSize, bool nr)
|
||||
{
|
||||
return fmt::format("/sys/devices/system/node/node{}/hugepages/hugepages-{}kB/{}_hugepages", node, oneGbPages ? "1048576" : "2048", nr ? "nr" : "free");
|
||||
return fmt::format("/sys/devices/system/node/node{}/hugepages/hugepages-{}kB/{}_hugepages", node, hugePageSize / 1024, nr ? "nr" : "free");
|
||||
}
|
||||
|
||||
|
||||
static inline bool write_nr_hugepages(uint32_t node, bool oneGbPages, uint64_t count) { return LinuxMemory::write(sysfs_path(node, oneGbPages, true).c_str(), count); }
|
||||
static inline int64_t free_hugepages(uint32_t node, bool oneGbPages) { return LinuxMemory::read(sysfs_path(node, oneGbPages, false).c_str()); }
|
||||
static inline int64_t nr_hugepages(uint32_t node, bool oneGbPages) { return LinuxMemory::read(sysfs_path(node, oneGbPages, true).c_str()); }
|
||||
static inline bool write_nr_hugepages(uint32_t node, size_t hugePageSize, uint64_t count) { return LinuxMemory::write(sysfs_path(node, hugePageSize, true).c_str(), count); }
|
||||
static inline int64_t free_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, false).c_str()); }
|
||||
static inline int64_t nr_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, true).c_str()); }
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
bool xmrig::LinuxMemory::reserve(size_t size, uint32_t node, bool oneGbPages)
|
||||
bool xmrig::LinuxMemory::reserve(size_t size, uint32_t node, size_t hugePageSize)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
|
||||
const size_t pageSize = oneGbPages ? oneGiB : twoMiB;
|
||||
const size_t required = VirtualMemory::align(size, pageSize) / pageSize;
|
||||
const size_t required = VirtualMemory::align(size, hugePageSize) / hugePageSize;
|
||||
|
||||
const auto available = free_hugepages(node, oneGbPages);
|
||||
const auto available = free_hugepages(node, hugePageSize);
|
||||
if (available < 0 || static_cast<size_t>(available) >= required) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return write_nr_hugepages(node, oneGbPages, std::max<size_t>(nr_hugepages(node, oneGbPages), 0) + (required - available));
|
||||
return write_nr_hugepages(node, hugePageSize, std::max<size_t>(nr_hugepages(node, hugePageSize), 0) + (required - available));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -30,7 +30,7 @@ namespace xmrig {
|
||||
class LinuxMemory
|
||||
{
|
||||
public:
|
||||
static bool reserve(size_t size, uint32_t node, bool oneGbPages = false);
|
||||
static bool reserve(size_t size, uint32_t node, size_t hugePageSize);
|
||||
|
||||
static bool write(const char *path, uint64_t value);
|
||||
static int64_t read(const char *path);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -36,16 +36,19 @@
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static IMemoryPool *pool = nullptr;
|
||||
|
||||
size_t VirtualMemory::m_hugePageSize = VirtualMemory::kDefaultHugePageSize;
|
||||
static IMemoryPool *pool = nullptr;
|
||||
static std::mutex mutex;
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node, size_t alignSize) :
|
||||
m_size(align(size)),
|
||||
m_capacity(m_size),
|
||||
m_node(node)
|
||||
m_size(alignToHugePageSize(size)),
|
||||
m_node(node),
|
||||
m_capacity(m_size)
|
||||
{
|
||||
if (usePool) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
@@ -114,18 +117,18 @@ void xmrig::VirtualMemory::destroy()
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::init(size_t poolSize, bool hugePages)
|
||||
void xmrig::VirtualMemory::init(size_t poolSize, size_t hugePageSize)
|
||||
{
|
||||
if (!pool) {
|
||||
osInit(hugePages);
|
||||
osInit(hugePageSize);
|
||||
}
|
||||
|
||||
# ifdef XMRIG_FEATURE_HWLOC
|
||||
if (Cpu::info()->nodes() > 1) {
|
||||
pool = new NUMAMemoryPool(align(poolSize, Cpu::info()->nodes()), hugePages);
|
||||
pool = new NUMAMemoryPool(align(poolSize, Cpu::info()->nodes()), hugePageSize > 0);
|
||||
} else
|
||||
# endif
|
||||
{
|
||||
pool = new MemoryPool(poolSize, hugePages);
|
||||
pool = new MemoryPool(poolSize, hugePageSize > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -39,6 +39,9 @@ class VirtualMemory
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(VirtualMemory)
|
||||
|
||||
constexpr static size_t kDefaultHugePageSize = 2U * 1024U * 1024U;
|
||||
constexpr static size_t kOneGiB = 1024U * 1024U * 1024U;
|
||||
|
||||
VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node = 0, size_t alignSize = 64);
|
||||
~VirtualMemory();
|
||||
|
||||
@@ -65,9 +68,11 @@ public:
|
||||
static void destroy();
|
||||
static void flushInstructionCache(void *p, size_t size);
|
||||
static void freeLargePagesMemory(void *p, size_t size);
|
||||
static void init(size_t poolSize, bool hugePages);
|
||||
static void init(size_t poolSize, size_t hugePageSize);
|
||||
|
||||
static inline constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; }
|
||||
static inline constexpr size_t align(size_t pos, size_t align = kDefaultHugePageSize) { return ((pos - 1) / align + 1) * align; }
|
||||
static inline size_t alignToHugePageSize(size_t pos) { return align(pos, hugePageSize()); }
|
||||
static inline size_t hugePageSize() { return m_hugePageSize; }
|
||||
|
||||
private:
|
||||
enum Flags {
|
||||
@@ -78,15 +83,17 @@ private:
|
||||
FLAG_MAX
|
||||
};
|
||||
|
||||
static void osInit(bool hugePages);
|
||||
static void osInit(size_t hugePageSize);
|
||||
|
||||
bool allocateLargePagesMemory();
|
||||
bool allocateOneGbPagesMemory();
|
||||
void freeLargePagesMemory();
|
||||
|
||||
static size_t m_hugePageSize;
|
||||
|
||||
const size_t m_size;
|
||||
size_t m_capacity;
|
||||
const uint32_t m_node;
|
||||
size_t m_capacity;
|
||||
std::bitset<FLAG_MAX> m_flags;
|
||||
uint8_t *m_scratchpad = nullptr;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -18,13 +18,14 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sys/mman.h>
|
||||
|
||||
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "crypto/common/portable/mm_malloc.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <sys/mman.h>
|
||||
|
||||
|
||||
#ifdef XMRIG_OS_APPLE
|
||||
@@ -42,14 +43,21 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(XMRIG_OS_LINUX)
|
||||
# if (defined(MAP_HUGE_1GB) || defined(MAP_HUGE_SHIFT))
|
||||
# define XMRIG_HAS_1GB_PAGES
|
||||
# endif
|
||||
#ifdef XMRIG_OS_LINUX
|
||||
# include "crypto/common/LinuxMemory.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MAP_HUGE_SHIFT
|
||||
# define MAP_HUGE_SHIFT 26
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MAP_HUGE_MASK
|
||||
# define MAP_HUGE_MASK 0x3f
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_SECURE_JIT
|
||||
# define SECURE_PROT_EXEC 0
|
||||
#else
|
||||
@@ -57,6 +65,19 @@
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
#ifdef XMRIG_OS_LINUX
|
||||
static inline int hugePagesFlag(size_t size)
|
||||
{
|
||||
return (static_cast<int>(log2(size)) & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
bool xmrig::VirtualMemory::isHugepagesAvailable()
|
||||
{
|
||||
# if defined(XMRIG_OS_MACOS) && defined(XMRIG_ARM)
|
||||
@@ -69,7 +90,7 @@ bool xmrig::VirtualMemory::isHugepagesAvailable()
|
||||
|
||||
bool xmrig::VirtualMemory::isOneGbPagesAvailable()
|
||||
{
|
||||
# ifdef XMRIG_HAS_1GB_PAGES
|
||||
# ifdef XMRIG_OS_LINUX
|
||||
return Cpu::info()->hasOneGbPages();
|
||||
# else
|
||||
return false;
|
||||
@@ -126,18 +147,10 @@ void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages
|
||||
|
||||
# else
|
||||
|
||||
# if defined(MAP_HUGE_2MB)
|
||||
constexpr int flag_2mb = MAP_HUGE_2MB;
|
||||
# elif defined(MAP_HUGE_SHIFT)
|
||||
constexpr int flag_2mb = (21 << MAP_HUGE_SHIFT);
|
||||
# else
|
||||
constexpr int flag_2mb = 0;
|
||||
# endif
|
||||
|
||||
void *mem = nullptr;
|
||||
|
||||
if (hugePages) {
|
||||
mem = mmap(0, align(size), PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | flag_2mb, -1, 0);
|
||||
mem = mmap(0, align(size), PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | hugePagesFlag(hugePageSize()), -1, 0);
|
||||
}
|
||||
|
||||
if (!mem) {
|
||||
@@ -157,17 +170,7 @@ void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size)
|
||||
# elif defined(__FreeBSD__)
|
||||
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0);
|
||||
# else
|
||||
|
||||
# if defined(MAP_HUGE_2MB)
|
||||
constexpr int flag_2mb = MAP_HUGE_2MB;
|
||||
# elif defined(MAP_HUGE_SHIFT)
|
||||
constexpr int flag_2mb = (21 << MAP_HUGE_SHIFT);
|
||||
# else
|
||||
constexpr int flag_2mb = 0;
|
||||
# endif
|
||||
|
||||
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | flag_2mb, 0, 0);
|
||||
|
||||
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | hugePagesFlag(hugePageSize()), 0, 0);
|
||||
# endif
|
||||
|
||||
return mem == MAP_FAILED ? nullptr : mem;
|
||||
@@ -176,17 +179,9 @@ void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size)
|
||||
|
||||
void *xmrig::VirtualMemory::allocateOneGbPagesMemory(size_t size)
|
||||
{
|
||||
# ifdef XMRIG_HAS_1GB_PAGES
|
||||
# ifdef XMRIG_OS_LINUX
|
||||
if (isOneGbPagesAvailable()) {
|
||||
# if defined(MAP_HUGE_1GB)
|
||||
constexpr int flag_1gb = MAP_HUGE_1GB;
|
||||
# elif defined(MAP_HUGE_SHIFT)
|
||||
constexpr int flag_1gb = (30 << MAP_HUGE_SHIFT);
|
||||
# else
|
||||
constexpr int flag_1gb = 0;
|
||||
# endif
|
||||
|
||||
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | flag_1gb, 0, 0);
|
||||
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | hugePagesFlag(kOneGiB), 0, 0);
|
||||
|
||||
return mem == MAP_FAILED ? nullptr : mem;
|
||||
}
|
||||
@@ -212,15 +207,18 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t size)
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::osInit(bool)
|
||||
void xmrig::VirtualMemory::osInit(size_t hugePageSize)
|
||||
{
|
||||
if (hugePageSize) {
|
||||
m_hugePageSize = hugePageSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::VirtualMemory::allocateLargePagesMemory()
|
||||
{
|
||||
# if defined(XMRIG_OS_LINUX)
|
||||
LinuxMemory::reserve(m_size, m_node);
|
||||
# ifdef XMRIG_OS_LINUX
|
||||
LinuxMemory::reserve(m_size, m_node, hugePageSize());
|
||||
# endif
|
||||
|
||||
m_scratchpad = static_cast<uint8_t*>(allocateLargePagesMemory(m_size));
|
||||
@@ -242,8 +240,8 @@ bool xmrig::VirtualMemory::allocateLargePagesMemory()
|
||||
|
||||
bool xmrig::VirtualMemory::allocateOneGbPagesMemory()
|
||||
{
|
||||
# if defined(XMRIG_HAS_1GB_PAGES)
|
||||
LinuxMemory::reserve(m_size, m_node, true);
|
||||
# ifdef XMRIG_OS_LINUX
|
||||
LinuxMemory::reserve(m_size, m_node, kOneGiB);
|
||||
# endif
|
||||
|
||||
m_scratchpad = static_cast<uint8_t*>(allocateOneGbPagesMemory(m_size));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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,9 +24,9 @@
|
||||
#include <tchar.h>
|
||||
|
||||
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "crypto/common/portable/mm_malloc.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_SECURE_JIT
|
||||
@@ -233,9 +233,9 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t)
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::osInit(bool hugePages)
|
||||
void xmrig::VirtualMemory::osInit(size_t hugePageSize)
|
||||
{
|
||||
if (hugePages) {
|
||||
if (hugePageSize) {
|
||||
hugepagesAvailable = TrySetLockPagesPrivilege();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ hashAndFillAes1Rx4_impl* softAESImpl = &hashAndFillAes1Rx4<1,1>;
|
||||
|
||||
void SelectSoftAESImpl(size_t threadsCount)
|
||||
{
|
||||
constexpr int test_length_ms = 100;
|
||||
constexpr uint64_t test_length_ms = 100;
|
||||
const std::array<hashAndFillAes1Rx4_impl *, 4> impl = {
|
||||
&hashAndFillAes1Rx4<1,1>,
|
||||
&hashAndFillAes1Rx4<2,1>,
|
||||
|
||||
@@ -171,7 +171,7 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con
|
||||
emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos);
|
||||
|
||||
# ifndef XMRIG_OS_APPLE
|
||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
|
||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), codePos - MainLoopBegin);
|
||||
# endif
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration
|
||||
emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 10), code, codePos);
|
||||
|
||||
# ifndef XMRIG_OS_APPLE
|
||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
|
||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), codePos - MainLoopBegin);
|
||||
# endif
|
||||
}
|
||||
|
||||
@@ -364,7 +364,7 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N])
|
||||
codePos += p2 - p1;
|
||||
|
||||
# ifndef XMRIG_OS_APPLE
|
||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + CodeSize), reinterpret_cast<char*>(code + codePos));
|
||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + CodeSize), codePos - MainLoopBegin);
|
||||
# endif
|
||||
}
|
||||
|
||||
@@ -401,6 +401,10 @@ void JitCompilerA64::allocate(size_t size)
|
||||
code = static_cast<uint8_t*>(allocExecutableMemory(allocatedSize, hugePages));
|
||||
|
||||
memcpy(code, reinterpret_cast<const void *>(randomx_program_aarch64), CodeSize);
|
||||
|
||||
# ifndef XMRIG_OS_APPLE
|
||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code), CodeSize);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2019-2020, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2019-2020, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
Copyright (c) 2019-2021, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2019-2021, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "crypto/rx/Profiler.h"
|
||||
|
||||
#ifdef XMRIG_FIX_RYZEN
|
||||
# include "crypto/rx/Rx.h"
|
||||
# include "crypto/rx/RxFix.h"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -417,17 +417,15 @@ namespace randomx {
|
||||
|
||||
void JitCompilerX86::generateProgramPrologue(Program& prog, ProgramConfiguration& pcfg) {
|
||||
codePos = ADDR(randomx_program_prologue_first_load) - ADDR(randomx_program_prologue);
|
||||
code[codePos + 2] = 0xc0 + pcfg.readReg0;
|
||||
code[codePos + 5] = 0xc0 + pcfg.readReg1;
|
||||
*(uint32_t*)(code + codePos + 10) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
|
||||
*(uint32_t*)(code + codePos + 20) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
|
||||
*(uint32_t*)(code + codePos + 4) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
|
||||
*(uint32_t*)(code + codePos + 14) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
|
||||
if (hasAVX) {
|
||||
uint32_t* p = (uint32_t*)(code + codePos + 67);
|
||||
uint32_t* p = (uint32_t*)(code + codePos + 61);
|
||||
*p = (*p & 0xFF000000U) | 0x0077F8C5U;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
xmrig::Rx::setMainLoopBounds(mainLoopBounds);
|
||||
xmrig::RxFix::setMainLoopBounds(mainLoopBounds);
|
||||
# endif
|
||||
|
||||
memcpy(code + prologueSize - 48, &pcfg.eMask, sizeof(pcfg.eMask));
|
||||
|
||||
@@ -93,8 +93,6 @@ DECL(randomx_program_prologue):
|
||||
movapd xmm15, xmmword ptr [scaleMask+rip]
|
||||
|
||||
DECL(randomx_program_prologue_first_load):
|
||||
xor rax, r8
|
||||
xor rax, r8
|
||||
mov rdx, rax
|
||||
and eax, RANDOMX_SCRATCHPAD_MASK
|
||||
ror rdx, 32
|
||||
|
||||
@@ -81,8 +81,6 @@ randomx_program_prologue PROC
|
||||
randomx_program_prologue ENDP
|
||||
|
||||
randomx_program_prologue_first_load PROC
|
||||
xor rax, r8
|
||||
xor rax, r8
|
||||
mov rdx, rax
|
||||
and eax, RANDOMX_SCRATCHPAD_MASK
|
||||
ror rdx, 32
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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,6 +27,12 @@
|
||||
#include "crypto/randomx/aes_hash.hpp"
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_MSR
|
||||
# include "crypto/rx/RxFix.h"
|
||||
# include "crypto/rx/RxMsr.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
@@ -34,8 +40,6 @@ class RxPrivate;
|
||||
|
||||
|
||||
static bool osInitialized = false;
|
||||
static bool msrInitialized = false;
|
||||
static bool msrEnabled = false;
|
||||
static RxPrivate *d_ptr = nullptr;
|
||||
|
||||
|
||||
@@ -65,9 +69,9 @@ xmrig::RxDataset *xmrig::Rx::dataset(const Job &job, uint32_t nodeId)
|
||||
|
||||
void xmrig::Rx::destroy()
|
||||
{
|
||||
if (osInitialized) {
|
||||
msrDestroy();
|
||||
}
|
||||
# ifdef XMRIG_FEATURE_MSR
|
||||
RxMsr::destroy();
|
||||
# endif
|
||||
|
||||
delete d_ptr;
|
||||
|
||||
@@ -85,11 +89,9 @@ template<typename T>
|
||||
bool xmrig::Rx::init(const T &seed, const RxConfig &config, const CpuConfig &cpu)
|
||||
{
|
||||
if (seed.algorithm().family() != Algorithm::RANDOM_X) {
|
||||
if (msrInitialized) {
|
||||
msrDestroy();
|
||||
msrInitialized = false;
|
||||
msrEnabled = false;
|
||||
}
|
||||
# ifdef XMRIG_FEATURE_MSR
|
||||
RxMsr::destroy();
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -98,13 +100,17 @@ bool xmrig::Rx::init(const T &seed, const RxConfig &config, const CpuConfig &cpu
|
||||
randomx_set_huge_pages_jit(cpu.isHugePagesJit());
|
||||
randomx_set_optimized_dataset_init(config.initDatasetAVX2());
|
||||
|
||||
if (!msrInitialized) {
|
||||
msrEnabled = msrInit(config, cpu.threads().get(seed.algorithm()).data());
|
||||
msrInitialized = true;
|
||||
# ifdef XMRIG_FEATURE_MSR
|
||||
if (!RxMsr::isInitialized()) {
|
||||
RxMsr::init(config, cpu.threads().get(seed.algorithm()).data());
|
||||
}
|
||||
# endif
|
||||
|
||||
if (!osInitialized) {
|
||||
setupMainLoopExceptionFrame();
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
RxFix::setupMainLoopExceptionFrame();
|
||||
# endif
|
||||
|
||||
if (!cpu.isHwAES()) {
|
||||
SelectSoftAESImpl(cpu.threads().get(seed.algorithm()).count());
|
||||
}
|
||||
@@ -131,24 +137,7 @@ bool xmrig::Rx::isReady(const T &seed)
|
||||
#ifdef XMRIG_FEATURE_MSR
|
||||
bool xmrig::Rx::isMSR()
|
||||
{
|
||||
return msrEnabled;
|
||||
}
|
||||
#else
|
||||
bool xmrig::Rx::msrInit(const RxConfig &, const std::vector<CpuThread> &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::msrDestroy()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef XMRIG_FIX_RYZEN
|
||||
void xmrig::Rx::setupMainLoopExceptionFrame()
|
||||
{
|
||||
return RxMsr::isEnabled();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -52,20 +52,11 @@ public:
|
||||
template<typename T> static bool init(const T &seed, const RxConfig &config, const CpuConfig &cpu);
|
||||
template<typename T> static bool isReady(const T &seed);
|
||||
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
static void setMainLoopBounds(const std::pair<const void*, const void*>& bounds);
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_MSR
|
||||
static bool isMSR();
|
||||
# else
|
||||
static constexpr bool isMSR() { return false; }
|
||||
# endif
|
||||
|
||||
private:
|
||||
static bool msrInit(const RxConfig &config, const std::vector<CpuThread>& threads);
|
||||
static void msrDestroy();
|
||||
static void setupMainLoopExceptionFrame();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_MSR
|
||||
# include "crypto/rx/msr/MsrItem.h"
|
||||
# include "hw/msr/MsrItem.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -113,7 +113,6 @@ private:
|
||||
|
||||
Mode readMode(const rapidjson::Value &value) const;
|
||||
|
||||
bool m_numa = true;
|
||||
bool m_oneGbPages = false;
|
||||
bool m_rdmsr = true;
|
||||
int m_threads = -1;
|
||||
@@ -123,6 +122,7 @@ private:
|
||||
ScratchpadPrefetchMode m_scratchpadPrefetchMode = ScratchpadPrefetchT0;
|
||||
|
||||
# ifdef XMRIG_FEATURE_HWLOC
|
||||
bool m_numa = true;
|
||||
std::vector<uint32_t> m_nodeset;
|
||||
# endif
|
||||
|
||||
|
||||
42
src/crypto/rx/RxFix.h
Normal file
42
src/crypto/rx/RxFix.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_RXFIX_H
|
||||
#define XMRIG_RXFIX_H
|
||||
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace xmrig
|
||||
{
|
||||
|
||||
|
||||
class RxFix
|
||||
{
|
||||
public:
|
||||
static void setMainLoopBounds(const std::pair<const void *, const void *> &bounds);
|
||||
static void setupMainLoopExceptionFrame();
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_RXFIX_H */
|
||||
71
src/crypto/rx/RxFix_linux.cpp
Normal file
71
src/crypto/rx/RxFix_linux.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto/rx/RxFix.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
||||
#include <csignal>
|
||||
#include <cstdlib>
|
||||
#include <ucontext.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static thread_local std::pair<const void*, const void*> mainLoopBounds = { nullptr, nullptr };
|
||||
|
||||
|
||||
static void MainLoopHandler(int sig, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
ucontext_t *ucp = (ucontext_t*) ucontext;
|
||||
|
||||
LOG_VERBOSE(YELLOW_BOLD("%s at %p"), (sig == SIGSEGV) ? "SIGSEGV" : "SIGILL", ucp->uc_mcontext.gregs[REG_RIP]);
|
||||
|
||||
void* p = reinterpret_cast<void*>(ucp->uc_mcontext.gregs[REG_RIP]);
|
||||
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
||||
|
||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||
ucp->uc_mcontext.gregs[REG_RIP] = reinterpret_cast<size_t>(loopBounds.second);
|
||||
}
|
||||
else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
||||
void xmrig::RxFix::setMainLoopBounds(const std::pair<const void *, const void *> &bounds)
|
||||
{
|
||||
mainLoopBounds = bounds;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::RxFix::setupMainLoopExceptionFrame()
|
||||
{
|
||||
struct sigaction act = {};
|
||||
act.sa_sigaction = MainLoopHandler;
|
||||
act.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
sigaction(SIGSEGV, &act, nullptr);
|
||||
sigaction(SIGILL, &act, nullptr);
|
||||
}
|
||||
74
src/crypto/rx/RxFix_win.cpp
Normal file
74
src/crypto/rx/RxFix_win.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto/rx/RxFix.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static thread_local std::pair<const void*, const void*> mainLoopBounds = { nullptr, nullptr };
|
||||
|
||||
|
||||
static LONG WINAPI MainLoopHandler(_EXCEPTION_POINTERS *ExceptionInfo)
|
||||
{
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == 0xC0000005) {
|
||||
const char* accessType;
|
||||
switch (ExceptionInfo->ExceptionRecord->ExceptionInformation[0]) {
|
||||
case 0: accessType = "read"; break;
|
||||
case 1: accessType = "write"; break;
|
||||
case 8: accessType = "DEP violation"; break;
|
||||
default: accessType = "unknown"; break;
|
||||
}
|
||||
LOG_VERBOSE(YELLOW_BOLD("[THREAD %u] Access violation at 0x%p: %s at address 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionAddress, accessType, ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
|
||||
}
|
||||
else {
|
||||
LOG_VERBOSE(YELLOW_BOLD("[THREAD %u] Exception 0x%08X at 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
|
||||
}
|
||||
|
||||
void* p = reinterpret_cast<void*>(ExceptionInfo->ContextRecord->Rip);
|
||||
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
||||
|
||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||
ExceptionInfo->ContextRecord->Rip = reinterpret_cast<DWORD64>(loopBounds.second);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
void xmrig::RxFix::setMainLoopBounds(const std::pair<const void *, const void *> &bounds)
|
||||
{
|
||||
mainLoopBounds = bounds;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::RxFix::setupMainLoopExceptionFrame()
|
||||
{
|
||||
AddVectoredExceptionHandler(1, MainLoopHandler);
|
||||
}
|
||||
183
src/crypto/rx/RxMsr.cpp
Normal file
183
src/crypto/rx/RxMsr.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto/rx/RxMsr.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "backend/cpu/CpuThread.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "crypto/rx/RxConfig.h"
|
||||
#include "hw/msr/Msr.h"
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
bool RxMsr::m_cacheQoS = false;
|
||||
bool RxMsr::m_enabled = false;
|
||||
bool RxMsr::m_initialized = false;
|
||||
|
||||
|
||||
static MsrItems items;
|
||||
|
||||
|
||||
#ifdef XMRIG_OS_WIN
|
||||
static constexpr inline int32_t get_cpu(int32_t) { return -1; }
|
||||
#else
|
||||
static constexpr inline int32_t get_cpu(int32_t cpu) { return cpu; }
|
||||
#endif
|
||||
|
||||
|
||||
static bool wrmsr(const MsrItems &preset, const std::vector<CpuThread> &threads, bool cache_qos, bool save)
|
||||
{
|
||||
auto msr = Msr::get();
|
||||
if (!msr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (save) {
|
||||
items.reserve(preset.size());
|
||||
|
||||
for (const auto &i : preset) {
|
||||
auto item = msr->read(i.reg());
|
||||
if (!item.isValid()) {
|
||||
items.clear();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_VERBOSE("%s " CYAN_BOLD("0x%08" PRIx32) CYAN(":0x%016" PRIx64) CYAN_BOLD(" -> 0x%016" PRIx64), Msr::tag(), i.reg(), item.value(), MsrItem::maskedValue(item.value(), i.value(), i.mask()));
|
||||
|
||||
items.emplace_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
// Which CPU cores will have access to the full L3 cache
|
||||
std::set<int32_t> cacheEnabled;
|
||||
bool cacheQoSDisabled = threads.empty();
|
||||
|
||||
if (cache_qos) {
|
||||
const auto &units = Cpu::info()->units();
|
||||
|
||||
for (const auto &t : threads) {
|
||||
const auto affinity = static_cast<int32_t>(t.affinity());
|
||||
|
||||
// If some thread has no affinity or wrong affinity, disable cache QoS
|
||||
if (affinity < 0 || std::find(units.begin(), units.end(), affinity) == units.end()) {
|
||||
cacheQoSDisabled = true;
|
||||
|
||||
LOG_WARN("%s " YELLOW_BOLD("cache QoS can only be enabled when all mining threads have affinity set"), Msr::tag());
|
||||
break;
|
||||
}
|
||||
|
||||
cacheEnabled.insert(affinity);
|
||||
}
|
||||
}
|
||||
|
||||
return msr->write([&msr, &preset, cache_qos, &cacheEnabled, cacheQoSDisabled](int32_t cpu) {
|
||||
for (const auto &item : preset) {
|
||||
if (!msr->write(item, get_cpu(cpu))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cache_qos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Assign Class Of Service 0 to current CPU core (default, full L3 cache available)
|
||||
if (cacheQoSDisabled || cacheEnabled.count(cpu)) {
|
||||
return msr->write(0xC8F, 0, get_cpu(cpu));
|
||||
}
|
||||
|
||||
// Disable L3 cache for Class Of Service 1
|
||||
if (!msr->write(0xC91, 0, get_cpu(cpu))) {
|
||||
// Some CPUs don't let set it to all zeros
|
||||
if (!msr->write(0xC91, 1, get_cpu(cpu))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign Class Of Service 1 to current CPU core
|
||||
return msr->write(0xC8F, 1ULL << 32, get_cpu(cpu));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
bool xmrig::RxMsr::init(const RxConfig &config, const std::vector<CpuThread> &threads)
|
||||
{
|
||||
if (isInitialized()) {
|
||||
return isEnabled();
|
||||
}
|
||||
|
||||
m_initialized = true;
|
||||
m_enabled = false;
|
||||
|
||||
const auto &preset = config.msrPreset();
|
||||
if (preset.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
m_cacheQoS = config.cacheQoS();
|
||||
|
||||
if (m_cacheQoS && !Cpu::info()->hasCatL3()) {
|
||||
LOG_WARN("%s " YELLOW_BOLD("this CPU doesn't support cat_l3, cache QoS is unavailable"), Msr::tag());
|
||||
|
||||
m_cacheQoS = false;
|
||||
}
|
||||
|
||||
if ((m_enabled = wrmsr(preset, threads, m_cacheQoS, config.rdmsr()))) {
|
||||
LOG_NOTICE("%s " GREEN_BOLD("register values for \"%s\" preset have been set successfully") BLACK_BOLD(" (%" PRIu64 " ms)"), Msr::tag(), config.msrPresetName(), Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
else {
|
||||
LOG_ERR("%s " RED_BOLD("FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW"), Msr::tag());
|
||||
}
|
||||
|
||||
return isEnabled();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::RxMsr::destroy()
|
||||
{
|
||||
if (!isInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_initialized = false;
|
||||
m_enabled = false;
|
||||
|
||||
if (items.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
if (!wrmsr(items, std::vector<CpuThread>(), m_cacheQoS, false)) {
|
||||
LOG_ERR("%s " RED_BOLD("failed to restore initial state" BLACK_BOLD(" (%" PRIu64 " ms)")), Msr::tag(), Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
}
|
||||
54
src/crypto/rx/RxMsr.h
Normal file
54
src/crypto/rx/RxMsr.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_RXMSR_H
|
||||
#define XMRIG_RXMSR_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace xmrig
|
||||
{
|
||||
|
||||
|
||||
class CpuThread;
|
||||
class RxConfig;
|
||||
|
||||
|
||||
class RxMsr
|
||||
{
|
||||
public:
|
||||
static inline bool isEnabled() { return m_enabled; }
|
||||
static inline bool isInitialized() { return m_initialized; }
|
||||
|
||||
static bool init(const RxConfig &config, const std::vector<CpuThread> &threads);
|
||||
static void destroy();
|
||||
|
||||
private:
|
||||
static bool m_cacheQoS;
|
||||
static bool m_enabled;
|
||||
static bool m_initialized;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_RXMSR_H */
|
||||
@@ -1,313 +0,0 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto/rx/Rx.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "backend/cpu/CpuThread.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "crypto/rx/RxConfig.h"
|
||||
|
||||
|
||||
#include <array>
|
||||
#include <cctype>
|
||||
#include <cinttypes>
|
||||
#include <cstdio>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ") " ";
|
||||
static MsrItems savedState;
|
||||
|
||||
|
||||
static inline int dir_filter(const struct dirent *dirp)
|
||||
{
|
||||
return isdigit(dirp->d_name[0]) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
bool rdmsr_on_cpu(uint32_t reg, uint32_t cpu, uint64_t &value)
|
||||
{
|
||||
char msr_file_name[64]{};
|
||||
|
||||
sprintf(msr_file_name, "/dev/cpu/%u/msr", cpu);
|
||||
int fd = open(msr_file_name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool success = pread(fd, &value, sizeof value, reg) == sizeof value;
|
||||
|
||||
close(fd);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
static MsrItem rdmsr(uint32_t reg)
|
||||
{
|
||||
uint64_t value = 0;
|
||||
if (!rdmsr_on_cpu(reg, 0, value)) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot read MSR 0x%08" PRIx32, tag, reg);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
return { reg, value };
|
||||
}
|
||||
|
||||
|
||||
static uint64_t get_masked_value(uint64_t old_value, uint64_t new_value, uint64_t mask)
|
||||
{
|
||||
return (new_value & mask) | (old_value & ~mask);
|
||||
}
|
||||
|
||||
|
||||
static bool wrmsr_on_cpu(uint32_t reg, uint32_t cpu, uint64_t value, uint64_t mask)
|
||||
{
|
||||
// If a bit in mask is set to 1, use new value, otherwise use old value
|
||||
if (mask != MsrItem::kNoMask) {
|
||||
uint64_t old_value;
|
||||
if (rdmsr_on_cpu(reg, cpu, old_value)) {
|
||||
value = get_masked_value(old_value, value, mask);
|
||||
}
|
||||
}
|
||||
|
||||
char msr_file_name[64]{};
|
||||
|
||||
sprintf(msr_file_name, "/dev/cpu/%u/msr", cpu);
|
||||
int fd = open(msr_file_name, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool success = pwrite(fd, &value, sizeof value, reg) == sizeof value;
|
||||
|
||||
close(fd);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
static bool wrmsr_on_all_cpus(uint32_t reg, uint64_t value, uint64_t mask, T&& callback)
|
||||
{
|
||||
struct dirent **namelist;
|
||||
int dir_entries = scandir("/dev/cpu", &namelist, dir_filter, 0);
|
||||
int errors = 0;
|
||||
|
||||
while (dir_entries--) {
|
||||
if (!callback(reg, strtoul(namelist[dir_entries]->d_name, nullptr, 10), value, mask)) {
|
||||
++errors;
|
||||
}
|
||||
|
||||
free(namelist[dir_entries]);
|
||||
}
|
||||
|
||||
free(namelist);
|
||||
|
||||
if (errors) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot set MSR 0x%08" PRIx32 " to 0x%08" PRIx64, tag, reg, value);
|
||||
}
|
||||
|
||||
return errors == 0;
|
||||
}
|
||||
|
||||
|
||||
static bool wrmsr_modprobe()
|
||||
{
|
||||
if (system("/sbin/modprobe msr allow_writes=on > /dev/null 2>&1") != 0) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "msr kernel module is not available", tag);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool wrmsr(const MsrItems& preset, const std::vector<CpuThread>& threads, bool cache_qos, bool save)
|
||||
{
|
||||
if (!wrmsr_modprobe()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (save) {
|
||||
for (const auto &i : preset) {
|
||||
auto item = rdmsr(i.reg());
|
||||
LOG_VERBOSE(CLEAR "%s" CYAN_BOLD("0x%08" PRIx32) CYAN(":0x%016" PRIx64) CYAN_BOLD(" -> 0x%016" PRIx64), tag, i.reg(), item.value(), get_masked_value(item.value(), i.value(), i.mask()));
|
||||
|
||||
if (item.isValid()) {
|
||||
savedState.emplace_back(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &i : preset) {
|
||||
if (!wrmsr_on_all_cpus(i.reg(), i.value(), i.mask(), [](uint32_t reg, uint32_t cpu, uint64_t value, uint64_t mask) { return wrmsr_on_cpu(reg, cpu, value, mask); })) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t n = Cpu::info()->threads();
|
||||
|
||||
// Which CPU cores will have access to the full L3 cache
|
||||
std::vector<bool> cacheEnabled(n, false);
|
||||
bool cacheQoSDisabled = threads.empty();
|
||||
|
||||
for (const CpuThread& t : threads) {
|
||||
// If some thread has no affinity or wrong affinity, disable cache QoS
|
||||
if ((t.affinity() < 0) || (t.affinity() >= n)) {
|
||||
cacheQoSDisabled = true;
|
||||
if (cache_qos) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "Cache QoS can only be enabled when all mining threads have affinity set", tag);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
cacheEnabled[t.affinity()] = true;
|
||||
}
|
||||
|
||||
if (cache_qos && !Cpu::info()->hasCatL3()) {
|
||||
if (!threads.empty()) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "This CPU doesn't support cat_l3, cache QoS is unavailable", tag);
|
||||
}
|
||||
cache_qos = false;
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
|
||||
if (cache_qos) {
|
||||
result = wrmsr_on_all_cpus(0xC8F, 0, MsrItem::kNoMask, [&cacheEnabled, cacheQoSDisabled](uint32_t, uint32_t cpu, uint64_t, uint64_t) {
|
||||
if (cacheQoSDisabled || (cpu >= cacheEnabled.size()) || cacheEnabled[cpu]) {
|
||||
// Assign Class Of Service 0 to current CPU core (default, full L3 cache available)
|
||||
if (!wrmsr_on_cpu(0xC8F, cpu, 0, MsrItem::kNoMask)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Disable L3 cache for Class Of Service 1
|
||||
if (!wrmsr_on_cpu(0xC91, cpu, 0, MsrItem::kNoMask)) {
|
||||
// Some CPUs don't let set it to all zeros
|
||||
if (!wrmsr_on_cpu(0xC91, cpu, 1, MsrItem::kNoMask)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign Class Of Service 1 to current CPU core
|
||||
if (!wrmsr_on_cpu(0xC8F, cpu, 1ULL << 32, MsrItem::kNoMask)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FIX_RYZEN
|
||||
static thread_local std::pair<const void*, const void*> mainLoopBounds = { nullptr, nullptr };
|
||||
|
||||
static void MainLoopHandler(int sig, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
ucontext_t *ucp = (ucontext_t*) ucontext;
|
||||
|
||||
LOG_VERBOSE(YELLOW_BOLD("%s at %p"), (sig == SIGSEGV) ? "SIGSEGV" : "SIGILL", ucp->uc_mcontext.gregs[REG_RIP]);
|
||||
|
||||
void* p = reinterpret_cast<void*>(ucp->uc_mcontext.gregs[REG_RIP]);
|
||||
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
||||
|
||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||
ucp->uc_mcontext.gregs[REG_RIP] = reinterpret_cast<size_t>(loopBounds.second);
|
||||
}
|
||||
else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void Rx::setMainLoopBounds(const std::pair<const void*, const void*>& bounds)
|
||||
{
|
||||
mainLoopBounds = bounds;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
bool xmrig::Rx::msrInit(const RxConfig &config, const std::vector<CpuThread> &threads)
|
||||
{
|
||||
const auto &preset = config.msrPreset();
|
||||
if (preset.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
if (wrmsr(preset, threads, config.cacheQoS(), config.rdmsr())) {
|
||||
LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for \"%s\" preset has been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, config.msrPresetName(), Chrono::steadyMSecs() - ts);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
LOG_ERR(CLEAR "%s" RED_BOLD_S "FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW", tag);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::msrDestroy()
|
||||
{
|
||||
if (savedState.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
if (!wrmsr(savedState, std::vector<CpuThread>(), true, false)) {
|
||||
LOG_ERR(CLEAR "%s" RED_BOLD_S "failed to restore initial state" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::setupMainLoopExceptionFrame()
|
||||
{
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
struct sigaction act = {};
|
||||
act.sa_sigaction = MainLoopHandler;
|
||||
act.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
sigaction(SIGSEGV, &act, nullptr);
|
||||
sigaction(SIGILL, &act, nullptr);
|
||||
# endif
|
||||
}
|
||||
@@ -1,431 +0,0 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2007-2009 hiyohiyo <https://openlibsys.org>, <hiyohiyo@crystalmark.info>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto/rx/Rx.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "backend/cpu/CpuThread.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "crypto/rx/RxConfig.h"
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
|
||||
#define SERVICE_NAME L"WinRing0_1_2_0"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static bool reuseDriver = false;
|
||||
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ") " ";
|
||||
static MsrItems savedState;
|
||||
|
||||
|
||||
static SC_HANDLE hManager;
|
||||
static SC_HANDLE hService;
|
||||
|
||||
|
||||
static bool wrmsr_uninstall_driver()
|
||||
{
|
||||
if (!hService) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
|
||||
if (!reuseDriver) {
|
||||
SERVICE_STATUS serviceStatus;
|
||||
|
||||
if (!ControlService(hService, SERVICE_CONTROL_STOP, &serviceStatus)) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (!DeleteService(hService)) {
|
||||
LOG_ERR(CLEAR "%s" RED_S "failed to remove WinRing0 driver, error %u", tag, GetLastError());
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
CloseServiceHandle(hService);
|
||||
hService = nullptr;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static HANDLE wrmsr_install_driver()
|
||||
{
|
||||
DWORD err = 0;
|
||||
|
||||
hManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
|
||||
if (!hManager) {
|
||||
err = GetLastError();
|
||||
|
||||
if (err == ERROR_ACCESS_DENIED) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "to write MSR registers Administrator privileges required.", tag);
|
||||
}
|
||||
else {
|
||||
LOG_ERR(CLEAR "%s" RED_S "failed to open service control manager, error %u", tag, err);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<wchar_t> dir;
|
||||
dir.resize(MAX_PATH);
|
||||
do {
|
||||
dir.resize(dir.size() * 2);
|
||||
GetModuleFileNameW(nullptr, dir.data(), dir.size());
|
||||
err = GetLastError();
|
||||
} while (err == ERROR_INSUFFICIENT_BUFFER);
|
||||
|
||||
if (err != ERROR_SUCCESS) {
|
||||
LOG_ERR(CLEAR "%s" RED_S "failed to get path to driver, error %u", tag, err);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (auto it = dir.end() - 1; it != dir.begin(); --it) {
|
||||
if ((*it == L'\\') || (*it == L'/')) {
|
||||
++it;
|
||||
*it = L'\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring driverPath = dir.data();
|
||||
driverPath += L"WinRing0x64.sys";
|
||||
|
||||
hService = OpenServiceW(hManager, SERVICE_NAME, SERVICE_ALL_ACCESS);
|
||||
if (hService) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW("service ") YELLOW_BOLD("WinRing0_1_2_0") YELLOW(" is already exists"), tag);
|
||||
|
||||
SERVICE_STATUS status;
|
||||
const auto rc = QueryServiceStatus(hService, &status);
|
||||
|
||||
if (rc) {
|
||||
DWORD dwBytesNeeded;
|
||||
|
||||
QueryServiceConfigA(hService, nullptr, 0, &dwBytesNeeded);
|
||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||
std::vector<BYTE> buffer(dwBytesNeeded);
|
||||
auto config = reinterpret_cast<LPQUERY_SERVICE_CONFIGA>(buffer.data());
|
||||
|
||||
if (QueryServiceConfigA(hService, config, buffer.size(), &dwBytesNeeded)) {
|
||||
LOG_INFO(CLEAR "%s" YELLOW("service path: ") YELLOW_BOLD("\"%s\""), tag, config->lpBinaryPathName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rc && status.dwCurrentState == SERVICE_RUNNING) {
|
||||
reuseDriver = true;
|
||||
}
|
||||
else if (!wrmsr_uninstall_driver()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!reuseDriver) {
|
||||
hService = CreateServiceW(hManager, SERVICE_NAME, SERVICE_NAME, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, driverPath.c_str(), nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||
if (!hService) {
|
||||
LOG_ERR(CLEAR "%s" RED_S "failed to install WinRing0 driver, error %u", tag, GetLastError());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!StartService(hService, 0, nullptr)) {
|
||||
err = GetLastError();
|
||||
if (err != ERROR_SERVICE_ALREADY_RUNNING) {
|
||||
if (err == ERROR_FILE_NOT_FOUND) {
|
||||
LOG_ERR(CLEAR "%s" RED("failed to start WinRing0 driver: ") RED_BOLD("\"WinRing0x64.sys not found\""), tag);
|
||||
}
|
||||
else {
|
||||
LOG_ERR(CLEAR "%s" RED_S "failed to start WinRing0 driver, error %u", tag, err);
|
||||
}
|
||||
|
||||
wrmsr_uninstall_driver();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE hDriver = CreateFileW(L"\\\\.\\" SERVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (!hDriver) {
|
||||
LOG_ERR(CLEAR "%s" RED_S "failed to connect to WinRing0 driver, error %u", tag, GetLastError());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return hDriver;
|
||||
}
|
||||
|
||||
|
||||
#define IOCTL_READ_MSR CTL_CODE(40000, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_WRITE_MSR CTL_CODE(40000, 0x822, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
|
||||
static bool rdmsr(HANDLE driver, uint32_t reg, uint64_t &value)
|
||||
{
|
||||
DWORD size = 0;
|
||||
|
||||
return DeviceIoControl(driver, IOCTL_READ_MSR, ®, sizeof(reg), &value, sizeof(value), &size, nullptr) != 0;
|
||||
}
|
||||
|
||||
|
||||
static MsrItem rdmsr(HANDLE driver, uint32_t reg)
|
||||
{
|
||||
uint64_t value = 0;
|
||||
if (!rdmsr(driver, reg, value)) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot read MSR 0x%08" PRIx32, tag, reg);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
return { reg, value };
|
||||
}
|
||||
|
||||
|
||||
static uint64_t get_masked_value(uint64_t old_value, uint64_t new_value, uint64_t mask)
|
||||
{
|
||||
return (new_value & mask) | (old_value & ~mask);
|
||||
}
|
||||
|
||||
|
||||
static bool wrmsr(HANDLE driver, uint32_t reg, uint64_t value, uint64_t mask)
|
||||
{
|
||||
struct {
|
||||
uint32_t reg = 0;
|
||||
uint32_t value[2]{};
|
||||
} input;
|
||||
|
||||
static_assert(sizeof(input) == 12, "Invalid struct size for WinRing0 driver");
|
||||
|
||||
// If a bit in mask is set to 1, use new value, otherwise use old value
|
||||
if (mask != MsrItem::kNoMask) {
|
||||
uint64_t old_value;
|
||||
if (rdmsr(driver, reg, old_value)) {
|
||||
value = get_masked_value(old_value, value, mask);
|
||||
}
|
||||
}
|
||||
|
||||
input.reg = reg;
|
||||
*(reinterpret_cast<uint64_t*>(input.value)) = value;
|
||||
|
||||
DWORD output;
|
||||
DWORD k;
|
||||
|
||||
if (!DeviceIoControl(driver, IOCTL_WRITE_MSR, &input, sizeof(input), &output, sizeof(output), &k, nullptr)) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot set MSR 0x%08" PRIx32 " to 0x%08" PRIx64, tag, reg, value);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool wrmsr(const MsrItems &preset, const std::vector<CpuThread>& threads, bool cache_qos, bool save)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
HANDLE driver = wrmsr_install_driver();
|
||||
if (!driver) {
|
||||
wrmsr_uninstall_driver();
|
||||
|
||||
if (hManager) {
|
||||
CloseServiceHandle(hManager);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (save) {
|
||||
for (const auto &i : preset) {
|
||||
auto item = rdmsr(driver, i.reg());
|
||||
LOG_VERBOSE(CLEAR "%s" CYAN_BOLD("0x%08" PRIx32) CYAN(":0x%016" PRIx64) CYAN_BOLD(" -> 0x%016" PRIx64), tag, i.reg(), item.value(), get_masked_value(item.value(), i.value(), i.mask()));
|
||||
|
||||
if (item.isValid()) {
|
||||
savedState.emplace_back(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t n = Cpu::info()->threads();
|
||||
|
||||
// Which CPU cores will have access to the full L3 cache
|
||||
std::vector<bool> cacheEnabled(n, false);
|
||||
bool cacheQoSDisabled = threads.empty();
|
||||
|
||||
for (const CpuThread& t : threads) {
|
||||
// If some thread has no affinity or wrong affinity, disable cache QoS
|
||||
if ((t.affinity() < 0) || (t.affinity() >= n)) {
|
||||
cacheQoSDisabled = true;
|
||||
if (cache_qos) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "Cache QoS can only be enabled when all mining threads have affinity set", tag);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
cacheEnabled[t.affinity()] = true;
|
||||
}
|
||||
|
||||
if (cache_qos && !Cpu::info()->hasCatL3()) {
|
||||
if (!threads.empty()) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "This CPU doesn't support cat_l3, cache QoS is unavailable", tag);
|
||||
}
|
||||
cache_qos = false;
|
||||
}
|
||||
|
||||
std::thread wrmsr_thread([n, driver, &preset, &cacheEnabled, cache_qos, cacheQoSDisabled, &success]() {
|
||||
for (uint32_t i = 0; i < n; ++i) {
|
||||
if (!Platform::setThreadAffinity(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto &i : preset) {
|
||||
success &= wrmsr(driver, i.reg(), i.value(), i.mask());
|
||||
}
|
||||
|
||||
if (cache_qos) {
|
||||
if (cacheQoSDisabled || cacheEnabled[i]) {
|
||||
// Assign Class Of Service 0 to current CPU core (default, full L3 cache available)
|
||||
success &= wrmsr(driver, 0xC8F, 0, MsrItem::kNoMask);
|
||||
}
|
||||
else {
|
||||
// Disable L3 cache for Class Of Service 1
|
||||
if (!wrmsr(driver, 0xC91, 0, MsrItem::kNoMask)) {
|
||||
// Some CPUs don't let set it to all zeros
|
||||
if (!wrmsr(driver, 0xC91, 1, MsrItem::kNoMask)) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign Class Of Service 1 to current CPU core
|
||||
success &= wrmsr(driver, 0xC8F, 1ULL << 32, MsrItem::kNoMask);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
wrmsr_thread.join();
|
||||
|
||||
CloseHandle(driver);
|
||||
|
||||
wrmsr_uninstall_driver();
|
||||
CloseServiceHandle(hManager);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FIX_RYZEN
|
||||
static thread_local std::pair<const void*, const void*> mainLoopBounds = { nullptr, nullptr };
|
||||
|
||||
static LONG WINAPI MainLoopHandler(_EXCEPTION_POINTERS *ExceptionInfo)
|
||||
{
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == 0xC0000005) {
|
||||
const char* accessType;
|
||||
switch (ExceptionInfo->ExceptionRecord->ExceptionInformation[0]) {
|
||||
case 0: accessType = "read"; break;
|
||||
case 1: accessType = "write"; break;
|
||||
case 8: accessType = "DEP violation"; break;
|
||||
default: accessType = "unknown"; break;
|
||||
}
|
||||
LOG_VERBOSE(YELLOW_BOLD("[THREAD %u] Access violation at 0x%p: %s at address 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionAddress, accessType, ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
|
||||
}
|
||||
else {
|
||||
LOG_VERBOSE(YELLOW_BOLD("[THREAD %u] Exception 0x%08X at 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
|
||||
}
|
||||
|
||||
void* p = reinterpret_cast<void*>(ExceptionInfo->ContextRecord->Rip);
|
||||
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
||||
|
||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||
ExceptionInfo->ContextRecord->Rip = reinterpret_cast<DWORD64>(loopBounds.second);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void Rx::setMainLoopBounds(const std::pair<const void*, const void*>& bounds)
|
||||
{
|
||||
mainLoopBounds = bounds;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
bool xmrig::Rx::msrInit(const RxConfig &config, const std::vector<CpuThread>& threads)
|
||||
{
|
||||
const auto &preset = config.msrPreset();
|
||||
if (preset.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
if (wrmsr(preset, threads, config.cacheQoS(), config.rdmsr())) {
|
||||
LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for \"%s\" preset has been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, config.msrPresetName(), Chrono::steadyMSecs() - ts);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_ERR(CLEAR "%s" RED_BOLD_S "FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW", tag);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::msrDestroy()
|
||||
{
|
||||
if (savedState.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
if (!wrmsr(savedState, std::vector<CpuThread>(), true, false)) {
|
||||
LOG_ERR(CLEAR "%s" RED_BOLD_S "failed to restore initial state" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::setupMainLoopExceptionFrame()
|
||||
{
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
AddVectoredExceptionHandler(1, MainLoopHandler);
|
||||
# endif
|
||||
}
|
||||
@@ -34,7 +34,7 @@
|
||||
* Example of how it works for the setting of 1%:
|
||||
* You miner will mine into your usual pool for random time (in range from 49.5 to 148.5 minutes),
|
||||
* then switch to the developer's pool for 1 minute, then switch again to your pool for 99 minutes
|
||||
* and then switch agaiin to developer's pool for 1 minute, these rounds will continue until miner working.
|
||||
* and then switch again to developer's pool for 1 minute, these rounds will continue until miner working.
|
||||
*
|
||||
* Randomised only first round, to prevent waves on the donation pool.
|
||||
*
|
||||
|
||||
45
src/hw/api/HwApi.cpp
Normal file
45
src/hw/api/HwApi.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "hw/api/HwApi.h"
|
||||
#include "base/api/interfaces/IApiRequest.h"
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_DMI
|
||||
# include "hw/dmi/DmiReader.h"
|
||||
#endif
|
||||
|
||||
|
||||
void xmrig::HwApi::onRequest(IApiRequest &request)
|
||||
{
|
||||
if (request.method() == IApiRequest::METHOD_GET) {
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
if (request.url() == "/2/dmi") {
|
||||
if (!m_dmi) {
|
||||
m_dmi = std::make_shared<DmiReader>();
|
||||
m_dmi->read();
|
||||
}
|
||||
|
||||
request.accept();
|
||||
m_dmi->toJSON(request.reply(), request.doc());
|
||||
}
|
||||
# endif
|
||||
}
|
||||
}
|
||||
53
src/hw/api/HwApi.h
Normal file
53
src/hw/api/HwApi.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_HWAPI_H
|
||||
#define XMRIG_HWAPI_H
|
||||
|
||||
|
||||
#include "base/api/interfaces/IApiListener.h"
|
||||
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
struct DmiReader;
|
||||
|
||||
|
||||
class HwApi : public IApiListener
|
||||
{
|
||||
public:
|
||||
HwApi() = default;
|
||||
|
||||
protected:
|
||||
void onRequest(IApiRequest &request) override;
|
||||
|
||||
private:
|
||||
# ifdef XMRIG_FEATURE_DMI
|
||||
std::shared_ptr<DmiReader> m_dmi;
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_HWAPI_H */
|
||||
11
src/hw/api/api.cmake
Normal file
11
src/hw/api/api.cmake
Normal file
@@ -0,0 +1,11 @@
|
||||
if (WITH_HTTP)
|
||||
add_definitions(/DXMRIG_FEATURE_DMI)
|
||||
|
||||
list(APPEND HEADERS
|
||||
src/hw/api/HwApi.h
|
||||
)
|
||||
|
||||
list(APPEND SOURCES
|
||||
src/hw/api/HwApi.cpp
|
||||
)
|
||||
endif()
|
||||
50
src/hw/dmi/DmiBoard.cpp
Normal file
50
src/hw/dmi/DmiBoard.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "hw/dmi/DmiBoard.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "hw/dmi/DmiTools.h"
|
||||
|
||||
|
||||
void xmrig::DmiBoard::decode(dmi_header *h)
|
||||
{
|
||||
if (h->length < 0x08) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_vendor = dmi_string(h, 0x04);
|
||||
m_product = dmi_string(h, 0x05);
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_API
|
||||
rapidjson::Value xmrig::DmiBoard::toJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
Value out(kObjectType);
|
||||
out.AddMember("vendor", m_vendor.toJSON(doc), allocator);
|
||||
out.AddMember("product", m_product.toJSON(doc), allocator);
|
||||
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
58
src/hw/dmi/DmiBoard.h
Normal file
58
src/hw/dmi/DmiBoard.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_DMIBOARD_H
|
||||
#define XMRIG_DMIBOARD_H
|
||||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
struct dmi_header;
|
||||
|
||||
|
||||
class DmiBoard
|
||||
{
|
||||
public:
|
||||
DmiBoard() = default;
|
||||
|
||||
inline const String &product() const { return m_product; }
|
||||
inline const String &vendor() const { return m_vendor; }
|
||||
inline bool isValid() const { return !m_product.isEmpty() && !m_vendor.isEmpty(); }
|
||||
|
||||
void decode(dmi_header *h);
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
# endif
|
||||
|
||||
private:
|
||||
String m_product;
|
||||
String m_vendor;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_DMIBOARD_H */
|
||||
243
src/hw/dmi/DmiMemory.cpp
Normal file
243
src/hw/dmi/DmiMemory.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "hw/dmi/DmiMemory.h"
|
||||
#include "3rdparty/fmt/format.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "hw/dmi/DmiTools.h"
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <regex>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static const char *kIdFormat = "DIMM_{}{}";
|
||||
|
||||
|
||||
static inline uint16_t dmi_memory_device_width(uint16_t code)
|
||||
{
|
||||
return (code == 0xFFFF || code == 0) ? 0 : code;
|
||||
}
|
||||
|
||||
|
||||
static const char *dmi_memory_device_form_factor(uint8_t code)
|
||||
{
|
||||
static const std::array<const char *, 0x10> form_factor
|
||||
{
|
||||
"Other",
|
||||
"Unknown",
|
||||
"SIMM",
|
||||
"SIP",
|
||||
"Chip",
|
||||
"DIP",
|
||||
"ZIP",
|
||||
"Proprietary Card",
|
||||
"DIMM",
|
||||
"TSOP",
|
||||
"Row Of Chips",
|
||||
"RIMM",
|
||||
"SODIMM",
|
||||
"SRIMM",
|
||||
"FB-DIMM",
|
||||
"Die"
|
||||
};
|
||||
|
||||
if (code >= 0x01 && code <= form_factor.size()) {
|
||||
return form_factor[code - 0x01];
|
||||
}
|
||||
|
||||
return form_factor[1];
|
||||
}
|
||||
|
||||
|
||||
static const char *dmi_memory_device_type(uint8_t code)
|
||||
{
|
||||
static const std::array<const char *, 0x23> type
|
||||
{
|
||||
"Other", /* 0x01 */
|
||||
"Unknown",
|
||||
"DRAM",
|
||||
"EDRAM",
|
||||
"VRAM",
|
||||
"SRAM",
|
||||
"RAM",
|
||||
"ROM",
|
||||
"Flash",
|
||||
"EEPROM",
|
||||
"FEPROM",
|
||||
"EPROM",
|
||||
"CDRAM",
|
||||
"3DRAM",
|
||||
"SDRAM",
|
||||
"SGRAM",
|
||||
"RDRAM",
|
||||
"DDR",
|
||||
"DDR2",
|
||||
"DDR2 FB-DIMM",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"DDR3",
|
||||
"FBD2",
|
||||
"DDR4",
|
||||
"LPDDR",
|
||||
"LPDDR2",
|
||||
"LPDDR3",
|
||||
"LPDDR4",
|
||||
"Logical non-volatile device",
|
||||
"HBM",
|
||||
"HBM2",
|
||||
"DDR5",
|
||||
"LPDDR5"
|
||||
};
|
||||
|
||||
if (code >= 0x01 && code <= type.size()) {
|
||||
return type[code - 0x01];
|
||||
}
|
||||
|
||||
return type[1];
|
||||
}
|
||||
|
||||
|
||||
static uint64_t dmi_memory_device_speed(uint16_t code1, uint32_t code2)
|
||||
{
|
||||
return (code1 == 0xFFFF) ? code2 : code1;
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
||||
xmrig::DmiMemory::DmiMemory(dmi_header *h)
|
||||
{
|
||||
if (h->length < 0x15) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_totalWidth = dmi_memory_device_width(dmi_get<uint16_t>(h, 0x08));
|
||||
m_width = dmi_memory_device_width(dmi_get<uint16_t>(h, 0x0A));
|
||||
|
||||
auto size = dmi_get<uint16_t>(h, 0x0C);
|
||||
if (h->length >= 0x20 && size == 0x7FFF) {
|
||||
m_size = (dmi_get<uint32_t>(h, 0x1C) & 0x7FFFFFFFUL) * 1024ULL * 1024ULL;
|
||||
}
|
||||
else if (size) {
|
||||
m_size = (1024ULL * (size & 0x7FFF) * ((size & 0x8000) ? 1 : 1024ULL));
|
||||
}
|
||||
|
||||
setId(dmi_string(h, 0x10), dmi_string(h, 0x11));
|
||||
|
||||
m_formFactor = h->data[0x0E];
|
||||
m_type = h->data[0x12];
|
||||
|
||||
if (!m_size || h->length < 0x17) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_speed = dmi_memory_device_speed(dmi_get<uint16_t>(h, 0x15), h->length >= 0x5C ? dmi_get<uint32_t>(h, 0x54) : 0) * 1000000ULL;
|
||||
|
||||
if (h->length < 0x1B) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_vendor = dmi_string(h, 0x17);
|
||||
m_product = dmi_string(h, 0x1A);
|
||||
|
||||
if (h->length < 0x1C) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_rank = h->data[0x1B] & 0x0F;
|
||||
|
||||
if (h->length < 0x22) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t configuredSpeed = dmi_memory_device_speed(dmi_get<uint16_t>(h, 0x20), h->length >= 0x5C ? dmi_get<uint32_t>(h, 0x58) : 0) * 1000000ULL;
|
||||
m_speed = configuredSpeed ? configuredSpeed : m_speed;
|
||||
|
||||
if (h->length < 0x28) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_voltage = dmi_get<uint16_t>(h, 0x26);
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::DmiMemory::formFactor() const
|
||||
{
|
||||
return dmi_memory_device_form_factor(m_formFactor);
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::DmiMemory::type() const
|
||||
{
|
||||
return dmi_memory_device_type(m_type);
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_API
|
||||
rapidjson::Value xmrig::DmiMemory::toJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
Value out(kObjectType);
|
||||
out.AddMember("id", id().toJSON(doc), allocator);
|
||||
out.AddMember("slot", m_slot.toJSON(doc), allocator);
|
||||
out.AddMember("type", StringRef(type()), allocator);
|
||||
out.AddMember("form_factor", StringRef(formFactor()), allocator);
|
||||
out.AddMember("size", m_size, allocator);
|
||||
out.AddMember("speed", m_speed, allocator);
|
||||
out.AddMember("rank", m_rank, allocator);
|
||||
out.AddMember("voltage", m_voltage, allocator);
|
||||
out.AddMember("width", m_width, allocator);
|
||||
out.AddMember("total_width", m_totalWidth, allocator);
|
||||
out.AddMember("vendor", m_vendor.toJSON(doc), allocator);
|
||||
out.AddMember("product", m_product.toJSON(doc), allocator);
|
||||
out.AddMember("bank", m_bank.toJSON(doc), allocator);
|
||||
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void xmrig::DmiMemory::setId(const char *slot, const char *bank)
|
||||
{
|
||||
m_slot = slot;
|
||||
m_bank = bank;
|
||||
|
||||
std::cmatch cm;
|
||||
if (std::regex_match(slot, cm, std::regex("^Channel([A-Z])[-_]DIMM(\\d+)$", std::regex_constants::icase))) {
|
||||
m_id = fmt::format(kIdFormat, cm.str(1), cm.str(2)).c_str();
|
||||
}
|
||||
else if (std::regex_search(bank, cm, std::regex("CHANNEL ([A-Z])$"))) {
|
||||
std::cmatch cm2;
|
||||
if (std::regex_match(slot, cm2, std::regex("^DIMM (\\d+)$"))) {
|
||||
m_id = fmt::format(kIdFormat, cm.str(1), cm2.str(1)).c_str();
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/hw/dmi/DmiMemory.h
Normal file
82
src/hw/dmi/DmiMemory.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_DMIMEMORY_H
|
||||
#define XMRIG_DMIMEMORY_H
|
||||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
struct dmi_header;
|
||||
|
||||
|
||||
class DmiMemory
|
||||
{
|
||||
public:
|
||||
DmiMemory() = default;
|
||||
DmiMemory(dmi_header *h);
|
||||
|
||||
inline bool isValid() const { return !m_slot.isEmpty(); }
|
||||
inline const String &bank() const { return m_bank; }
|
||||
inline const String &id() const { return m_id.isNull() ? m_slot : m_id; }
|
||||
inline const String &product() const { return m_product; }
|
||||
inline const String &slot() const { return m_slot; }
|
||||
inline const String &vendor() const { return m_vendor; }
|
||||
inline uint16_t totalWidth() const { return m_totalWidth; }
|
||||
inline uint16_t voltage() const { return m_voltage; }
|
||||
inline uint16_t width() const { return m_width; }
|
||||
inline uint64_t size() const { return m_size; }
|
||||
inline uint64_t speed() const { return m_speed; }
|
||||
inline uint8_t rank() const { return m_rank; }
|
||||
|
||||
const char *formFactor() const;
|
||||
const char *type() const;
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
# endif
|
||||
|
||||
private:
|
||||
void setId(const char *slot, const char *bank);
|
||||
|
||||
String m_bank;
|
||||
String m_id;
|
||||
String m_product;
|
||||
String m_slot;
|
||||
String m_vendor;
|
||||
uint16_t m_totalWidth = 0;
|
||||
uint16_t m_voltage = 0;
|
||||
uint16_t m_width = 0;
|
||||
uint64_t m_size = 0;
|
||||
uint64_t m_speed = 0;
|
||||
uint8_t m_formFactor = 0;
|
||||
uint8_t m_rank = 0;
|
||||
uint8_t m_type = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_DMIMEMORY_H */
|
||||
139
src/hw/dmi/DmiReader.cpp
Normal file
139
src/hw/dmi/DmiReader.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "hw/dmi/DmiReader.h"
|
||||
#include "3rdparty/fmt/core.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "hw/dmi/DmiTools.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static void dmi_get_header(dmi_header *h, uint8_t *data)
|
||||
{
|
||||
h->type = data[0];
|
||||
h->length = data[1];
|
||||
h->handle = dmi_get<uint16_t>(data + 2);
|
||||
h->data = data;
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_API
|
||||
rapidjson::Value xmrig::DmiReader::toJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
rapidjson::Value obj;
|
||||
toJSON(obj, doc);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DmiReader::toJSON(rapidjson::Value &out, rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
out.SetObject();
|
||||
|
||||
Value memory(kArrayType);
|
||||
memory.Reserve(m_memory.size(), allocator);
|
||||
|
||||
for (const auto &value : m_memory) {
|
||||
memory.PushBack(value.toJSON(doc), allocator);
|
||||
}
|
||||
|
||||
out.AddMember("smbios", Value(fmt::format("{}.{}.{}", m_version >> 16, m_version >> 8 & 0xff, m_version & 0xff).c_str(), allocator), allocator);
|
||||
out.AddMember("system", m_system.toJSON(doc), allocator);
|
||||
out.AddMember("board", m_board.toJSON(doc), allocator);
|
||||
out.AddMember("memory", memory, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool xmrig::DmiReader::decode(uint8_t *buf, const Cleanup &cleanup)
|
||||
{
|
||||
const bool rc = decode(buf);
|
||||
|
||||
cleanup();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::DmiReader::decode(uint8_t *buf)
|
||||
{
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t *data = buf;
|
||||
int i = 0;
|
||||
|
||||
while (data + 4 <= buf + m_size) {
|
||||
dmi_header h{};
|
||||
dmi_get_header(&h, data);
|
||||
|
||||
if (h.length < 4 || h.type == 127) {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
|
||||
uint8_t *next = data + h.length;
|
||||
while (static_cast<uint32_t>(next - buf + 1) < m_size && (next[0] != 0 || next[1] != 0)) {
|
||||
next++;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_OS_APPLE
|
||||
while ((unsigned long)(next - buf + 1) < m_size && (next[0] == 0 && next[1] == 0))
|
||||
# endif
|
||||
next += 2;
|
||||
|
||||
if (static_cast<uint32_t>(next - buf) > m_size) {
|
||||
data = next;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (h.type) {
|
||||
case 1:
|
||||
m_system.decode(&h);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_board.decode(&h);
|
||||
break;
|
||||
|
||||
case 17:
|
||||
m_memory.emplace_back(&h);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
data = next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
70
src/hw/dmi/DmiReader.h
Normal file
70
src/hw/dmi/DmiReader.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_DMIREADER_H
|
||||
#define XMRIG_DMIREADER_H
|
||||
|
||||
|
||||
#include "hw/dmi/DmiBoard.h"
|
||||
#include "hw/dmi/DmiMemory.h"
|
||||
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class DmiReader
|
||||
{
|
||||
public:
|
||||
DmiReader() = default;
|
||||
|
||||
inline const DmiBoard &board() const { return m_board; }
|
||||
inline const DmiBoard &system() const { return m_system; }
|
||||
inline const std::vector<DmiMemory> &memory() const { return m_memory; }
|
||||
inline uint32_t size() const { return m_size; }
|
||||
inline uint32_t version() const { return m_version; }
|
||||
|
||||
bool read();
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const;
|
||||
# endif
|
||||
|
||||
private:
|
||||
using Cleanup = std::function<void()>;
|
||||
|
||||
bool decode(uint8_t *buf, const Cleanup &cleanup);
|
||||
bool decode(uint8_t *buf);
|
||||
|
||||
DmiBoard m_board;
|
||||
DmiBoard m_system;
|
||||
std::vector<DmiMemory> m_memory;
|
||||
uint32_t m_size = 0;
|
||||
uint32_t m_version = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_DMIREADER_H */
|
||||
108
src/hw/dmi/DmiReader_mac.cpp
Normal file
108
src/hw/dmi/DmiReader_mac.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2002-2006 Hugo Weber <address@hidden>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "hw/dmi/DmiReader.h"
|
||||
#include "hw/dmi/DmiTools.h"
|
||||
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static int checksum(const uint8_t *buf, size_t len)
|
||||
{
|
||||
uint8_t sum = 0;
|
||||
|
||||
for (size_t a = 0; a < len; a++) {
|
||||
sum += buf[a];
|
||||
}
|
||||
|
||||
return (sum == 0);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t *dmi_table(uint32_t base, uint32_t &len, io_service_t service)
|
||||
{
|
||||
CFMutableDictionaryRef properties = nullptr;
|
||||
if (IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CFDataRef data;
|
||||
uint8_t *buf = nullptr;
|
||||
|
||||
if (CFDictionaryGetValueIfPresent(properties, CFSTR("SMBIOS"), (const void **)&data)) {
|
||||
assert(len == CFDataGetLength(data));
|
||||
|
||||
len = CFDataGetLength(data);
|
||||
buf = reinterpret_cast<uint8_t *>(malloc(len));
|
||||
|
||||
CFDataGetBytes(data, CFRangeMake(0, len), buf);
|
||||
}
|
||||
|
||||
CFRelease(properties);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t *smbios_decode(uint8_t *buf, uint32_t &size, uint32_t &version, io_service_t service)
|
||||
{
|
||||
if (buf[0x05] > 0x20 || !checksum(buf, buf[0x05]) || memcmp(buf + 0x10, "_DMI_", 5) != 0 || !checksum(buf + 0x10, 0x0F)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
version = ((buf[0x06] << 8) + buf[0x07]) << 8;
|
||||
size = dmi_get<uint16_t>(buf + 0x16);
|
||||
|
||||
return dmi_table(dmi_get<uint32_t>(buf + 0x18), size, service);
|
||||
}
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
bool xmrig::DmiReader::read()
|
||||
{
|
||||
mach_port_t port;
|
||||
IOMasterPort(MACH_PORT_NULL, &port);
|
||||
|
||||
io_service_t service = IOServiceGetMatchingService(port, IOServiceMatching("AppleSMBIOS"));
|
||||
if (service == MACH_PORT_NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CFDataRef data = reinterpret_cast<CFDataRef>(IORegistryEntryCreateCFProperty(service, CFSTR("SMBIOS-EPS"), kCFAllocatorDefault, kNilOptions));
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t buf[0x20]{};
|
||||
CFDataGetBytes(data, CFRangeMake(0, sizeof(buf)), buf);
|
||||
CFRelease(data);
|
||||
|
||||
auto smb = smbios_decode(buf, m_size, m_version, service);
|
||||
const bool rc = smb ? decode(smb) : false;
|
||||
|
||||
IOObjectRelease(service);
|
||||
|
||||
return rc;
|
||||
}
|
||||
415
src/hw/dmi/DmiReader_unix.cpp
Normal file
415
src/hw/dmi/DmiReader_unix.cpp
Normal file
@@ -0,0 +1,415 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "hw/dmi/DmiReader.h"
|
||||
#include "hw/dmi/DmiTools.h"
|
||||
|
||||
|
||||
#include <cerrno>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
# include <kenv.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define FLAG_NO_FILE_OFFSET (1 << 0)
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static const char *kMemDevice = "/dev/mem";
|
||||
static const char *kSysEntryFile = "/sys/firmware/dmi/tables/smbios_entry_point";
|
||||
static const char *kSysTableFile = "/sys/firmware/dmi/tables/DMI";
|
||||
|
||||
|
||||
static inline void safe_memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
# ifdef XMRIG_ARM
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
*((uint8_t *)dest + i) = *((const uint8_t *)src + i);
|
||||
}
|
||||
# else
|
||||
memcpy(dest, src, n);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int myread(int fd, uint8_t *buf, size_t count, const char *prefix)
|
||||
{
|
||||
ssize_t r = 1;
|
||||
size_t r2 = 0;
|
||||
|
||||
while (r2 != count && r != 0) {
|
||||
r = read(fd, buf + r2, count - r2);
|
||||
if (r == -1) {
|
||||
if (errno != EINTR) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
r2 += r;
|
||||
}
|
||||
}
|
||||
|
||||
if (r2 != count) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reads all of file from given offset, up to max_len bytes.
|
||||
* A buffer of at most max_len bytes is allocated by this function, and
|
||||
* needs to be freed by the caller.
|
||||
* This provides a similar usage model to mem_chunk()
|
||||
*
|
||||
* Returns a pointer to the allocated buffer, or NULL on error, and
|
||||
* sets max_len to the length actually read.
|
||||
*/
|
||||
static uint8_t *read_file(off_t base, size_t *max_len, const char *filename)
|
||||
{
|
||||
const int fd = open(filename, O_RDONLY);
|
||||
uint8_t *p = nullptr;
|
||||
|
||||
if (fd == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct stat statbuf{};
|
||||
if (fstat(fd, &statbuf) == 0) {
|
||||
if (base >= statbuf.st_size) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (*max_len > static_cast<size_t>(statbuf.st_size) - base) {
|
||||
*max_len = statbuf.st_size - base;
|
||||
}
|
||||
}
|
||||
|
||||
if ((p = reinterpret_cast<uint8_t *>(malloc(*max_len))) == nullptr) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (lseek(fd, base, SEEK_SET) == -1) {
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
if (myread(fd, p, *max_len, filename) == 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
err_free:
|
||||
free(p);
|
||||
p = nullptr;
|
||||
|
||||
out:
|
||||
close(fd);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy a physical memory chunk into a memory buffer.
|
||||
* This function allocates memory.
|
||||
*/
|
||||
static uint8_t *mem_chunk(off_t base, size_t len, const char *devmem)
|
||||
{
|
||||
const int fd = open(devmem, O_RDONLY);
|
||||
uint8_t *p = nullptr;
|
||||
uint8_t *mmp = nullptr;
|
||||
struct stat statbuf{};
|
||||
|
||||
# ifdef _SC_PAGESIZE
|
||||
const off_t mmoffset = base % sysconf(_SC_PAGESIZE);
|
||||
# else
|
||||
const off_t mmoffset = base % getpagesize();
|
||||
# endif
|
||||
|
||||
if (fd == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ((p = reinterpret_cast<uint8_t *>(malloc(len))) == nullptr) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fstat(fd, &statbuf) == -1) {
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
if (S_ISREG(statbuf.st_mode) && base + (off_t)len > statbuf.st_size) {
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
mmp = reinterpret_cast<uint8_t *>(mmap(nullptr, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset));
|
||||
if (mmp == MAP_FAILED) {
|
||||
goto try_read;
|
||||
}
|
||||
|
||||
safe_memcpy(p, mmp + mmoffset, len);
|
||||
munmap(mmp, mmoffset + len);
|
||||
|
||||
goto out;
|
||||
|
||||
try_read:
|
||||
if (lseek(fd, base, SEEK_SET) == -1) {
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
if (myread(fd, p, len, devmem) == 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
err_free:
|
||||
free(p);
|
||||
p = nullptr;
|
||||
|
||||
out:
|
||||
close(fd);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static int checksum(const uint8_t *buf, size_t len)
|
||||
{
|
||||
uint8_t sum = 0;
|
||||
|
||||
for (size_t a = 0; a < len; a++) {
|
||||
sum += buf[a];
|
||||
}
|
||||
|
||||
return (sum == 0);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t *dmi_table(off_t base, uint32_t &len, const char *devmem, uint32_t flags)
|
||||
{
|
||||
if (flags & FLAG_NO_FILE_OFFSET) {
|
||||
size_t size = len;
|
||||
auto buf = read_file(0, &size, devmem);
|
||||
len = size;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
return mem_chunk(base, len, devmem);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t *smbios3_decode(uint8_t *buf, const char *devmem, uint32_t &size, uint32_t &version, uint32_t flags)
|
||||
{
|
||||
if (buf[0x06] > 0x20 || !checksum(buf, buf[0x06])) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
version = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09];
|
||||
size = dmi_get<uint32_t>(buf + 0x0C);
|
||||
const u64 offset = dmi_get<u64>(buf + 0x10);
|
||||
|
||||
return dmi_table(((off_t)offset.h << 32) | offset.l, size, devmem, flags);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t *smbios_decode(uint8_t *buf, const char *devmem, uint32_t &size, uint32_t &version, uint32_t flags)
|
||||
{
|
||||
if (buf[0x05] > 0x20 || !checksum(buf, buf[0x05]) || memcmp(buf + 0x10, "_DMI_", 5) != 0 || !checksum(buf + 0x10, 0x0F)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
version = (buf[0x06] << 8) + buf[0x07];
|
||||
|
||||
switch (version) {
|
||||
case 0x021F:
|
||||
case 0x0221:
|
||||
version = 0x0203;
|
||||
break;
|
||||
|
||||
case 0x0233:
|
||||
version = 0x0206;
|
||||
break;
|
||||
}
|
||||
|
||||
version = version << 8;
|
||||
size = dmi_get<uint16_t>(buf + 0x16);
|
||||
|
||||
return dmi_table(dmi_get<uint32_t>(buf + 0x18), size, devmem, flags);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t *legacy_decode(uint8_t *buf, const char *devmem, uint32_t &size, uint32_t &version, uint32_t flags)
|
||||
{
|
||||
if (!checksum(buf, 0x0F)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
version = ((buf[0x0E] & 0xF0) << 12) + ((buf[0x0E] & 0x0F) << 8);
|
||||
size = dmi_get<uint16_t>(buf + 0x06);
|
||||
|
||||
return dmi_table(dmi_get<uint32_t>(buf + 0x08), size, devmem, flags);
|
||||
}
|
||||
|
||||
|
||||
#define EFI_NOT_FOUND (-1)
|
||||
#define EFI_NO_SMBIOS (-2)
|
||||
static off_t address_from_efi()
|
||||
{
|
||||
# if defined(__linux__)
|
||||
FILE *efi_systab;
|
||||
const char *filename;
|
||||
char linebuf[64];
|
||||
off_t address = 0;
|
||||
# elif defined(__FreeBSD__)
|
||||
char addrstr[KENV_MVALLEN + 1];
|
||||
# endif
|
||||
|
||||
# if defined(__linux__)
|
||||
if ((efi_systab = fopen(filename = "/sys/firmware/efi/systab", "r")) == nullptr && (efi_systab = fopen(filename = "/proc/efi/systab", "r")) == nullptr) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
address = EFI_NO_SMBIOS;
|
||||
while ((fgets(linebuf, sizeof(linebuf) - 1, efi_systab)) != nullptr) {
|
||||
char *addrp = strchr(linebuf, '=');
|
||||
*(addrp++) = '\0';
|
||||
if (strcmp(linebuf, "SMBIOS3") == 0 || strcmp(linebuf, "SMBIOS") == 0) {
|
||||
address = strtoull(addrp, nullptr, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(efi_systab);
|
||||
|
||||
return address;
|
||||
# elif defined(__FreeBSD__)
|
||||
if (kenv(KENV_GET, "hint.smbios.0.mem", addrstr, sizeof(addrstr)) == -1) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
return strtoull(addrstr, nullptr, 0);
|
||||
# endif
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
bool xmrig::DmiReader::read()
|
||||
{
|
||||
size_t size = 0x20;
|
||||
uint8_t *buf = read_file(0, &size, kSysEntryFile);
|
||||
uint8_t *smb = nullptr;
|
||||
|
||||
if (buf) {
|
||||
smb = nullptr;
|
||||
|
||||
if (size >= 24 && memcmp(buf, "_SM3_", 5) == 0) {
|
||||
smb = smbios3_decode(buf, kSysTableFile, m_size, m_version, FLAG_NO_FILE_OFFSET);
|
||||
}
|
||||
else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0) {
|
||||
smb = smbios_decode(buf, kSysTableFile, m_size, m_version, FLAG_NO_FILE_OFFSET);
|
||||
}
|
||||
else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0) {
|
||||
smb = legacy_decode(buf, kSysTableFile, m_size, m_version, FLAG_NO_FILE_OFFSET);
|
||||
}
|
||||
|
||||
if (smb) {
|
||||
return decode(smb, [smb, buf]() { free(smb); free(buf); });
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
const auto efi = address_from_efi();
|
||||
if (efi == EFI_NO_SMBIOS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (efi != EFI_NOT_FOUND) {
|
||||
if ((buf = mem_chunk(efi, 0x20, kMemDevice)) == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
smb = nullptr;
|
||||
|
||||
if (memcmp(buf, "_SM3_", 5) == 0) {
|
||||
smb = smbios3_decode(buf, kMemDevice, m_size, m_version, 0);
|
||||
}
|
||||
else if (memcmp(buf, "_SM_", 4) == 0) {
|
||||
smb = smbios_decode(buf, kSysTableFile, m_size, m_version, 0);
|
||||
}
|
||||
|
||||
if (smb) {
|
||||
return decode(smb, [smb, buf]() { free(smb); free(buf); });
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
# if defined(__x86_64__) || defined(_M_AMD64)
|
||||
if ((buf = mem_chunk(0xF0000, 0x10000, kMemDevice)) == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
smb = nullptr;
|
||||
|
||||
for (off_t fp = 0; fp <= 0xFFE0; fp += 16) {
|
||||
if (memcmp(buf + fp, "_SM3_", 5) == 0) {
|
||||
smb = smbios3_decode(buf + fp, kMemDevice, m_size, m_version, 0);
|
||||
}
|
||||
|
||||
if (smb) {
|
||||
return decode(smb, [smb, buf]() { free(smb); free(buf); });
|
||||
}
|
||||
}
|
||||
|
||||
for (off_t fp = 0; fp <= 0xFFF0; fp += 16) {
|
||||
if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) {
|
||||
smb = smbios3_decode(buf + fp, kMemDevice, m_size, m_version, 0);
|
||||
}
|
||||
else if (!smb && memcmp(buf + fp, "_DMI_", 5) == 0) {
|
||||
smb = legacy_decode(buf + fp, kMemDevice, m_size, m_version, 0);
|
||||
}
|
||||
|
||||
if (smb) {
|
||||
return decode(smb, [smb, buf]() { free(smb); free(buf); });
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
# endif
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
68
src/hw/dmi/DmiReader_win.cpp
Normal file
68
src/hw/dmi/DmiReader_win.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2002-2006 Hugo Weber <address@hidden>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "hw/dmi/DmiReader.h"
|
||||
#include "hw/dmi/DmiTools.h"
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
/*
|
||||
* Struct needed to get the SMBIOS table using GetSystemFirmwareTable API.
|
||||
*/
|
||||
struct RawSMBIOSData {
|
||||
uint8_t Used20CallingMethod;
|
||||
uint8_t SMBIOSMajorVersion;
|
||||
uint8_t SMBIOSMinorVersion;
|
||||
uint8_t DmiRevision;
|
||||
uint32_t Length;
|
||||
uint8_t SMBIOSTableData[];
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
bool xmrig::DmiReader::read()
|
||||
{
|
||||
const uint32_t size = GetSystemFirmwareTable('RSMB', 0, nullptr, 0);
|
||||
auto smb = reinterpret_cast<RawSMBIOSData *>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size));
|
||||
|
||||
if (!smb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetSystemFirmwareTable('RSMB', 0, smb, size) != size) {
|
||||
HeapFree(GetProcessHeap(), 0, smb);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_version = (smb->SMBIOSMajorVersion << 16) + (smb->SMBIOSMinorVersion << 8) + smb->DmiRevision;
|
||||
m_size = smb->Length;
|
||||
|
||||
return decode(smb->SMBIOSTableData, [smb]() {
|
||||
HeapFree(GetProcessHeap(), 0, smb);
|
||||
});
|
||||
}
|
||||
75
src/hw/dmi/DmiTools.cpp
Normal file
75
src/hw/dmi/DmiTools.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "hw/dmi/DmiTools.h"
|
||||
|
||||
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
/* Replace non-ASCII characters with dots */
|
||||
static void ascii_filter(char *bp, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (bp[i] < 32 || bp[i] >= 127) {
|
||||
bp[i] = '.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char *_dmi_string(dmi_header *dm, uint8_t s, bool filter)
|
||||
{
|
||||
char *bp = reinterpret_cast<char *>(dm->data);
|
||||
|
||||
bp += dm->length;
|
||||
while (s > 1 && *bp) {
|
||||
bp += strlen(bp);
|
||||
bp++;
|
||||
s--;
|
||||
}
|
||||
|
||||
if (!*bp) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
ascii_filter(bp, strlen(bp));
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
|
||||
const char *dmi_string(dmi_header *dm, size_t offset)
|
||||
{
|
||||
if (offset < 4) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return _dmi_string(dm, dm->data[offset], true);
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
60
src/hw/dmi/DmiTools.h
Normal file
60
src/hw/dmi/DmiTools.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_DMITOOLS_H
|
||||
#define XMRIG_DMITOOLS_H
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
struct dmi_header
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint16_t handle;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
|
||||
struct u64 {
|
||||
uint32_t l;
|
||||
uint32_t h;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline T dmi_get(const uint8_t *data) { return *reinterpret_cast<const T *>(data); }
|
||||
|
||||
template<typename T>
|
||||
inline T dmi_get(const dmi_header *h, size_t offset) { return *reinterpret_cast<const T *>(h->data + offset); }
|
||||
|
||||
|
||||
const char *dmi_string(dmi_header *dm, size_t offset);
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_DMITOOLS_H */
|
||||
35
src/hw/dmi/dmi.cmake
Normal file
35
src/hw/dmi/dmi.cmake
Normal file
@@ -0,0 +1,35 @@
|
||||
if (WITH_DMI AND (XMRIG_OS_WIN OR XMRIG_OS_LINUX OR XMRIG_OS_FREEBSD OR (XMRIG_OS_MACOS AND NOT XMRIG_ARM)))
|
||||
set(WITH_DMI ON)
|
||||
else()
|
||||
set(WITH_DMI OFF)
|
||||
endif()
|
||||
|
||||
if (WITH_DMI)
|
||||
add_definitions(/DXMRIG_FEATURE_DMI)
|
||||
|
||||
list(APPEND HEADERS
|
||||
src/hw/dmi/DmiBoard.h
|
||||
src/hw/dmi/DmiMemory.h
|
||||
src/hw/dmi/DmiReader.h
|
||||
src/hw/dmi/DmiTools.h
|
||||
)
|
||||
|
||||
list(APPEND SOURCES
|
||||
src/hw/dmi/DmiBoard.cpp
|
||||
src/hw/dmi/DmiMemory.cpp
|
||||
src/hw/dmi/DmiReader.cpp
|
||||
src/hw/dmi/DmiTools.cpp
|
||||
)
|
||||
|
||||
if (XMRIG_OS_WIN)
|
||||
list(APPEND SOURCES src/hw/dmi/DmiReader_win.cpp)
|
||||
elseif(XMRIG_OS_LINUX OR XMRIG_OS_FREEBSD)
|
||||
list(APPEND SOURCES src/hw/dmi/DmiReader_unix.cpp)
|
||||
elseif(XMRIG_OS_MACOS)
|
||||
list(APPEND SOURCES src/hw/dmi/DmiReader_mac.cpp)
|
||||
find_library(CORESERVICES_LIBRARY CoreServices)
|
||||
list(APPEND EXTRA_LIBS ${CORESERVICES_LIBRARY})
|
||||
endif()
|
||||
else()
|
||||
remove_definitions(/DXMRIG_FEATURE_DMI)
|
||||
endif()
|
||||
88
src/hw/msr/Msr.cpp
Normal file
88
src/hw/msr/Msr.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "hw/msr/Msr.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static const char *kTag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ");
|
||||
static std::weak_ptr<Msr> instance;
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
||||
const char *xmrig::Msr::tag()
|
||||
{
|
||||
return kTag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<xmrig::Msr> xmrig::Msr::get()
|
||||
{
|
||||
auto msr = instance.lock();
|
||||
if (!msr) {
|
||||
msr = std::make_shared<Msr>();
|
||||
instance = msr;
|
||||
}
|
||||
|
||||
if (msr->isAvailable()) {
|
||||
return msr;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::write(uint32_t reg, uint64_t value, int32_t cpu, uint64_t mask, bool verbose)
|
||||
{
|
||||
if (mask != MsrItem::kNoMask) {
|
||||
uint64_t old_value;
|
||||
if (rdmsr(reg, cpu, old_value)) {
|
||||
value = MsrItem::maskedValue(old_value, value, mask);
|
||||
}
|
||||
}
|
||||
|
||||
const bool result = wrmsr(reg, value, cpu);
|
||||
if (!result && verbose) {
|
||||
LOG_WARN("%s " YELLOW_BOLD("cannot set MSR 0x%08" PRIx32 " to 0x%016" PRIx64), tag(), reg, value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
xmrig::MsrItem xmrig::Msr::read(uint32_t reg, int32_t cpu, bool verbose) const
|
||||
{
|
||||
uint64_t value = 0;
|
||||
if (rdmsr(reg, cpu, value)) {
|
||||
return { reg, value };
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
LOG_WARN("%s " YELLOW_BOLD("cannot read MSR 0x%08" PRIx32), tag(), reg);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
69
src/hw/msr/Msr.h
Normal file
69
src/hw/msr/Msr.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_MSR_H
|
||||
#define XMRIG_MSR_H
|
||||
|
||||
|
||||
#include "base/tools/Object.h"
|
||||
#include "hw/msr/MsrItem.h"
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace xmrig
|
||||
{
|
||||
|
||||
|
||||
class MsrPrivate;
|
||||
|
||||
|
||||
class Msr
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE(Msr)
|
||||
|
||||
using Callback = std::function<bool(int32_t cpu)>;
|
||||
|
||||
Msr();
|
||||
~Msr();
|
||||
|
||||
static const char *tag();
|
||||
static std::shared_ptr<Msr> get();
|
||||
|
||||
inline bool write(const MsrItem &item, int32_t cpu = -1, bool verbose = true) { return write(item.reg(), item.value(), cpu, item.mask(), verbose); }
|
||||
|
||||
bool isAvailable() const;
|
||||
bool write(uint32_t reg, uint64_t value, int32_t cpu = -1, uint64_t mask = MsrItem::kNoMask, bool verbose = true);
|
||||
bool write(Callback &&callback);
|
||||
MsrItem read(uint32_t reg, int32_t cpu = -1, bool verbose = true) const;
|
||||
|
||||
private:
|
||||
bool rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const;
|
||||
bool wrmsr(uint32_t reg, uint64_t value, int32_t cpu);
|
||||
|
||||
MsrPrivate *d_ptr = nullptr;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_MSR_H */
|
||||
@@ -1,14 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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,7 +17,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto/rx/msr/MsrItem.h"
|
||||
#include "hw/msr/MsrItem.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
@@ -39,9 +31,6 @@ namespace xmrig
|
||||
{
|
||||
|
||||
|
||||
class RxDataset;
|
||||
|
||||
|
||||
class MsrItem
|
||||
{
|
||||
public:
|
||||
@@ -57,6 +46,11 @@ public:
|
||||
inline uint64_t value() const { return m_value; }
|
||||
inline uint64_t mask() const { return m_mask; }
|
||||
|
||||
static inline uint64_t maskedValue(uint64_t old_value, uint64_t new_value, uint64_t mask)
|
||||
{
|
||||
return (new_value & mask) | (old_value & ~mask);
|
||||
}
|
||||
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
String toString() const;
|
||||
|
||||
122
src/hw/msr/Msr_linux.cpp
Normal file
122
src/hw/msr/Msr_linux.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "hw/msr/Msr.h"
|
||||
#include "3rdparty/fmt/core.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
||||
#include <array>
|
||||
#include <cctype>
|
||||
#include <cinttypes>
|
||||
#include <cstdio>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static int msr_open(int32_t cpu, int flags)
|
||||
{
|
||||
const auto name = fmt::format("/dev/cpu/{}/msr", cpu < 0 ? Cpu::info()->units().front() : cpu);
|
||||
|
||||
return open(name.c_str(), flags);
|
||||
}
|
||||
|
||||
|
||||
class MsrPrivate
|
||||
{
|
||||
public:
|
||||
bool available = true;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::Msr::Msr() : d_ptr(new MsrPrivate())
|
||||
{
|
||||
if (system("/sbin/modprobe msr allow_writes=on > /dev/null 2>&1") != 0) {
|
||||
LOG_WARN("%s " YELLOW_BOLD("msr kernel module is not available"), Msr::tag());
|
||||
|
||||
d_ptr->available = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::Msr::~Msr()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::isAvailable() const
|
||||
{
|
||||
return d_ptr->available;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::write(Callback &&callback)
|
||||
{
|
||||
const auto &units = Cpu::info()->units();
|
||||
|
||||
for (int32_t pu : units) {
|
||||
if (!callback(pu)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const
|
||||
{
|
||||
const int fd = msr_open(cpu, O_RDONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool success = pread(fd, &value, sizeof value, reg) == sizeof value;
|
||||
close(fd);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::wrmsr(uint32_t reg, uint64_t value, int32_t cpu)
|
||||
{
|
||||
const int fd = msr_open(cpu, O_WRONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool success = pwrite(fd, &value, sizeof value, reg) == sizeof value;
|
||||
|
||||
close(fd);
|
||||
|
||||
return success;
|
||||
}
|
||||
255
src/hw/msr/Msr_win.cpp
Normal file
255
src/hw/msr/Msr_win.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
/* XMRig
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "hw/msr/Msr.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
#define SERVICE_NAME L"WinRing0_1_2_0"
|
||||
#define IOCTL_READ_MSR CTL_CODE(40000, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_WRITE_MSR CTL_CODE(40000, 0x822, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static const wchar_t *kServiceName = SERVICE_NAME;
|
||||
|
||||
|
||||
class MsrPrivate
|
||||
{
|
||||
public:
|
||||
bool uninstall()
|
||||
{
|
||||
if (driver != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(driver);
|
||||
}
|
||||
|
||||
if (!service) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
|
||||
if (!reuse) {
|
||||
SERVICE_STATUS serviceStatus;
|
||||
|
||||
if (!ControlService(service, SERVICE_CONTROL_STOP, &serviceStatus)) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (!DeleteService(service)) {
|
||||
LOG_ERR("%s " RED("failed to remove WinRing0 driver, error %u"), Msr::tag(), GetLastError());
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
CloseServiceHandle(service);
|
||||
service = nullptr;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool reuse = false;
|
||||
HANDLE driver = INVALID_HANDLE_VALUE;
|
||||
SC_HANDLE manager = nullptr;
|
||||
SC_HANDLE service = nullptr;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::Msr::Msr() : d_ptr(new MsrPrivate())
|
||||
{
|
||||
DWORD err = 0;
|
||||
|
||||
d_ptr->manager = OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
|
||||
if (!d_ptr->manager) {
|
||||
if ((err = GetLastError()) == ERROR_ACCESS_DENIED) {
|
||||
LOG_WARN("%s " YELLOW_BOLD("to access MSR registers Administrator privileges required."), tag());
|
||||
}
|
||||
else {
|
||||
LOG_ERR("%s " RED("failed to open service control manager, error %u"), tag(), err);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<wchar_t> dir;
|
||||
|
||||
do {
|
||||
dir.resize(dir.empty() ? MAX_PATH : dir.size() * 2);
|
||||
GetModuleFileNameW(nullptr, dir.data(), dir.size());
|
||||
err = GetLastError();
|
||||
} while (err == ERROR_INSUFFICIENT_BUFFER);
|
||||
|
||||
if (err != ERROR_SUCCESS) {
|
||||
LOG_ERR("%s " RED("failed to get path to driver, error %u"), tag(), err);
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = dir.end() - 1; it != dir.begin(); --it) {
|
||||
if ((*it == L'\\') || (*it == L'/')) {
|
||||
++it;
|
||||
*it = L'\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const std::wstring path = std::wstring(dir.data()) + L"WinRing0x64.sys";
|
||||
|
||||
d_ptr->service = OpenServiceW(d_ptr->manager, kServiceName, SERVICE_ALL_ACCESS);
|
||||
if (d_ptr->service) {
|
||||
LOG_WARN("%s " YELLOW("service ") YELLOW_BOLD("WinRing0_1_2_0") YELLOW(" already exists"), tag());
|
||||
|
||||
SERVICE_STATUS status;
|
||||
const auto rc = QueryServiceStatus(d_ptr->service, &status);
|
||||
|
||||
if (rc) {
|
||||
DWORD dwBytesNeeded = 0;
|
||||
|
||||
QueryServiceConfigA(d_ptr->service, nullptr, 0, &dwBytesNeeded);
|
||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||
std::vector<BYTE> buffer(dwBytesNeeded);
|
||||
auto config = reinterpret_cast<LPQUERY_SERVICE_CONFIGA>(buffer.data());
|
||||
|
||||
if (QueryServiceConfigA(d_ptr->service, config, buffer.size(), &dwBytesNeeded)) {
|
||||
LOG_INFO("%s " YELLOW("service path: ") YELLOW_BOLD("\"%s\""), tag(), config->lpBinaryPathName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rc && status.dwCurrentState == SERVICE_RUNNING) {
|
||||
d_ptr->reuse = true;
|
||||
}
|
||||
else if (!d_ptr->uninstall()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!d_ptr->reuse) {
|
||||
d_ptr->service = CreateServiceW(d_ptr->manager, kServiceName, kServiceName, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, path.c_str(), nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||
if (!d_ptr->service) {
|
||||
LOG_ERR("%s " RED("failed to install WinRing0 driver, error %u"), tag(), GetLastError());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!StartService(d_ptr->service, 0, nullptr)) {
|
||||
err = GetLastError();
|
||||
if (err != ERROR_SERVICE_ALREADY_RUNNING) {
|
||||
if (err == ERROR_FILE_NOT_FOUND) {
|
||||
LOG_ERR("%s " RED("failed to start WinRing0 driver: ") RED_BOLD("\"WinRing0x64.sys not found\""), tag());
|
||||
}
|
||||
else {
|
||||
LOG_ERR("%s " RED("failed to start WinRing0 driver, error %u"), tag(), err);
|
||||
}
|
||||
|
||||
d_ptr->uninstall();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d_ptr->driver = CreateFileW(L"\\\\.\\" SERVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (d_ptr->driver == INVALID_HANDLE_VALUE) {
|
||||
LOG_ERR("%s " RED("failed to connect to WinRing0 driver, error %u"), tag(), GetLastError());;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::Msr::~Msr()
|
||||
{
|
||||
d_ptr->uninstall();
|
||||
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::isAvailable() const
|
||||
{
|
||||
return d_ptr->driver != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::write(Callback &&callback)
|
||||
{
|
||||
const auto &units = Cpu::info()->units();
|
||||
bool success = false;
|
||||
|
||||
std::thread thread([&callback, &units, &success]() {
|
||||
for (int32_t pu : units) {
|
||||
if (!Platform::setThreadAffinity(pu)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!callback(pu)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
success = true;
|
||||
});
|
||||
|
||||
thread.join();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const
|
||||
{
|
||||
assert(cpu < 0);
|
||||
|
||||
DWORD size = 0;
|
||||
|
||||
return DeviceIoControl(d_ptr->driver, IOCTL_READ_MSR, ®, sizeof(reg), &value, sizeof(value), &size, nullptr) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::wrmsr(uint32_t reg, uint64_t value, int32_t cpu)
|
||||
{
|
||||
assert(cpu < 0);
|
||||
|
||||
struct {
|
||||
uint32_t reg = 0;
|
||||
uint32_t value[2]{};
|
||||
} input;
|
||||
|
||||
static_assert(sizeof(input) == 12, "Invalid struct size for WinRing0 driver");
|
||||
|
||||
input.reg = reg;
|
||||
*(reinterpret_cast<uint64_t*>(input.value)) = value;
|
||||
|
||||
DWORD output;
|
||||
DWORD k;
|
||||
|
||||
return DeviceIoControl(d_ptr->driver, IOCTL_WRITE_MSR, &input, sizeof(input), &output, sizeof(output), &k, nullptr) != 0;
|
||||
}
|
||||
@@ -28,15 +28,15 @@
|
||||
#define APP_ID "xmrig"
|
||||
#define APP_NAME "XMRig"
|
||||
#define APP_DESC "XMRig miner"
|
||||
#define APP_VERSION "6.7.1"
|
||||
#define APP_VERSION "6.8.1"
|
||||
#define APP_DOMAIN "xmrig.com"
|
||||
#define APP_SITE "www.xmrig.com"
|
||||
#define APP_COPYRIGHT "Copyright (C) 2016-2021 xmrig.com"
|
||||
#define APP_KIND "miner"
|
||||
|
||||
#define APP_VER_MAJOR 6
|
||||
#define APP_VER_MINOR 7
|
||||
#define APP_VER_PATCH 0
|
||||
#define APP_VER_MINOR 8
|
||||
#define APP_VER_PATCH 1
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# if (_MSC_VER >= 1920)
|
||||
|
||||
Reference in New Issue
Block a user