/* * Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope 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 . * */ /* -------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * , , * wrote this file. As long as you retain this notice you can do whatever you * want with this stuff. If you meet any of us some day, and you think this * stuff is worth it, you can buy us a beer in return. - The sys-clk authors * -------------------------------------------------------------------------- */ #include #include "board_fuse.hpp" namespace board { namespace { constexpr u32 FuseCpuSpeedoCalib = 0x114; // constexpr u32 FuseCpuSpeedo1Calib = 0x12C; constexpr u32 FuseGpuSpeedoCalib = 0x130; constexpr u32 FuseSocSpeedoCalib = 0x134; // constexpr u32 FuseSocSpeedo1Calib = 0x138; // constexpr u32 FuseSocSpeedo2Calib = 0x13C; constexpr u32 FuseCpuIddqCalib = 0x118; constexpr u32 FuseSocIddqCalib = 0x140; constexpr u32 FuseGpuIddqCalib = 0x228; } void SetGpuBracket(u8 speedo, u8 &gpuBracket) { if (speedo <= 1624) { gpuBracket = 0; return; } if (speedo <= 1689) { gpuBracket = 1; return; } if (speedo <= 1753) { gpuBracket = 2; return; } /* >= 1754 */ gpuBracket = 3; } FuseReadSpeedo(FuseSpeedoData &speedo) { u64 pid = 0; constexpr u64 UsbID = 0x0100000000000006; if (R_FAILED(pmdmntGetProcessId(&pid, UsbID))) { return; } Handle debug; if (R_FAILED(svcDebugActiveProcess(&debug, pid))) { return; } MemoryInfo mem_info = {}; u32 pageinfo = 0; u64 addr = 0; u8 stack[0x10] = {}; const u8 compare[0x10] = {}; u8 dump[0x400] = {}; constexpr u64 PageSize = 0x1000; while (true) { if (R_FAILED(svcQueryDebugProcessMemory(&mem_info, &pageinfo, debug, addr)) || mem_info.addr < addr) { break; } if (mem_info.type == MemType_Io && mem_info.size == PageSize) { if (R_FAILED(svcReadDebugProcessMemory(stack, debug, mem_info.addr, sizeof(stack)))) { break; } if (memcmp(stack, compare, sizeof(stack)) == 0) { if (R_FAILED(svcReadDebugProcessMemory(dump, debug, mem_info.addr + 0x800, sizeof(dump)))) { break; } speedo.cpuSpeedo = *reinterpret_cast(dump + FuseCpuSpeedoCalib); speedo.gpuSpeedo = *reinterpret_cast(dump + FuseGpuSpeedoCalib); speedo.socSpeedo = *reinterpret_cast(dump + FuseSocSpeedoCalib); speedo.cpuIDDQ = *reinterpret_cast(dump + FuseCpuIddqCalib); speedo.gpuIDDQ = *reinterpret_cast(dump + FuseSocIddqCalib); speedo.socIDDQ = *reinterpret_cast(dump + FUSE_GPU_IDDQ_CALIB); svcCloseHandle(debug); return; } } addr = mem_info.addr + mem_info.size; } svcCloseHandle(debug); } }