Added RxMsr class.
This commit is contained in:
parent
b9d813c403
commit
9dae559b73
17 changed files with 435 additions and 746 deletions
|
@ -55,6 +55,24 @@ std::shared_ptr<xmrig::Msr> xmrig::Msr::get()
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::write(uint32_t reg, uint64_t value, int32_t cpu, uint64_t mask, bool verbose)
|
||||
{
|
||||
if (mask != MsrItem::kNoMask) {
|
||||
uint64_t old_value;
|
||||
if (rdmsr(reg, cpu, old_value)) {
|
||||
value = MsrItem::maskedValue(old_value, value, mask);
|
||||
}
|
||||
}
|
||||
|
||||
const bool result = wrmsr(reg, value, cpu);
|
||||
if (!result && verbose) {
|
||||
LOG_WARN("%s " YELLOW_BOLD("cannot set MSR 0x%08" PRIx32 " to 0x%016" PRIx64), tag(), reg, value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
xmrig::MsrItem xmrig::Msr::read(uint32_t reg, int32_t cpu, bool verbose) const
|
||||
{
|
||||
uint64_t value = 0;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "hw/msr/MsrItem.h"
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
@ -39,17 +40,24 @@ class Msr
|
|||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE(Msr)
|
||||
|
||||
using Callback = std::function<bool(int32_t cpu)>;
|
||||
|
||||
Msr();
|
||||
~Msr();
|
||||
|
||||
static const char *tag();
|
||||
static std::shared_ptr<Msr> get();
|
||||
|
||||
inline bool write(const MsrItem &item, int32_t cpu = -1, bool verbose = true) { return write(item.reg(), item.value(), cpu, item.mask(), verbose); }
|
||||
|
||||
bool isAvailable() const;
|
||||
bool write(uint32_t reg, uint64_t value, int32_t cpu = -1, uint64_t mask = MsrItem::kNoMask, bool verbose = true);
|
||||
bool write(Callback &&callback);
|
||||
MsrItem read(uint32_t reg, int32_t cpu = -1, bool verbose = true) const;
|
||||
|
||||
private:
|
||||
bool rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const;
|
||||
bool wrmsr(uint32_t reg, uint64_t value, int32_t cpu);
|
||||
|
||||
MsrPrivate *d_ptr = nullptr;
|
||||
};
|
||||
|
|
|
@ -46,6 +46,11 @@ public:
|
|||
inline uint64_t value() const { return m_value; }
|
||||
inline uint64_t mask() const { return m_mask; }
|
||||
|
||||
static inline uint64_t maskedValue(uint64_t old_value, uint64_t new_value, uint64_t mask)
|
||||
{
|
||||
return (new_value & mask) | (old_value & ~mask);
|
||||
}
|
||||
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
String toString() const;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "hw/msr/Msr.h"
|
||||
#include "3rdparty/fmt/core.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
||||
|
@ -31,8 +32,6 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
@ -70,6 +69,20 @@ bool xmrig::Msr::isAvailable() const
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::write(Callback &&callback)
|
||||
{
|
||||
const auto &units = Cpu::info()->units();
|
||||
|
||||
for (int32_t pu : units) {
|
||||
if (!callback(pu)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const
|
||||
{
|
||||
const auto name = fmt::format("/dev/cpu/{}/msr", cpu < 0 ? 0 : cpu);
|
||||
|
@ -84,3 +97,20 @@ bool xmrig::Msr::rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const
|
|||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::wrmsr(uint32_t reg, uint64_t value, int32_t cpu)
|
||||
{
|
||||
const auto name = fmt::format("/dev/cpu/{}/msr", cpu < 0 ? 0 : cpu);
|
||||
int fd = open(name.c_str(), O_WRONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool success = pwrite(fd, &value, sizeof value, reg) == sizeof value;
|
||||
|
||||
close(fd);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -18,10 +18,13 @@
|
|||
|
||||
|
||||
#include "hw/msr/Msr.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
|
@ -196,9 +199,57 @@ bool xmrig::Msr::isAvailable() const
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::rdmsr(uint32_t reg, int32_t, uint64_t &value) const
|
||||
bool xmrig::Msr::write(Callback &&callback)
|
||||
{
|
||||
const auto &units = Cpu::info()->units();
|
||||
bool success = false;
|
||||
|
||||
std::thread thread([&callback, &units, &success]() {
|
||||
for (int32_t pu : units) {
|
||||
if (!Platform::setThreadAffinity(pu)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!callback(pu)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
success = true;
|
||||
});
|
||||
|
||||
thread.join();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const
|
||||
{
|
||||
assert(cpu < 0);
|
||||
|
||||
DWORD size = 0;
|
||||
|
||||
return DeviceIoControl(d_ptr->driver, IOCTL_READ_MSR, ®, sizeof(reg), &value, sizeof(value), &size, nullptr) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Msr::wrmsr(uint32_t reg, uint64_t value, int32_t cpu)
|
||||
{
|
||||
assert(cpu < 0);
|
||||
|
||||
struct {
|
||||
uint32_t reg = 0;
|
||||
uint32_t value[2]{};
|
||||
} input;
|
||||
|
||||
static_assert(sizeof(input) == 12, "Invalid struct size for WinRing0 driver");
|
||||
|
||||
input.reg = reg;
|
||||
*(reinterpret_cast<uint64_t*>(input.value)) = value;
|
||||
|
||||
DWORD output;
|
||||
DWORD k;
|
||||
|
||||
return DeviceIoControl(d_ptr->driver, IOCTL_WRITE_MSR, &input, sizeof(input), &output, sizeof(output), &k, nullptr) != 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue