From 11e0d3de3aa501dcd44172b17f4b64ecced9607d Mon Sep 17 00:00:00 2001 From: XMRig <support@xmrig.com> Date: Mon, 18 Jan 2021 11:23:29 +0700 Subject: [PATCH 01/11] Added DMI reader (Windows only). --- CMakeLists.txt | 3 + src/Summary.cpp | 30 ++++++ src/hw/dmi/DmiBoard.cpp | 35 +++++++ src/hw/dmi/DmiBoard.h | 54 ++++++++++ src/hw/dmi/DmiMemory.cpp | 192 ++++++++++++++++++++++++++++++++++ src/hw/dmi/DmiMemory.h | 74 +++++++++++++ src/hw/dmi/DmiReader.cpp | 87 +++++++++++++++ src/hw/dmi/DmiReader.h | 59 +++++++++++ src/hw/dmi/DmiReader_unix.cpp | 26 +++++ src/hw/dmi/DmiReader_win.cpp | 112 ++++++++++++++++++++ src/hw/dmi/DmiTools.cpp | 75 +++++++++++++ src/hw/dmi/DmiTools.h | 53 ++++++++++ src/hw/dmi/dmi.cmake | 25 +++++ 13 files changed, 825 insertions(+) create mode 100644 src/hw/dmi/DmiBoard.cpp create mode 100644 src/hw/dmi/DmiBoard.h create mode 100644 src/hw/dmi/DmiMemory.cpp create mode 100644 src/hw/dmi/DmiMemory.h create mode 100644 src/hw/dmi/DmiReader.cpp create mode 100644 src/hw/dmi/DmiReader.h create mode 100644 src/hw/dmi/DmiReader_unix.cpp create mode 100644 src/hw/dmi/DmiReader_win.cpp create mode 100644 src/hw/dmi/DmiTools.cpp create mode 100644 src/hw/dmi/DmiTools.h create mode 100644 src/hw/dmi/dmi.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 35fba8ea5..c1a222fc4 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 reader" OFF) option(BUILD_STATIC "Build static binary" OFF) option(ARM_TARGET "Force use specific ARM target 8 or 7" 0) @@ -197,6 +198,8 @@ if (WITH_EMBEDDED_CONFIG) add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG) endif() +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..345ed48e7 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -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 @@ -130,6 +135,31 @@ static void print_memory() totalMem / oneGiB, percent ); + +# ifdef XMRIG_FEATURE_DMI + DmiReader reader; + if (!reader.read()) { + return; + } + + for (const auto &memory : reader.memory()) { + if (!memory.isValid()) { + continue; + } + + if (!memory.size()) { + Log::print(WHITE_BOLD(" %-13s") WHITE_BOLD("%s: ") BLACK_BOLD("<empty>"), "", memory.slot().data()); + continue; + } + + Log::print(WHITE_BOLD(" %-13s") WHITE_BOLD("%s: ") CYAN_BOLD("%" PRIu64 " GB ") WHITE_BOLD("%s @ %" PRIu64 " MHz ") BLACK_BOLD("%s"), + "", memory.slot().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data()); + } + + if (reader.board().isValid()) { + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") " - " WHITE_BOLD("%s"), "MOTHERBOARD", reader.board().vendor().data(), reader.board().product().data()); + } +# endif } diff --git a/src/hw/dmi/DmiBoard.cpp b/src/hw/dmi/DmiBoard.cpp new file mode 100644 index 000000000..381865f4e --- /dev/null +++ b/src/hw/dmi/DmiBoard.cpp @@ -0,0 +1,35 @@ +/* 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 "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); +} diff --git a/src/hw/dmi/DmiBoard.h b/src/hw/dmi/DmiBoard.h new file mode 100644 index 000000000..dd28a607b --- /dev/null +++ b/src/hw/dmi/DmiBoard.h @@ -0,0 +1,54 @@ +/* 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); + +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..0006d0063 --- /dev/null +++ b/src/hw/dmi/DmiMemory.cpp @@ -0,0 +1,192 @@ +/* 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 "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(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); +} diff --git a/src/hw/dmi/DmiMemory.h b/src/hw/dmi/DmiMemory.h new file mode 100644 index 000000000..b9a0468b0 --- /dev/null +++ b/src/hw/dmi/DmiMemory.h @@ -0,0 +1,74 @@ +/* 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; + +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..660838454 --- /dev/null +++ b/src/hw/dmi/DmiReader.cpp @@ -0,0 +1,87 @@ +/* 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" + + +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 + + +bool xmrig::DmiReader::decode(uint8_t *buf) +{ + if (!buf || !m_count) { + return false; + } + + uint8_t *data = buf; + int i = 0; + + while ((i < m_count || !m_count) && 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++; + } + next += 2; + + if (static_cast<uint32_t>(next - buf) > m_size) { + data = next; + break; + } + + switch (h.type) { + 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..69ba483b9 --- /dev/null +++ b/src/hw/dmi/DmiReader.h @@ -0,0 +1,59 @@ +/* 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" + + +namespace xmrig { + + +class DmiReader +{ +public: + DmiReader() = default; + + inline const DmiBoard &board() const { return m_board; } + inline const std::vector<DmiMemory> &memory() const { return m_memory; } + inline uint16_t count() const { return m_count; } + inline uint32_t size() const { return m_size; } + inline uint32_t version() const { return m_version; } + + bool read(); + +private: + bool decode(uint8_t *buf); + + DmiBoard m_board; + uint16_t m_count = 0; + uint32_t m_size = 0; + uint32_t m_version = 0; + std::vector<DmiMemory> m_memory; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_DMIREADER_H */ diff --git a/src/hw/dmi/DmiReader_unix.cpp b/src/hw/dmi/DmiReader_unix.cpp new file mode 100644 index 000000000..4919935fd --- /dev/null +++ b/src/hw/dmi/DmiReader_unix.cpp @@ -0,0 +1,26 @@ +/* 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/dmi/DmiReader.h" + + +bool xmrig::DmiReader::read() +{ + return false; +} diff --git a/src/hw/dmi/DmiReader_win.cpp b/src/hw/dmi/DmiReader_win.cpp new file mode 100644 index 000000000..6b8e2ac46 --- /dev/null +++ b/src/hw/dmi/DmiReader_win.cpp @@ -0,0 +1,112 @@ +/* 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[]; +}; + + +/* + * Counts the number of SMBIOS structures present in + * the SMBIOS table. + * + * buf - Pointer that receives the SMBIOS Table address. + * This will be the address of the BYTE array from + * the RawSMBIOSData struct. + * + * len - The length of the SMBIOS Table pointed by buff. + * + * return - The number of SMBIOS strutctures. + * + * Remarks: + * The SMBIOS Table Entry Point has this information, + * however the GetSystemFirmwareTable API doesn't + * return all fields from the Entry Point, and + * DMIDECODE uses this value as a parameter for + * dmi_table function. This is the reason why + * this function was make. + * + * Hugo Weber address@hidden + */ +uint16_t count_smbios_structures(const uint8_t *buf, uint32_t len) +{ + uint16_t count = 0; + uint32_t offset = 0; + + while (offset < len) { + offset += reinterpret_cast<const dmi_header *>(buf + offset)->length; + count++; + + while ((*reinterpret_cast<const uint16_t *>(buf + offset) != 0) && (offset < len)) { + offset++; + } + + offset += 2; + } + + return count; +} + + +} // 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; + m_count = count_smbios_structures(smb->SMBIOSTableData, m_size); + + const bool rc = decode(smb->SMBIOSTableData); + HeapFree(GetProcessHeap(), 0, smb); + + return rc; +} 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..e929e6fe5 --- /dev/null +++ b/src/hw/dmi/DmiTools.h @@ -0,0 +1,53 @@ +/* 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 <cstdint> + + +namespace xmrig { + + +struct dmi_header +{ + uint8_t type; + uint8_t length; + uint16_t handle; + uint8_t *data; +}; + + +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..ff4882ce0 --- /dev/null +++ b/src/hw/dmi/dmi.cmake @@ -0,0 +1,25 @@ +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) + list(APPEND SOURCES src/hw/dmi/DmiReader_unix.cpp) + endif() +else() + remove_definitions(/DXMRIG_FEATURE_DMI) +endif() From 05e6f661690f067b2ed0f507ea8717b73449e7ed Mon Sep 17 00:00:00 2001 From: XMRig <support@xmrig.com> Date: Mon, 18 Jan 2021 16:53:42 +0700 Subject: [PATCH 02/11] Added basic Linux support. --- CMakeLists.txt | 2 +- src/hw/dmi/DmiMemory.cpp | 2 +- src/hw/dmi/DmiReader.cpp | 4 +- src/hw/dmi/DmiReader.h | 2 - src/hw/dmi/DmiReader_unix.cpp | 168 +++++++++++++++++++++++++++++++++- src/hw/dmi/DmiReader_win.cpp | 43 --------- src/hw/dmi/DmiTools.h | 7 ++ 7 files changed, 177 insertions(+), 51 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1a222fc4..69f40fcdd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,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) diff --git a/src/hw/dmi/DmiMemory.cpp b/src/hw/dmi/DmiMemory.cpp index 0006d0063..f02a64ecd 100644 --- a/src/hw/dmi/DmiMemory.cpp +++ b/src/hw/dmi/DmiMemory.cpp @@ -170,7 +170,7 @@ xmrig::DmiMemory::DmiMemory(dmi_header *h) return; } - m_speed = std::max(m_speed, dmi_memory_device_speed(dmi_get<uint16_t>(h, 0x20), h->length >= 0x5C ? dmi_get<uint32_t>(h, 0x58) : 0) * 1000000ULL); + 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; diff --git a/src/hw/dmi/DmiReader.cpp b/src/hw/dmi/DmiReader.cpp index 660838454..66f1dd5fa 100644 --- a/src/hw/dmi/DmiReader.cpp +++ b/src/hw/dmi/DmiReader.cpp @@ -40,14 +40,14 @@ static void dmi_get_header(dmi_header *h, uint8_t *data) bool xmrig::DmiReader::decode(uint8_t *buf) { - if (!buf || !m_count) { + if (!buf) { return false; } uint8_t *data = buf; int i = 0; - while ((i < m_count || !m_count) && data + 4 <= buf + m_size) { + while (data + 4 <= buf + m_size) { dmi_header h{}; dmi_get_header(&h, data); diff --git a/src/hw/dmi/DmiReader.h b/src/hw/dmi/DmiReader.h index 69ba483b9..243b5164b 100644 --- a/src/hw/dmi/DmiReader.h +++ b/src/hw/dmi/DmiReader.h @@ -36,7 +36,6 @@ public: inline const DmiBoard &board() const { return m_board; } inline const std::vector<DmiMemory> &memory() const { return m_memory; } - inline uint16_t count() const { return m_count; } inline uint32_t size() const { return m_size; } inline uint32_t version() const { return m_version; } @@ -46,7 +45,6 @@ private: bool decode(uint8_t *buf); DmiBoard m_board; - uint16_t m_count = 0; uint32_t m_size = 0; uint32_t m_version = 0; std::vector<DmiMemory> m_memory; diff --git a/src/hw/dmi/DmiReader_unix.cpp b/src/hw/dmi/DmiReader_unix.cpp index 4919935fd..e9b25abcb 100644 --- a/src/hw/dmi/DmiReader_unix.cpp +++ b/src/hw/dmi/DmiReader_unix.cpp @@ -1,6 +1,8 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> - * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * 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 @@ -18,9 +20,171 @@ #include "hw/dmi/DmiReader.h" +#include "hw/dmi/DmiTools.h" + + +#include <cerrno> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + + +#define FLAG_NO_FILE_OFFSET (1 << 0) + + +namespace xmrig { + + +static const char *kSysEntryFile = "/sys/firmware/dmi/tables/smbios_entry_point"; +static const char *kSysTableFile = "/sys/firmware/dmi/tables/DMI"; + + + +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; +} + + +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) +{ + uint8_t *buf = nullptr; + + if (flags & FLAG_NO_FILE_OFFSET) { + size_t size = len; + buf = read_file(0, &size, devmem); + len = size; + } + else { + // FIXME + } + + return buf; +} + + +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);; +} + + +} // namespace xmrig bool xmrig::DmiReader::read() { + size_t size = 0x20; + uint8_t *buf = read_file(0, &size, kSysEntryFile); + + if (buf) { + uint8_t *smb = nullptr; + + if (size >= 24 && memcmp(buf, "_SM3_", 5) == 0) { + smb = smbios3_decode(buf, kSysTableFile, m_size, m_version, FLAG_NO_FILE_OFFSET); + } + + if (smb) { + decode(smb); + + free(smb); + free(buf); + + return true; + } + } + return false; } diff --git a/src/hw/dmi/DmiReader_win.cpp b/src/hw/dmi/DmiReader_win.cpp index 6b8e2ac46..b79f952a4 100644 --- a/src/hw/dmi/DmiReader_win.cpp +++ b/src/hw/dmi/DmiReader_win.cpp @@ -41,48 +41,6 @@ struct RawSMBIOSData { }; -/* - * Counts the number of SMBIOS structures present in - * the SMBIOS table. - * - * buf - Pointer that receives the SMBIOS Table address. - * This will be the address of the BYTE array from - * the RawSMBIOSData struct. - * - * len - The length of the SMBIOS Table pointed by buff. - * - * return - The number of SMBIOS strutctures. - * - * Remarks: - * The SMBIOS Table Entry Point has this information, - * however the GetSystemFirmwareTable API doesn't - * return all fields from the Entry Point, and - * DMIDECODE uses this value as a parameter for - * dmi_table function. This is the reason why - * this function was make. - * - * Hugo Weber address@hidden - */ -uint16_t count_smbios_structures(const uint8_t *buf, uint32_t len) -{ - uint16_t count = 0; - uint32_t offset = 0; - - while (offset < len) { - offset += reinterpret_cast<const dmi_header *>(buf + offset)->length; - count++; - - while ((*reinterpret_cast<const uint16_t *>(buf + offset) != 0) && (offset < len)) { - offset++; - } - - offset += 2; - } - - return count; -} - - } // namespace xmrig @@ -103,7 +61,6 @@ bool xmrig::DmiReader::read() m_version = (smb->SMBIOSMajorVersion << 16) + (smb->SMBIOSMinorVersion << 8) + smb->DmiRevision; m_size = smb->Length; - m_count = count_smbios_structures(smb->SMBIOSTableData, m_size); const bool rc = decode(smb->SMBIOSTableData); HeapFree(GetProcessHeap(), 0, smb); diff --git a/src/hw/dmi/DmiTools.h b/src/hw/dmi/DmiTools.h index e929e6fe5..65a1dfd75 100644 --- a/src/hw/dmi/DmiTools.h +++ b/src/hw/dmi/DmiTools.h @@ -22,6 +22,7 @@ #define XMRIG_DMITOOLS_H +#include <cstddef> #include <cstdint> @@ -37,6 +38,12 @@ struct dmi_header }; +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); } From 3b8d081c8c63c717dc366f17fad861b75cea45c7 Mon Sep 17 00:00:00 2001 From: XMRig <support@xmrig.com> Date: Mon, 18 Jan 2021 22:56:57 +0700 Subject: [PATCH 03/11] Add support for older DMI formats on Linux. --- src/Summary.cpp | 6 ++-- src/hw/dmi/DmiReader.cpp | 10 ++++++ src/hw/dmi/DmiReader.h | 6 ++++ src/hw/dmi/DmiReader_unix.cpp | 57 ++++++++++++++++++++++++++++++----- src/hw/dmi/DmiReader_win.cpp | 7 ++--- 5 files changed, 72 insertions(+), 14 deletions(-) diff --git a/src/Summary.cpp b/src/Summary.cpp index 345ed48e7..b925232fd 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -129,7 +129,7 @@ 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, @@ -148,11 +148,11 @@ static void print_memory() } if (!memory.size()) { - Log::print(WHITE_BOLD(" %-13s") WHITE_BOLD("%s: ") BLACK_BOLD("<empty>"), "", memory.slot().data()); + Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data()); continue; } - Log::print(WHITE_BOLD(" %-13s") WHITE_BOLD("%s: ") CYAN_BOLD("%" PRIu64 " GB ") WHITE_BOLD("%s @ %" PRIu64 " MHz ") BLACK_BOLD("%s"), + 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()); } diff --git a/src/hw/dmi/DmiReader.cpp b/src/hw/dmi/DmiReader.cpp index 66f1dd5fa..8993531a6 100644 --- a/src/hw/dmi/DmiReader.cpp +++ b/src/hw/dmi/DmiReader.cpp @@ -38,6 +38,16 @@ static void dmi_get_header(dmi_header *h, uint8_t *data) } // namespace xmrig +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) { diff --git a/src/hw/dmi/DmiReader.h b/src/hw/dmi/DmiReader.h index 243b5164b..f140f8676 100644 --- a/src/hw/dmi/DmiReader.h +++ b/src/hw/dmi/DmiReader.h @@ -26,6 +26,9 @@ #include "hw/dmi/DmiMemory.h" +#include <functional> + + namespace xmrig { @@ -42,6 +45,9 @@ public: bool read(); private: + using Cleanup = std::function<void()>; + + bool decode(uint8_t *buf, const Cleanup &cleanup); bool decode(uint8_t *buf); DmiBoard m_board; diff --git a/src/hw/dmi/DmiReader_unix.cpp b/src/hw/dmi/DmiReader_unix.cpp index e9b25abcb..db5160126 100644 --- a/src/hw/dmi/DmiReader_unix.cpp +++ b/src/hw/dmi/DmiReader_unix.cpp @@ -157,7 +157,46 @@ static uint8_t *smbios3_decode(uint8_t *buf, const char *devmem, uint32_t &size, 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);; + 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); } @@ -175,14 +214,18 @@ bool xmrig::DmiReader::read() 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) { - decode(smb); - - free(smb); - free(buf); - - return true; + return decode(smb, [smb, buf]() { + free(smb); + free(buf); + }); } } diff --git a/src/hw/dmi/DmiReader_win.cpp b/src/hw/dmi/DmiReader_win.cpp index b79f952a4..837bdb7b3 100644 --- a/src/hw/dmi/DmiReader_win.cpp +++ b/src/hw/dmi/DmiReader_win.cpp @@ -62,8 +62,7 @@ bool xmrig::DmiReader::read() m_version = (smb->SMBIOSMajorVersion << 16) + (smb->SMBIOSMinorVersion << 8) + smb->DmiRevision; m_size = smb->Length; - const bool rc = decode(smb->SMBIOSTableData); - HeapFree(GetProcessHeap(), 0, smb); - - return rc; + return decode(smb->SMBIOSTableData, [smb]() { + HeapFree(GetProcessHeap(), 0, smb); + }); } From 3df47052ed499a24d9045efed07a9c5f8713c387 Mon Sep 17 00:00:00 2001 From: XMRig <support@xmrig.com> Date: Tue, 19 Jan 2021 01:23:09 +0700 Subject: [PATCH 04/11] Added legacy DMI readers for Linux. --- src/hw/dmi/DmiReader_unix.cpp | 211 +++++++++++++++++++++++++++++++--- 1 file changed, 197 insertions(+), 14 deletions(-) diff --git a/src/hw/dmi/DmiReader_unix.cpp b/src/hw/dmi/DmiReader_unix.cpp index db5160126..d73e39436 100644 --- a/src/hw/dmi/DmiReader_unix.cpp +++ b/src/hw/dmi/DmiReader_unix.cpp @@ -25,19 +25,38 @@ #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 *kSysEntryFile = "/sys/firmware/dmi/tables/smbios_entry_point"; -static const char *kSysTableFile = "/sys/firmware/dmi/tables/DMI"; +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 +} @@ -118,6 +137,69 @@ out: } +/* + * 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; @@ -132,18 +214,15 @@ static int checksum(const uint8_t *buf, size_t len) static uint8_t *dmi_table(off_t base, uint32_t &len, const char *devmem, uint32_t flags) { - uint8_t *buf = nullptr; - if (flags & FLAG_NO_FILE_OFFSET) { size_t size = len; - buf = read_file(0, &size, devmem); + auto buf = read_file(0, &size, devmem); len = size; - } - else { - // FIXME + + return buf; } - return buf; + return mem_chunk(base, len, devmem); } @@ -200,6 +279,50 @@ static uint8_t *legacy_decode(uint8_t *buf, const char *devmem, uint32_t &size, } +#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]; +# elif defined(__FreeBSD__) + char addrstr[KENV_MVALLEN + 1]; +# endif + + off_t address = 0; + +# 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 @@ -207,9 +330,10 @@ bool xmrig::DmiReader::read() { size_t size = 0x20; uint8_t *buf = read_file(0, &size, kSysEntryFile); + uint8_t *smb = nullptr; if (buf) { - uint8_t *smb = nullptr; + smb = nullptr; if (size >= 24 && memcmp(buf, "_SM3_", 5) == 0) { smb = smbios3_decode(buf, kSysTableFile, m_size, m_version, FLAG_NO_FILE_OFFSET); @@ -222,12 +346,71 @@ bool xmrig::DmiReader::read() } if (smb) { - return decode(smb, [smb, buf]() { - free(smb); - free(buf); - }); + 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; } From 9dffcdaddd02752c8a39827521227dcd57f4bc1f Mon Sep 17 00:00:00 2001 From: XMRig <support@xmrig.com> Date: Tue, 19 Jan 2021 01:45:17 +0700 Subject: [PATCH 05/11] Enable FreeBSD support. --- src/hw/dmi/DmiReader_unix.cpp | 3 +-- src/hw/dmi/dmi.cmake | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hw/dmi/DmiReader_unix.cpp b/src/hw/dmi/DmiReader_unix.cpp index d73e39436..ff57b7a6a 100644 --- a/src/hw/dmi/DmiReader_unix.cpp +++ b/src/hw/dmi/DmiReader_unix.cpp @@ -287,12 +287,11 @@ static off_t address_from_efi() FILE *efi_systab; const char *filename; char linebuf[64]; + off_t address = 0; # elif defined(__FreeBSD__) char addrstr[KENV_MVALLEN + 1]; # endif - off_t address = 0; - # 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; diff --git a/src/hw/dmi/dmi.cmake b/src/hw/dmi/dmi.cmake index ff4882ce0..e10ec3ed4 100644 --- a/src/hw/dmi/dmi.cmake +++ b/src/hw/dmi/dmi.cmake @@ -17,7 +17,7 @@ if (WITH_DMI) if (XMRIG_OS_WIN) list(APPEND SOURCES src/hw/dmi/DmiReader_win.cpp) - elseif(XMRIG_OS_LINUX) + elseif(XMRIG_OS_LINUX OR XMRIG_OS_FREEBSD) list(APPEND SOURCES src/hw/dmi/DmiReader_unix.cpp) endif() else() From 24c290963aea6034d7ece6fafdc4480943dd8d7f Mon Sep 17 00:00:00 2001 From: XMRig <support@xmrig.com> Date: Tue, 19 Jan 2021 14:16:03 +0700 Subject: [PATCH 06/11] Added DMI reader for macOS. --- src/Summary.cpp | 12 ++-- src/hw/dmi/DmiReader.cpp | 4 ++ src/hw/dmi/DmiReader_mac.cpp | 108 +++++++++++++++++++++++++++++++++++ src/hw/dmi/dmi.cmake | 4 ++ 4 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 src/hw/dmi/DmiReader_mac.cpp diff --git a/src/Summary.cpp b/src/Summary.cpp index b925232fd..8118f99d7 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -147,13 +147,13 @@ static void print_memory() continue; } - if (!memory.size()) { - Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data()); - 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 (!Cpu::info()->isVM()) { + Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data()); } - - 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()); } if (reader.board().isValid()) { diff --git a/src/hw/dmi/DmiReader.cpp b/src/hw/dmi/DmiReader.cpp index 8993531a6..5c6a9607f 100644 --- a/src/hw/dmi/DmiReader.cpp +++ b/src/hw/dmi/DmiReader.cpp @@ -70,6 +70,10 @@ bool xmrig::DmiReader::decode(uint8_t *buf) 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) { 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/dmi.cmake b/src/hw/dmi/dmi.cmake index e10ec3ed4..aee0ff9a3 100644 --- a/src/hw/dmi/dmi.cmake +++ b/src/hw/dmi/dmi.cmake @@ -19,6 +19,10 @@ if (WITH_DMI) 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) From dea5be0a57029074bde06db1faabbcd82be64bb8 Mon Sep 17 00:00:00 2001 From: XMRig <support@xmrig.com> Date: Wed, 20 Jan 2021 00:43:01 +0700 Subject: [PATCH 07/11] Added basic system reader. --- src/Summary.cpp | 8 ++++++-- src/hw/dmi/DmiBoard.cpp | 1 - src/hw/dmi/DmiReader.cpp | 4 ++++ src/hw/dmi/DmiReader.h | 4 +++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Summary.cpp b/src/Summary.cpp index 8118f99d7..0cbbbbcad 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -142,6 +142,8 @@ static void print_memory() return; } + const bool vm = Cpu::info()->isVM(); + for (const auto &memory : reader.memory()) { if (!memory.isValid()) { continue; @@ -151,12 +153,14 @@ static void print_memory() 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 (!Cpu::info()->isVM()) { + else if (!vm) { Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data()); } } - if (reader.board().isValid()) { + 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", reader.board().vendor().data(), reader.board().product().data()); } # endif diff --git a/src/hw/dmi/DmiBoard.cpp b/src/hw/dmi/DmiBoard.cpp index 381865f4e..5ebfd9aa3 100644 --- a/src/hw/dmi/DmiBoard.cpp +++ b/src/hw/dmi/DmiBoard.cpp @@ -23,7 +23,6 @@ #include "hw/dmi/DmiTools.h" - void xmrig::DmiBoard::decode(dmi_header *h) { if (h->length < 0x08) { diff --git a/src/hw/dmi/DmiReader.cpp b/src/hw/dmi/DmiReader.cpp index 5c6a9607f..9854ff1b4 100644 --- a/src/hw/dmi/DmiReader.cpp +++ b/src/hw/dmi/DmiReader.cpp @@ -82,6 +82,10 @@ bool xmrig::DmiReader::decode(uint8_t *buf) } switch (h.type) { + case 1: + m_system.decode(&h); + break; + case 2: m_board.decode(&h); break; diff --git a/src/hw/dmi/DmiReader.h b/src/hw/dmi/DmiReader.h index f140f8676..ccf2311ae 100644 --- a/src/hw/dmi/DmiReader.h +++ b/src/hw/dmi/DmiReader.h @@ -38,6 +38,7 @@ 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; } @@ -51,9 +52,10 @@ private: 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; - std::vector<DmiMemory> m_memory; }; From efc5e5d81128389cad59ea0d9a6258dd717c8c9c Mon Sep 17 00:00:00 2001 From: XMRig <support@xmrig.com> Date: Wed, 20 Jan 2021 00:45:36 +0700 Subject: [PATCH 08/11] Fix summary. --- src/Summary.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Summary.cpp b/src/Summary.cpp index 0cbbbbcad..e0c4d58e9 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -161,7 +161,7 @@ static void print_memory() 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", reader.board().vendor().data(), reader.board().product().data()); + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") " - " WHITE_BOLD("%s"), "MOTHERBOARD", board.vendor().data(), board.product().data()); } # endif } From 9a0200790042d22664a39f54c0199f27318c69a5 Mon Sep 17 00:00:00 2001 From: XMRig <support@xmrig.com> Date: Wed, 20 Jan 2021 16:02:48 +0700 Subject: [PATCH 09/11] Added config option "dmi" and command line option "--no-dmi". --- CMakeLists.txt | 2 +- src/Summary.cpp | 32 ++++++++++------- src/Summary.h | 4 +-- src/base/kernel/interfaces/IConfig.h | 5 +-- src/core/config/Config.cpp | 38 +++++++++++++++++---- src/core/config/Config.h | 28 +++++++++++++-- src/core/config/ConfigTransform.cpp | 51 ++++++++++++++-------------- src/core/config/ConfigTransform.h | 4 +-- src/core/config/Config_platform.h | 5 +++ src/core/config/usage.h | 4 +++ src/hw/dmi/dmi.cmake | 4 +++ 11 files changed, 121 insertions(+), 56 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 69f40fcdd..fe411cb1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +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 reader" 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) diff --git a/src/Summary.cpp b/src/Summary.cpp index e0c4d58e9..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 @@ -76,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")); @@ -92,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(); @@ -121,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()); @@ -137,6 +137,10 @@ static void print_memory() ); # ifdef XMRIG_FEATURE_DMI + if (!config->isDMI()) { + return; + } + DmiReader reader; if (!reader.read()) { return; @@ -167,7 +171,7 @@ static void print_memory() } -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", @@ -209,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/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/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/dmi/dmi.cmake b/src/hw/dmi/dmi.cmake index aee0ff9a3..5140692a7 100644 --- a/src/hw/dmi/dmi.cmake +++ b/src/hw/dmi/dmi.cmake @@ -1,3 +1,7 @@ +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) From 8471f7fad3db29e0765d733335647c63fedc5822 Mon Sep 17 00:00:00 2001 From: XMRig <support@xmrig.com> Date: Wed, 20 Jan 2021 22:54:02 +0700 Subject: [PATCH 10/11] Added "GET /2/dmi" API endpoint. --- CMakeLists.txt | 3 +- src/base/api/Api.cpp | 10 +--- src/base/api/Api.h | 11 +---- src/base/api/interfaces/IApiListener.h | 14 +++--- src/base/api/interfaces/IApiRequest.h | 16 +++---- src/base/kernel/interfaces/IBaseListener.h | 18 ++++---- src/core/Controller.cpp | 42 ++++++++--------- src/core/Controller.h | 23 +++++----- src/hw/api/HwApi.cpp | 47 +++++++++++++++++++ src/hw/api/HwApi.h | 53 ++++++++++++++++++++++ src/hw/api/api.cmake | 11 +++++ src/hw/dmi/DmiBoard.cpp | 16 +++++++ src/hw/dmi/DmiBoard.h | 4 ++ src/hw/dmi/DmiMemory.cpp | 26 +++++++++++ src/hw/dmi/DmiMemory.h | 4 ++ src/hw/dmi/DmiReader.cpp | 34 ++++++++++++++ src/hw/dmi/DmiReader.h | 5 ++ 17 files changed, 263 insertions(+), 74 deletions(-) create mode 100644 src/hw/api/HwApi.cpp create mode 100644 src/hw/api/HwApi.h create mode 100644 src/hw/api/api.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index fe411cb1c..79486e03e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -198,7 +198,8 @@ if (WITH_EMBEDDED_CONFIG) add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG) endif() -include (src/hw/dmi/dmi.cmake) +include(src/hw/api/api.cmake) +include(src/hw/dmi/dmi.cmake) include_directories(src) include_directories(src/3rdparty) 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/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/hw/api/HwApi.cpp b/src/hw/api/HwApi.cpp new file mode 100644 index 000000000..5aedbf334 --- /dev/null +++ b/src/hw/api/HwApi.cpp @@ -0,0 +1,47 @@ +/* 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" + +#include "base/io/log/Log.h" // FIXME + + +#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 index 5ebfd9aa3..3cbe3dd9a 100644 --- a/src/hw/dmi/DmiBoard.cpp +++ b/src/hw/dmi/DmiBoard.cpp @@ -20,6 +20,7 @@ #include "hw/dmi/DmiBoard.h" +#include "3rdparty/rapidjson/document.h" #include "hw/dmi/DmiTools.h" @@ -32,3 +33,18 @@ void xmrig::DmiBoard::decode(dmi_header *h) 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 index dd28a607b..0c64da17c 100644 --- a/src/hw/dmi/DmiBoard.h +++ b/src/hw/dmi/DmiBoard.h @@ -42,6 +42,10 @@ public: void decode(dmi_header *h); +# ifdef XMRIG_FEATURE_API + rapidjson::Value toJSON(rapidjson::Document &doc) const; +# endif + private: String m_product; String m_vendor; diff --git a/src/hw/dmi/DmiMemory.cpp b/src/hw/dmi/DmiMemory.cpp index f02a64ecd..5b36e2bae 100644 --- a/src/hw/dmi/DmiMemory.cpp +++ b/src/hw/dmi/DmiMemory.cpp @@ -20,6 +20,7 @@ #include "hw/dmi/DmiMemory.h" +#include "3rdparty/rapidjson/document.h" #include "hw/dmi/DmiTools.h" @@ -190,3 +191,28 @@ 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 index b9a0468b0..badee2cfd 100644 --- a/src/hw/dmi/DmiMemory.h +++ b/src/hw/dmi/DmiMemory.h @@ -52,6 +52,10 @@ public: 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; diff --git a/src/hw/dmi/DmiReader.cpp b/src/hw/dmi/DmiReader.cpp index 9854ff1b4..18211759a 100644 --- a/src/hw/dmi/DmiReader.cpp +++ b/src/hw/dmi/DmiReader.cpp @@ -20,6 +20,8 @@ #include "hw/dmi/DmiReader.h" +#include "3rdparty/fmt/core.h" +#include "3rdparty/rapidjson/document.h" #include "hw/dmi/DmiTools.h" @@ -38,6 +40,38 @@ static void dmi_get_header(dmi_header *h, uint8_t *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); diff --git a/src/hw/dmi/DmiReader.h b/src/hw/dmi/DmiReader.h index ccf2311ae..a4f7eb8a7 100644 --- a/src/hw/dmi/DmiReader.h +++ b/src/hw/dmi/DmiReader.h @@ -45,6 +45,11 @@ public: 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()>; From ef8cc28f3f250eb3adcd380a3da253a83102ab8d Mon Sep 17 00:00:00 2001 From: XMRig <support@xmrig.com> Date: Thu, 21 Jan 2021 23:22:01 +0700 Subject: [PATCH 11/11] Added DMI data to online benchmark. --- src/base/net/stratum/Pools.cpp | 6 +++--- src/base/net/stratum/Pools.h | 4 ++-- src/base/net/stratum/benchmark/BenchClient.cpp | 17 +++++++++++++++-- src/base/net/stratum/benchmark/BenchClient.h | 4 ++-- src/base/net/stratum/benchmark/BenchConfig.cpp | 11 ++++++----- src/base/net/stratum/benchmark/BenchConfig.h | 10 ++++++---- src/hw/api/HwApi.cpp | 2 -- 7 files changed, 34 insertions(+), 20 deletions(-) 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/hw/api/HwApi.cpp b/src/hw/api/HwApi.cpp index 5aedbf334..fed5de3f9 100644 --- a/src/hw/api/HwApi.cpp +++ b/src/hw/api/HwApi.cpp @@ -21,8 +21,6 @@ #include "base/api/interfaces/IApiRequest.h" #include "base/tools/String.h" -#include "base/io/log/Log.h" // FIXME - #ifdef XMRIG_FEATURE_DMI # include "hw/dmi/DmiReader.h"