7z¼¯'4#Ñ{§8jýšbsdiff --git a/build.sh b/build.sh new file mode 100755 index 00000000..e5ccc845 --- /dev/null +++ b/build.sh @@ -0,0 +1 @@ +make clean && make -j17 -C libraries/libstratosphere && make -j17 -C stratosphere/loader \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_patcher.cpp b/stratosphere/loader/source/ldr_patcher.cpp index 99385fc5..dfc5f5d7 100644 --- a/stratosphere/loader/source/ldr_patcher.cpp +++ b/stratosphere/loader/source/ldr_patcher.cpp @@ -15,6 +15,7 @@ */ #include #include "ldr_patcher.hpp" +#include "ldr_pcv_patch.hpp" namespace ams::ldr { @@ -140,6 +141,13 @@ namespace ams::ldr { } } } + + for(unsigned int i = 0; i < sizeof(PcvInfo)/sizeof(PcvInfo[0]); i++) { + if (std::memcmp(PcvInfo[i].ModuleId, build_id, 20) == 0) { + ApplyPcvPatch(reinterpret_cast(mapped_nso), mapped_size, i); + return; + } + } } } \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_pcv_patch.cpp b/stratosphere/loader/source/ldr_pcv_patch.cpp new file mode 100644 index 00000000..9f75ff9c --- /dev/null +++ b/stratosphere/loader/source/ldr_pcv_patch.cpp @@ -0,0 +1,50 @@ +#include +#include "ldr_pcv_patch.hpp" + +#define EMC_OVERCLOCK 1 +#define EMC_OVERVOLT 0 + +namespace ams::ldr { + + namespace { + + constexpr u32 NewEmcFreq = 1862400; + + namespace Erista { + /* EMC */ + constexpr u32 NewEmcVoltage = 1200000; + static_assert(NewEmcVoltage <= 1250000); + + }; + + namespace Mariko { + /* NOTE: Mariko hardware was not supported until firmware 5.0.0 */ + /* ... */ + }; + + } + + void ApplyPcvPatch(u8 *mapped_module, size_t mapped_size, u32 target_version) { + /* Patch EMC clocks and voltage if enabled. note: requires removing minerva or modifiying minerva to enable overclocking */ + if constexpr(EMC_OVERCLOCK) { + for(u32 i = 0; i < PcvInfo[target_version].EmcFreqOffsets.offset_count; i++) { + AMS_ABORT_UNLESS(PcvInfo[target_version].EmcFreqOffsets.offsets[i] <= mapped_size); + std::memcpy(mapped_module + PcvInfo[target_version].EmcFreqOffsets.offsets[i], &NewEmcFreq, sizeof(NewEmcFreq)); + } + } + + if constexpr(EMC_OVERVOLT) { + if(spl::GetSocType() == spl::SocType_Erista) { + for(u32 i = 0; i < 2; i++) { + AMS_ABORT_UNLESS(PcvInfo[target_version].EristaEmcVolatageOffsets[i] <= mapped_size); + std::memcpy(mapped_module + PcvInfo[target_version].EristaEmcVolatageOffsets[i], &Erista::NewEmcVoltage, sizeof(Erista::NewEmcVoltage)); + } + } else if(spl::GetSocType() == spl::SocType_Mariko && PcvInfo[target_version].MarikoSupported) { + /* ... */ + } + } + + return; + } + +} diff --git a/stratosphere/loader/source/ldr_pcv_patch.hpp b/stratosphere/loader/source/ldr_pcv_patch.hpp new file mode 100644 index 00000000..7f38736c --- /dev/null +++ b/stratosphere/loader/source/ldr_pcv_patch.hpp @@ -0,0 +1,267 @@ +#pragma once +#include + +namespace ams::ldr { + + typedef struct { + u8 offset_count = 0; + u32 offsets[30] = {0}; + } emc_freq_offset_info_t; + + typedef struct { + u8 ModuleId[20] = {0}; + + bool MarikoSupported = false; + + /* Common */ + emc_freq_offset_info_t EmcFreqOffsets = {0, {0}}; + + /* Erista Specific */ + u32 EristaEmcVolatageOffsets[2] = {0}; + + /* Mariko Specific */ + /* ... */ + } pcv_offset_info_t; + + constexpr pcv_offset_info_t PcvInfo[] = { + /* 0.4.0 */ + { + .ModuleId = { 0x93, 0x8B, 0xB8, 0x1D, 0xC5, 0x29, 0x26, 0xB6, 0x0F, 0x01, 0x0C, 0xC6, 0x11, 0xF7, 0x5A, 0x09, 0x99, 0x44, 0xD1, 0xDF }, + + .MarikoSupported = false, + + .EmcFreqOffsets = {4, { 0x9605C, 0xA7A0C, 0xB3A8C, 0xBFB0C}}, + + /* Erista Specific */ + // NOTE: Default is 1100mV + .EristaEmcVolatageOffsets = { 0x831D0, 0x831D4 }, + }, + + /* 1.0.0-7 */ + { + .ModuleId = { 0xB5, 0x92, 0x56, 0x04, 0xD5, 0x5D, 0xD4, 0xBA, 0x0A, 0x4F, 0x53, 0xEF, 0x2D, 0x54, 0x76, 0x52, 0xEC, 0x10, 0x88, 0x4F }, + + .MarikoSupported = false, + + .EmcFreqOffsets = { 5, { 0xE211C, 0xFA38C, 0x10640C, 0x11248C, 0x11E50C } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0xD4B48, 0xD4B4C } + }, + + /* 1.0.0-15 */ + { + .ModuleId = { 0x79, 0x8E, 0x17, 0xE0, 0x82, 0xFD, 0xAD, 0x67, 0x13, 0xAC, 0x80, 0x71, 0x81, 0x04, 0x02, 0x77, 0xC8, 0x04, 0x96, 0xBB }, + + .MarikoSupported = false, + + .EmcFreqOffsets = { 5, { 0xE211C, 0xFA38C, 0x10640C, 0x11248C, 0x11E50C } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0xD4B48, 0xD4B4C } + }, + + /* 2.0.0-13 to 2.3.0 */ + { + .ModuleId = { 0x98, 0xE4, 0xC0, 0xFE, 0x3A, 0x85, 0x87, 0x94, 0x2C, 0x4F, 0x3E, 0x39, 0xA9, 0x36, 0xDE, 0xD1, 0xFC, 0x85, 0xF4, 0x0A }, + + .MarikoSupported = false, + + .EmcFreqOffsets = { 6, { 0xBE4E0, 0xD6DDC, 0xE2E5C, 0xEEEDC, 0xFAF5C, 0x106FDC } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0xB0CD8, 0xB0CDC } + }, + + /* 3.0.0 */ + { + .ModuleId = { 0x20, 0x8B, 0xB4, 0xD2, 0x82, 0x72, 0x31, 0xC2, 0x60, 0xA8, 0x90, 0x1E, 0xF3, 0x05, 0x05, 0x4D, 0x4B, 0x99, 0x49, 0x7D }, + + .MarikoSupported = false, + + .EmcFreqOffsets = { 8, { 0xCC2F0, 0xE4D7C, 0xF0DFC, 0xFCE7C, 0x108EFC, 0x114F7C, 0x120FFC, 0x12D07C } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0x12F5B0, 0x12F5B4 } + }, + + /* 3.0.1 to 3.0.2 */ + { + .ModuleId = { 0x7B, 0x00, 0xB6, 0xBF, 0x89, 0xAB, 0xBF, 0x0A, 0xCC, 0x43, 0xCC, 0x2C, 0x66, 0xE2, 0xB1, 0xC8, 0x57, 0x19, 0xFF, 0x96 }, + + .MarikoSupported = false, + + .EmcFreqOffsets = { 8, { 0xCC2F0, 0xE4D7C, 0xF0DFC, 0xFCE7C, 0x108EFC, 0x114F7C, 0x120FFC, 0x12D07C } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0x12F5B0, 0x12F5B4 } + }, + + /* 4.0.0 to 4.1.0 */ + { + .ModuleId = { 0x71, 0x11, 0x83, 0xE5, 0x61, 0x3A, 0x02, 0xC6, 0xB4, 0x0C, 0xE9, 0xBA, 0x62, 0xA4, 0x37, 0xD5, 0xAE, 0x7B, 0x3A, 0xCB }, + + .MarikoSupported = false, + + .EmcFreqOffsets = { 8, { 0xCD830, 0xE62CC, 0xF234C, 0xFE3CC, 0x10A44C, 0x1164C4, 0x12254C, 0x12E5CC } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0x130B90, 0x130B94 }, + }, + + /* 5.0.0 to 5.0.2 */ + { + .ModuleId = { 0x02, 0x5A, 0xFE, 0xC8, 0x23, 0x4F, 0x9D, 0x29, 0xA2, 0xB4, 0xE5, 0x9D, 0xB8, 0xC2, 0x42, 0x8F, 0x65, 0xE1, 0xAA, 0x96 }, + + .MarikoSupported = true, + + .EmcFreqOffsets = { 24, { 0xBE4A8, 0x105CB8, 0x10A8D8, 0x10A928, 0x10AE48, 0x10AE50, 0x10AE58, 0x10AE60, 0x10AE68, 0x10AE70, 0x10AE78, 0x10AE80, 0x10AE88, 0x10AE90, 0x121E70, 0x12DEF0, 0x1313C8, 0x13D1D4, 0x149254, 0x1552D4, 0x161354, 0x16D3D4, 0x1708AC, 0x173B10 } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0x1762C0, 0x1762C4 }, + + /* Mariko Specific */ + /* ... */ + + }, + + /* 5.1.0 */ + { + .ModuleId = { 0x0F, 0xBC, 0x5C, 0xF9, 0xE0, 0xC3, 0x3C, 0xFB, 0xA6, 0xA7, 0x94, 0xB3, 0xAC, 0x4A, 0x2C, 0x6B, 0x51, 0xE7, 0x59, 0x2C }, + + .MarikoSupported = true, + + .EmcFreqOffsets = { 24, { 0xBE538, 0x105CF8, 0x10A918, 0x10A968, 0x10AE88, 0x10AE90, 0x10AE98, 0x10AEA0, 0x10AEA8, 0x10AEB0, 0x10AEB8, 0x10AEC0, 0x10AEC8, 0x10AED0, 0x121EB0, 0x12DF30, 0x131408, 0x13D214, 0x149294, 0x155314, 0x161394, 0x16D414, 0x1708EC, 0x173B50 } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0x176300, 0x176304 }, + + /* Mariko Specific */ + /* ... */ + }, + + /* 6.0.0-4.0 */ + { + .ModuleId = { 0xFE, 0x9F, 0x29, 0x72, 0xD0, 0x62, 0xFE, 0x7B, 0x42, 0x84, 0xC5, 0x75, 0x6F, 0x8D, 0x1F, 0xEA, 0xA7, 0xCB, 0xB4, 0x23 }, + + .MarikoSupported = true, + + .EmcFreqOffsets = { 25, { 0xFE170, 0xFE178, 0xFE180, 0xFE188, 0xFE190, 0xFE198, 0xFE1A0, 0xFE1A8, 0xFE1B0, 0xFE1B8, 0x107CE0, 0x1154A0, 0x121520, 0x1249FC, 0x130804, 0x13C884, 0x148904, 0x154984, 0x160A04, 0x163EDC, 0x167140, 0x16A3A4, 0x176158, 0x17AE78, 0x17AEC8 } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0xE92E0, 0xE92E4 }, + + /* Mariko Specific */ + /* ... */ + }, + + /* 6.0.0-5.0 to 6.2.0 */ + { + .ModuleId = { 0xAB, 0x67, 0xDC, 0x8A, 0x73, 0x27, 0x3A, 0x11, 0x4B, 0x35, 0x25, 0xF4, 0xA8, 0xDD, 0x7B, 0xC9, 0xCA, 0xDC, 0x56, 0xC4 }, + + .MarikoSupported = true, + + .EmcFreqOffsets = { 25, { 0xFE170, 0xFE178, 0xFE180, 0xFE188, 0xFE190, 0xFE198, 0xFE1A0, 0xFE1A8, 0xFE1B0, 0xFE1B8, 0x107CE0, 0x1154A0, 0x121520, 0x1249FC, 0x130804, 0x13C884, 0x148904, 0x154984, 0x160A04, 0x163EDC, 0x167140, 0x16A3A4, 0x176158, 0x17AE78, 0x17AEC8 } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0xE92E0, 0xE92E4 }, + + /* Mariko Specific */ + /* ... */ + }, + + /* 7.0.0 to 7.0.1 */ + { + .ModuleId = { 0x2A, 0x32, 0x15, 0x69, 0xA7, 0x21, 0x4D, 0x8A, 0x49, 0x47, 0x7F, 0x8D, 0x70, 0xFC, 0xCC, 0xC0, 0xCF, 0xC0, 0x64, 0xBF }, + + .MarikoSupported = true, + + .EmcFreqOffsets = { 26, { 0x1001D0, 0x1001D8, 0x1001E0, 0x1001E8, 0x1001F0, 0x1001F8, 0x100200, 0x100208, 0x100210, 0x100218, 0x109D70, 0x1174F0, 0x123570, 0x125A4C, 0x132854, 0x13E8D4, 0x14A954, 0x1569D4, 0x162A54, 0x165F2C, 0x169190, 0x16C3F4, 0x16F654, 0x17B410, 0x180130, 0x180180 } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0xEB340, 0xEB344 }, + + /* Mariko Specific */ + /* ... */ + }, + + /* 8.0.0 to 8.1.1 */ + { + .ModuleId = { 0x00, 0xB8, 0x94, 0x35, 0x46, 0x39, 0x1A, 0x1F, 0x4E, 0x80, 0xAE, 0xB2, 0x10, 0x04, 0x9E, 0x37, 0xEB, 0x33, 0xBA, 0xF0 }, + + .MarikoSupported = true, + + .EmcFreqOffsets = { 27, { 0x11C9E0, 0x11C9E8, 0x11C9F0, 0x11C9F8, 0x11CA00, 0x11CA08, 0x11CA10, 0x11CA18, 0x11CA20, 0x11CA28, 0x126580, 0x133D20, 0x13FDA0, 0x143278, 0x14F084, 0x15B104, 0x167184, 0x173204, 0x17F284, 0x18275C, 0x1859C0, 0x188C24, 0x18BE88, 0x18F0EC, 0x19AEA0, 0x19FBC0, 0x19FC10 } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0x107978, 0x10797C }, + + /* Mariko Specific */ + /* ... */ + }, + + /* 9.0.0 to 9.2.0 */ + { + .ModuleId = { 0xEE, 0x33, 0xAE, 0x06, 0x45, 0x2B, 0x44, 0x56, 0x57, 0x8D, 0xFD, 0x1E, 0x9C, 0x45, 0xA7, 0xF9, 0x0C, 0xEF, 0x11, 0xA7 }, + + .MarikoSupported = true, + + .EmcFreqOffsets = { 28, { 0xD9A28, 0xD9A30, 0xD9A38, 0xD9A40, 0xD9A48, 0xD9A50, 0xD9A58, 0xD9A60, 0xD9A68, 0xD9A70, 0xE35C8, 0xF0D68, 0xF4240, 0x10004C, 0x10C0CC, 0x10F5A4, 0x112808, 0x115A6C, 0x118CD0, 0x11BF34, 0x11F198, 0x1223FC, 0x125660, 0x1288C4, 0x12BB28, 0x1378E0, 0x13C600, 0x13C650 } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0x13F1B0, 0x13F1B4 }, + + /* Mariko Specific */ + /* ... */ + }, + + /* 10.0.0 to 10.2.0 */ + { + .ModuleId = { 0x2F, 0x17, 0xB5, 0x04, 0x33, 0xCF, 0xB4, 0xF5, 0x7B, 0x47, 0xA9, 0x09, 0xEF, 0xE5, 0xD7, 0xDD, 0x10, 0x39, 0x4D, 0xC4 }, + + .MarikoSupported = true, + + .EmcFreqOffsets = { 28, { 0xD78D8, 0xD78E0, 0xD78E8, 0xD78F0, 0xD78F8, 0xD7900, 0xD7908, 0xD7910, 0xD7918, 0xD7920, 0xE1478, 0xEEC18, 0xF20F0, 0xFDEFC, 0x109F7C, 0x10D454, 0x1106B8, 0x11391C, 0x116B80, 0x119DE4, 0x11D048, 0x1202AC, 0x123510, 0x126774, 0x1299D8, 0x135790, 0x13A4B0, 0x13A500 } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0x13D128, 0x13D12C }, + + /* Mariko Specific */ + /* ... */ + }, + + /* 11.0.0 to 11.0.1 */ + { + .ModuleId = { 0x91, 0xD6, 0x1D, 0x59, 0xD7, 0x00, 0x23, 0x78, 0xE3, 0x55, 0x84, 0xFC, 0x0B, 0x38, 0xC7, 0x69, 0x3A, 0x3A, 0xBA, 0xB5 }, + + .MarikoSupported = true, + + .EmcFreqOffsets = { 30, { 0xD7C60, 0xD7C68, 0xD7C70, 0xD7C78, 0xD7C80, 0xD7C88, 0xD7C90, 0xD7C98, 0xD7CA0, 0xD7CA8, 0xE1800, 0xEEFA0, 0xF2478, 0xFE284, 0x10A304, 0x10D7DC, 0x110A40, 0x113CA4, 0x116F08, 0x11A16C, 0x11D3D0, 0x120634, 0x123898, 0x126AFC, 0x129D60, 0x12CFC4, 0x130228, 0x13BFE0, 0x140D00, 0x140D50 } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0x143998, 0x14399C }, + + /* Mariko Specific */ + /* ... */ + }, + + /* 12.0.0+ */ + { + .ModuleId = { 0xC5, 0x03, 0xE9, 0x65, 0x50, 0xF3, 0x02, 0xE1, 0x21, 0x87, 0x31, 0x36, 0xB8, 0x14, 0xA5, 0x29, 0x86, 0x3D, 0x94, 0x9B }, + + .MarikoSupported = true, + + .EmcFreqOffsets = { 30, { 0xE1810, 0xE6530, 0xE6580, 0xE6AB0, 0xE6AB8, 0xE6AC0, 0xE6AC8, 0xE6AD0, 0xE6AD8, 0xE6AE0, 0xE6AE8, 0xE6AF0, 0xE6AF8, 0xF0650, 0xFDDF0, 0x1012C8, 0x10D0D4, 0x119154, 0x11C62C, 0x11F890, 0x122AF4, 0x125D58, 0x128FBC, 0x12C220, 0x12F484, 0x1326E8, 0x13594C, 0x138BB0, 0x13BE14, 0x13F078 } }, + + /* Erista Specific */ + .EristaEmcVolatageOffsets = { 0x142878, 0x14287C }, + + /* Mariko Specific */ + /* ... */ + }, + + }; + + void ApplyPcvPatch(u8 *mapped_module, size_t mapped_size, u32 target_version); + +}  ¸§  ¸§ ”c !pcv_ram_oc.diff TPOÞb×