diff --git a/CMakeLists.txt b/CMakeLists.txt index 35fba8ea5..79486e03e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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" OFF) 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}) diff --git a/src/Summary.cpp b/src/Summary.cpp index ebaeb3563..eaee89bf5 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -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); } diff --git a/src/Summary.h b/src/Summary.h index 4317d13e1..0b03f6759 100644 --- a/src/Summary.h +++ b/src/Summary.h @@ -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 diff --git a/src/base/api/Api.cpp b/src/base/api/Api.cpp index 89e61593c..3a71fd9c3 100644 --- a/src/base/api/Api.cpp +++ b/src/base/api/Api.cpp @@ -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 diff --git a/src/base/api/Api.h b/src/base/api/Api.h index 0ee9ca6ae..f412a3172 100644 --- a/src/base/api/Api.h +++ b/src/base/api/Api.h @@ -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" diff --git a/src/base/api/interfaces/IApiListener.h b/src/base/api/interfaces/IApiListener.h index bbf153a69..71ee9c76d 100644 --- a/src/base/api/interfaces/IApiListener.h +++ b/src/base/api/interfaces/IApiListener.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 diff --git a/src/base/api/interfaces/IApiRequest.h b/src/base/api/interfaces/IApiRequest.h index c05e513ec..35fb27d5f 100644 --- a/src/base/api/interfaces/IApiRequest.h +++ b/src/base/api/interfaces/IApiRequest.h @@ -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; diff --git a/src/base/kernel/interfaces/IBaseListener.h b/src/base/kernel/interfaces/IBaseListener.h index 1f2123690..80120ab85 100644 --- a/src/base/kernel/interfaces/IBaseListener.h +++ b/src/base/kernel/interfaces/IBaseListener.h @@ -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; }; diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index 8b5ae278a..792c43a11 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -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, diff --git a/src/base/net/stratum/Pools.cpp b/src/base/net/stratum/Pools.cpp index a9c245fa3..d2ab30126 100644 --- a/src/base/net/stratum/Pools.cpp +++ b/src/base/net/stratum/Pools.cpp @@ -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); diff --git a/src/base/net/stratum/Pools.h b/src/base/net/stratum/Pools.h index 477ce211b..7fa6ec9d5 100644 --- a/src/base/net/stratum/Pools.h +++ b/src/base/net/stratum/Pools.h @@ -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 diff --git a/src/base/net/stratum/benchmark/BenchClient.cpp b/src/base/net/stratum/benchmark/BenchClient.cpp index c81f40105..0e1093a11 100644 --- a/src/base/net/stratum/benchmark/BenchClient.cpp +++ b/src/base/net/stratum/benchmark/BenchClient.cpp @@ -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); } diff --git a/src/base/net/stratum/benchmark/BenchClient.h b/src/base/net/stratum/benchmark/BenchClient.h index 018bceaaf..7eac1ee87 100644 --- a/src/base/net/stratum/benchmark/BenchClient.h +++ b/src/base/net/stratum/benchmark/BenchClient.h @@ -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 diff --git a/src/base/net/stratum/benchmark/BenchConfig.cpp b/src/base/net/stratum/benchmark/BenchConfig.cpp index 2e02755a1..c81e0c172 100644 --- a/src/base/net/stratum/benchmark/BenchConfig.cpp +++ b/src/base/net/stratum/benchmark/BenchConfig.cpp @@ -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); } diff --git a/src/base/net/stratum/benchmark/BenchConfig.h b/src/base/net/stratum/benchmark/BenchConfig.h index f1310236f..87e541972 100644 --- a/src/base/net/stratum/benchmark/BenchConfig.h +++ b/src/base/net/stratum/benchmark/BenchConfig.h @@ -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; diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 8f230e002..40c3aeac4 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -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(); } diff --git a/src/core/Controller.h b/src/core/Controller.h index 947084734..13704f151 100644 --- a/src/core/Controller.h +++ b/src/core/Controller.h @@ -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 }; diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 792b3873d..f8b7bb858 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -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 diff --git a/src/core/config/Config.h b/src/core/config/Config.h index 501b8c592..d8433beb2 100644 --- a/src/core/config/Config.h +++ b/src/core/config/Config.h @@ -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; diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp index b8a431fd1..b32aede37 100644 --- a/src/core/config/ConfigTransform.cpp +++ b/src/core/config/ConfigTransform.cpp @@ -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 diff --git a/src/core/config/ConfigTransform.h b/src/core/config/ConfigTransform.h index 0251777ce..8fd2505ce 100644 --- a/src/core/config/ConfigTransform.h +++ b/src/core/config/ConfigTransform.h @@ -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 diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index f698836c4..b6fcd1c1a 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -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 } }; diff --git a/src/core/config/usage.h b/src/core/config/usage.h index 54e629ecb..261e571cf 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -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; } diff --git a/src/hw/api/HwApi.cpp b/src/hw/api/HwApi.cpp new file mode 100644 index 000000000..fed5de3f9 --- /dev/null +++ b/src/hw/api/HwApi.cpp @@ -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 + } +} diff --git a/src/hw/api/HwApi.h b/src/hw/api/HwApi.h new file mode 100644 index 000000000..f434a0a5a --- /dev/null +++ b/src/hw/api/HwApi.h @@ -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 */ diff --git a/src/hw/api/api.cmake b/src/hw/api/api.cmake new file mode 100644 index 000000000..94b224704 --- /dev/null +++ b/src/hw/api/api.cmake @@ -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() diff --git a/src/hw/dmi/DmiBoard.cpp b/src/hw/dmi/DmiBoard.cpp new file mode 100644 index 000000000..3cbe3dd9a --- /dev/null +++ b/src/hw/dmi/DmiBoard.cpp @@ -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 diff --git a/src/hw/dmi/DmiBoard.h b/src/hw/dmi/DmiBoard.h new file mode 100644 index 000000000..0c64da17c --- /dev/null +++ b/src/hw/dmi/DmiBoard.h @@ -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 */ diff --git a/src/hw/dmi/DmiMemory.cpp b/src/hw/dmi/DmiMemory.cpp new file mode 100644 index 000000000..5b36e2bae --- /dev/null +++ b/src/hw/dmi/DmiMemory.cpp @@ -0,0 +1,218 @@ +/* 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; + } + + m_speed = std::max<uint64_t>(m_speed, dmi_memory_device_speed(dmi_get<uint16_t>(h, 0x20), h->length >= 0x5C ? dmi_get<uint32_t>(h, 0x58) : 0) * 1000000ULL); + + 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 diff --git a/src/hw/dmi/DmiMemory.h b/src/hw/dmi/DmiMemory.h new file mode 100644 index 000000000..badee2cfd --- /dev/null +++ b/src/hw/dmi/DmiMemory.h @@ -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 */ diff --git a/src/hw/dmi/DmiReader.cpp b/src/hw/dmi/DmiReader.cpp new file mode 100644 index 000000000..18211759a --- /dev/null +++ b/src/hw/dmi/DmiReader.cpp @@ -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; +} diff --git a/src/hw/dmi/DmiReader.h b/src/hw/dmi/DmiReader.h new file mode 100644 index 000000000..a4f7eb8a7 --- /dev/null +++ b/src/hw/dmi/DmiReader.h @@ -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 */ diff --git a/src/hw/dmi/DmiReader_mac.cpp b/src/hw/dmi/DmiReader_mac.cpp new file mode 100644 index 000000000..a23bfe47f --- /dev/null +++ b/src/hw/dmi/DmiReader_mac.cpp @@ -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; +} diff --git a/src/hw/dmi/DmiReader_unix.cpp b/src/hw/dmi/DmiReader_unix.cpp new file mode 100644 index 000000000..ff57b7a6a --- /dev/null +++ b/src/hw/dmi/DmiReader_unix.cpp @@ -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> + + +#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; +} diff --git a/src/hw/dmi/DmiReader_win.cpp b/src/hw/dmi/DmiReader_win.cpp new file mode 100644 index 000000000..837bdb7b3 --- /dev/null +++ b/src/hw/dmi/DmiReader_win.cpp @@ -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); + }); +} diff --git a/src/hw/dmi/DmiTools.cpp b/src/hw/dmi/DmiTools.cpp new file mode 100644 index 000000000..e82c2f452 --- /dev/null +++ b/src/hw/dmi/DmiTools.cpp @@ -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 diff --git a/src/hw/dmi/DmiTools.h b/src/hw/dmi/DmiTools.h new file mode 100644 index 000000000..65a1dfd75 --- /dev/null +++ b/src/hw/dmi/DmiTools.h @@ -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 */ diff --git a/src/hw/dmi/dmi.cmake b/src/hw/dmi/dmi.cmake new file mode 100644 index 000000000..5140692a7 --- /dev/null +++ b/src/hw/dmi/dmi.cmake @@ -0,0 +1,33 @@ +if (WITH_DMI) + set(WITH_DMI XMRIG_OS_WIN OR XMRIG_OS_LINUX OR XMRIG_OS_FREEBSD OR (XMRIG_OS_MACOS AND NOT XMRIG_ARM)) +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()