mirror of
https://github.com/xmrig/xmrig.git
synced 2025-03-12 09:37:35 +00:00
Merge branch 'dev'
This commit is contained in:
commit
e38d277143
70 changed files with 2869 additions and 1047 deletions
|
@ -1,3 +1,12 @@
|
|||
# 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.
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 vm = Cpu::info()->isVM();
|
||||
|
||||
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.slot().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data());
|
||||
}
|
||||
else if (!vm) {
|
||||
Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data());
|
||||
}
|
||||
}
|
||||
|
||||
const auto &board = vm ? 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,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,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,7 @@ public:
|
|||
BenchSeedKey = 1046,
|
||||
BenchHashKey = 1047,
|
||||
BenchTokenKey = 1048,
|
||||
DmiKey = 1049,
|
||||
|
||||
// xmrig common
|
||||
CPUPriorityKey = 1021,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -54,7 +52,12 @@ int xmrig::Controller::init()
|
|||
|
||||
VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().isHugePages());
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -208,47 +200,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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -155,7 +155,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 }
|
||||
};
|
||||
|
|
|
@ -190,6 +190,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
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 have 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(" 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 */
|
219
src/hw/dmi/DmiMemory.cpp
Normal file
219
src/hw/dmi/DmiMemory.cpp
Normal file
|
@ -0,0 +1,219 @@
|
|||
/* 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/rapidjson/document.h"
|
||||
#include "hw/dmi/DmiTools.h"
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
m_formFactor = h->data[0x0E];
|
||||
m_slot = dmi_string(h, 0x10);
|
||||
m_bank = dmi_string(h, 0x11);
|
||||
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("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
|
78
src/hw/dmi/DmiMemory.h
Normal file
78
src/hw/dmi/DmiMemory.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* 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 &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:
|
||||
String m_bank;
|
||||
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.2"
|
||||
#define APP_VERSION "6.8.0-dev"
|
||||
#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 2
|
||||
#define APP_VER_MINOR 8
|
||||
#define APP_VER_PATCH 0
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# if (_MSC_VER >= 1920)
|
||||
|
|
Loading…
Reference in a new issue