Added support for write custom MSR.
This commit is contained in:
parent
33e7a54c29
commit
8bef964f68
15 changed files with 408 additions and 106 deletions
|
@ -48,17 +48,8 @@
|
|||
namespace xmrig {
|
||||
|
||||
|
||||
enum MsrMod : uint32_t {
|
||||
MSR_MOD_NONE,
|
||||
MSR_MOD_RYZEN,
|
||||
MSR_MOD_INTEL,
|
||||
MSR_MOD_MAX
|
||||
};
|
||||
|
||||
|
||||
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ") " ";
|
||||
static const std::array<const char *, MSR_MOD_MAX> modNames = { nullptr, "Ryzen", "Intel" };
|
||||
static bool reuseDriver = false;
|
||||
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ") " ";
|
||||
static bool reuseDriver = false;
|
||||
|
||||
|
||||
static SC_HANDLE hManager;
|
||||
|
@ -189,7 +180,7 @@ static HANDLE wrmsr_install_driver()
|
|||
#define IOCTL_WRITE_MSR CTL_CODE(40000, 0x822, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
|
||||
static bool wrmsr(HANDLE hDriver, uint32_t reg, uint64_t value) {
|
||||
static bool wrmsr(HANDLE driver, uint32_t reg, uint64_t value) {
|
||||
struct {
|
||||
uint32_t reg = 0;
|
||||
uint32_t value[2]{};
|
||||
|
@ -198,12 +189,12 @@ static bool wrmsr(HANDLE hDriver, uint32_t reg, uint64_t value) {
|
|||
static_assert(sizeof(input) == 12, "Invalid struct size for WinRing0 driver");
|
||||
|
||||
input.reg = reg;
|
||||
*((uint64_t*)input.value) = value;
|
||||
*(reinterpret_cast<uint64_t*>(input.value)) = value;
|
||||
|
||||
DWORD output;
|
||||
DWORD k;
|
||||
|
||||
if (!DeviceIoControl(hDriver, IOCTL_WRITE_MSR, &input, sizeof(input), &output, sizeof(output), &k, nullptr)) {
|
||||
if (!DeviceIoControl(driver, IOCTL_WRITE_MSR, &input, sizeof(input), &output, sizeof(output), &k, nullptr)) {
|
||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot set MSR 0x%08" PRIx32 " to 0x%08" PRIx64, tag, reg, value);
|
||||
|
||||
return false;
|
||||
|
@ -213,55 +204,29 @@ static bool wrmsr(HANDLE hDriver, uint32_t reg, uint64_t value) {
|
|||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
void xmrig::Rx::osInit(const RxConfig &config)
|
||||
static bool wrmsr(const MsrItems &preset)
|
||||
{
|
||||
if ((config.wrmsr() < 0) || !ICpuInfo::isX64()) {
|
||||
return;
|
||||
}
|
||||
bool success = true;
|
||||
|
||||
MsrMod mod = MSR_MOD_NONE;
|
||||
if (Cpu::info()->assembly() == Assembly::RYZEN) {
|
||||
mod = MSR_MOD_RYZEN;
|
||||
}
|
||||
else if (Cpu::info()->vendor() == ICpuInfo::VENDOR_INTEL) {
|
||||
mod = MSR_MOD_INTEL;
|
||||
}
|
||||
|
||||
if (mod == MSR_MOD_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
bool success = true;
|
||||
|
||||
HANDLE hDriver = wrmsr_install_driver();
|
||||
if (!hDriver) {
|
||||
HANDLE driver = wrmsr_install_driver();
|
||||
if (!driver) {
|
||||
wrmsr_uninstall_driver();
|
||||
|
||||
if (hManager) {
|
||||
CloseServiceHandle(hManager);
|
||||
}
|
||||
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::thread wrmsr_thread([hDriver, mod, &config, &success]() {
|
||||
std::thread wrmsr_thread([driver, &preset, &success]() {
|
||||
for (uint32_t i = 0, n = Cpu::info()->threads(); i < n; ++i) {
|
||||
if (!Platform::setThreadAffinity(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mod == MSR_MOD_RYZEN) {
|
||||
success = wrmsr(hDriver, 0xC0011020, 0) &&
|
||||
wrmsr(hDriver, 0xC0011021, 0x40) &&
|
||||
wrmsr(hDriver, 0xC0011022, 0x510000) &&
|
||||
wrmsr(hDriver, 0xC001102b, 0x1808cc16);
|
||||
}
|
||||
else if (mod == MSR_MOD_INTEL) {
|
||||
success = wrmsr(hDriver, 0x1a4, config.wrmsr());
|
||||
for (const auto &i : preset) {
|
||||
success = wrmsr(driver, i.reg(), i.value());
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
|
@ -272,15 +237,33 @@ void xmrig::Rx::osInit(const RxConfig &config)
|
|||
|
||||
wrmsr_thread.join();
|
||||
|
||||
CloseHandle(hDriver);
|
||||
CloseHandle(driver);
|
||||
|
||||
wrmsr_uninstall_driver();
|
||||
CloseServiceHandle(hManager);
|
||||
|
||||
if (success) {
|
||||
LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for %s has been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, modNames[mod], Chrono::steadyMSecs() - ts);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
void xmrig::Rx::msrInit(const RxConfig &config)
|
||||
{
|
||||
const auto &preset = config.msrPreset();
|
||||
if (preset.empty()) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
LOG_ERR(CLEAR "%s" RED_BOLD_S "failed to write MSR registers" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts);
|
||||
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
if (wrmsr(preset)) {
|
||||
LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for \"%s\" preset has been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, config.msrPresetName(), Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::msrDestroy()
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue