From bfa20ca5265dcd9ad9e6097b4aeeeeb5fc257d74 Mon Sep 17 00:00:00 2001 From: souldbminersmwc Date: Wed, 1 Oct 2025 19:10:21 -0400 Subject: [PATCH] configurator: update and modularize --- .gitignore | 4 +- .../loader/source/oc/customize.cpp | 17 +- .../loader/source/oc/customize.hpp | 8 +- .../loader/source/oc/mtc_timing_value.hpp | 4 +- Source/Configurator/deps.bat | 4 +- .../__pycache__/_4ifir_rant.cpython-313.pyc | Bin 2581 -> 0 bytes .../src/__pycache__/about.cpython-313.pyc | Bin 3419 -> 3439 bytes .../src/__pycache__/common.cpython-313.pyc | Bin 5093 -> 5113 bytes .../src/__pycache__/cpu.cpython-313.pyc | Bin 5910 -> 5909 bytes .../src/__pycache__/defaults.cpython-313.pyc | Bin 3569 -> 3589 bytes .../src/__pycache__/fan.cpython-313.pyc | Bin 371 -> 0 bytes .../src/__pycache__/gpu.cpython-313.pyc | Bin 9335 -> 10827 bytes .../src/__pycache__/ini.cpython-313.pyc | Bin 5044 -> 4205 bytes .../src/__pycache__/installer.cpython-313.pyc | Bin 9734 -> 9565 bytes .../src/__pycache__/kip.cpython-313.pyc | Bin 12402 -> 8080 bytes .../src/__pycache__/license.cpython-313.pyc | Bin 15995 -> 16015 bytes .../src/__pycache__/main.cpython-313.pyc | Bin 7504 -> 0 bytes .../src/__pycache__/misc.cpython-313.pyc | Bin 18399 -> 13882 bytes .../src/__pycache__/preset.cpython-313.pyc | Bin 6125 -> 5455 bytes .../src/__pycache__/ram.cpython-313.pyc | Bin 6289 -> 5876 bytes .../src/__pycache__/settings.cpython-313.pyc | Bin 0 -> 13870 bytes Source/Configurator/src/cpu.py | 20 +- Source/Configurator/src/defaults.py | 2 +- Source/Configurator/src/gpu.py | 107 ++-- Source/Configurator/src/ini.py | 23 - Source/Configurator/src/installer.py | 8 +- Source/Configurator/src/kip.py | 153 +---- Source/Configurator/src/misc.py | 182 +----- Source/Configurator/src/preset.py | 265 +------- Source/Configurator/src/ram.py | 24 +- Source/Configurator/src/settings.py | 603 ++++++++++++++++++ dist/README.md | 4 +- dist/atmosphere/kips/hoc.kip | Bin 270412 -> 270540 bytes 33 files changed, 738 insertions(+), 690 deletions(-) delete mode 100644 Source/Configurator/src/__pycache__/_4ifir_rant.cpython-313.pyc delete mode 100644 Source/Configurator/src/__pycache__/fan.cpython-313.pyc delete mode 100644 Source/Configurator/src/__pycache__/main.cpython-313.pyc create mode 100644 Source/Configurator/src/__pycache__/settings.cpython-313.pyc create mode 100644 Source/Configurator/src/settings.py diff --git a/.gitignore b/.gitignore index d8998056..b795ef9e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.DS_Store .vscode/ -build/ \ No newline at end of file +build/ +dist/ +.pyc \ No newline at end of file diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp index 43e015d5..701e66c9 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp @@ -83,9 +83,8 @@ volatile CustomizeTable C = { * Value should be divided evenly by 5'000 * Default: 600'000 * Not enabled by default. - * This will not work without sys-clk-OC. */ -.marikoEmcVddqVolt = 0, +.marikoEmcVddqVolt = 600000, .marikoCpuUV = 0, @@ -118,6 +117,13 @@ volatile CustomizeTable C = { .mem_burst_latency = 0, +.marikoCpuVmin = 600, + +.eristaGpuVmin = 810, + +.marikoGpuVmin = 610, + +.marikoGpuVmax = 800, // NOTE: These tables should NOT BE USED and are only here as placeholders. Always try and find your own optimal tables. // Ensure the voltages actually increase or stay the sameot @@ -167,13 +173,6 @@ volatile CustomizeTable C = { }, -.marikoCpuVmin = 600, - -.eristaGpuVmin = 810, - -.marikoGpuVmin = 610, - -.marikoGpuVmax = 800, /* Advanced Settings: * - Erista CPU DVFS Table: diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp index 5aae100e..e4583c5c 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp @@ -78,16 +78,16 @@ u32 t7_tWTR; u32 t8_tREFI; u32 mem_burst_latency; - - u32 marikoGpuVoltArray[24]; - u32 eristaGpuVoltArray[14]; - + u32 marikoCpuVmin; u32 eristaGpuVmin; u32 marikoGpuVmin; u32 marikoGpuVmax; + u32 marikoGpuVoltArray[24]; + u32 eristaGpuVoltArray[14]; + CustomizeCpuDvfsTable eristaCpuDvfsTable; CustomizeCpuDvfsTable marikoCpuDvfsTable; CustomizeCpuDvfsTable marikoCpuDvfsTableSLT; diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp index 472e01ac..17e10b6b 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/mtc_timing_value.hpp @@ -48,7 +48,7 @@ const std::array tWTR_values = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // Preset Six - const std::array tREFpb_values = {488, 976, 1952, 3256, 9999, 9999}; + const std::array tREFpb_values = {488, 976, 1952, 3256, 6512, 9999}; // const u32 TIMING_PRESET_ONE = C.ramTimingPresetOne; // const u32 TIMING_PRESET_TWO = C.ramTimingPresetTwo; @@ -64,7 +64,7 @@ // Write Latency const u32 WL = 14 + C.mem_burst_latency; // Read Latency - const u32 RL = 32 - C.mem_burst_latency; + const u32 RL = 32 + C.mem_burst_latency; // tRFCpb (refresh cycle time per bank) in ns for 8Gb density const u32 tRFCpb = !C.t5_tRFC ? 140 : tRFC_values[C.t5_tRFC-1]; diff --git a/Source/Configurator/deps.bat b/Source/Configurator/deps.bat index c264d6a2..c1ea927a 100644 --- a/Source/Configurator/deps.bat +++ b/Source/Configurator/deps.bat @@ -1,5 +1,5 @@ -pip install -U pyinstaller -pip install dpg +pip install pyinstaller +pip install dearpygui pip install numpy pip install psutil pip install pil diff --git a/Source/Configurator/src/__pycache__/_4ifir_rant.cpython-313.pyc b/Source/Configurator/src/__pycache__/_4ifir_rant.cpython-313.pyc deleted file mode 100644 index a50b934b6fb9163e6f54a8566b9b8291b3a742f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2581 zcmZuz%WfMt6qS;oj|qYl1-ido6p4UDKpv|!DBxI5Y&3}r%Z4`s0%}NU2y@6O$S_0e9I|cLDMPJ(tu-N>IU%5g(WLo^$Tue7JL`7~u0K{Z+*;2ZMk3OaHmC zdHC=Z9)2H82h-t?13#SJ@Hdvj(anE(`mOjL+lu0{5|MPErzbB@&gj0dl47N(t8`Qp z^-_6qP1Mekwsh>g{uPg>ha=*ZUA3mQYbjK&HIl^2X-PU3MRAT8mnp`1igB7_+|S44 zh@+1~au&{-HPuSkNDJpl$d$0AlGFy}LppMLe0uSELT^vc>BSLUOphkxqBuzCic&{F4bHgO*AJS_!XR8~T*ecrC7wokr1ip)l zU8F^845_-c3`ps`Z?ne0bXbQ^NADvM1a1Rp?B_@09XTu`fuxo2J=-Manc{>M#GY7= z%9z{$+%<_t<dU= zjTvjJ`^ue--fd9LP7x@y&<#>Le0iBpn{GHw&CPzwN|-yx4UW#q7_uvd)HOV7*oRVg zq;*?IYAtfj%Tjao#3e7=YxkZ=VS?++2~-OUHhUmasho~Ocw`dhcdf7n}`yeFzmQM0}RxTUwr<9;ncA+G0>9B!wOGsi^`wV#x<(P`%$%u}H_izUGyu_73A8`4l z=M#!z>)2U?FdqnX%_}%~Ud1wm&xZs-K57fHwxww$lmt6v=V}l?gB&#@(ugj}7}c;@ zK{e^l>0mklFlspSdzTezZf!!ppan5R>Dp0}v^iu#%S0A+X&SY4Iy)Vx z5;79n8xKs@CZr9CH`sVUsC|T&0a7K9SQMm4M!fN|2M|*K0j`r6XKmJIy^_y8K0f#N zJLl)?k9)&+hq*nc(~ijaXy?zB>--(A3s2oSJM6?j&D%sf&;cYmzPtJOF+AqyR7_OkhsYgvK&T6BBDf`$6>Mpw{Av!$ z`}u|ltzb%-8k}{?jsuiTgHY?s-5@jz^bzaqiT&&PH9;(gRO$fskV?TB!L^F5DeEyR zwvmbtUuRT2-Q22Opj+wMv^8ows(uS~OZxc7eA2>c1wW@J!I5$tqYsvp!|60hvO)Hb zQwTc1HHky0DbItH`xduMuDR1beMOSjJ!1wBc)-5!9s$@x0NcPzVd#ZW9qVnao@9?vmF_|K09b2fPwC1kpIL(K z$a%UUXJ31Arda5QGjR5Z-p|!KmyLbU^4_G(V1fY{YzyotEE~Z(4;PxT-qhtYW~f(Y zfVGx!=tX55ZpavEPsUacEP3Zff!qHMgqJ`bfzjr+jBa%AKvym0eh%qaOVV+e&^cwY zCtE!+H7WDttsEkUfR=TSK8`o=a(s&k#pbp|?L+o7ry1?Tq*~unezQmErxpPNOBe>lcM`p_-vz6dn#ecc%zP$VH?xnIjsr=%N^*y**?Hw!kj_qWt6Z7SX z`Q2=JBJulTvbwljUR delta 1991 zcmbVNT}&KR6h1S1XLfgn{hyr$mY-c(3yX!trC9!p4~>|x(sHuIxWk>_j4;mq38`4Il{xno$gTW{<`k?i}XiOmc(rkS2L1Q$H(V~fu-eG5}z(P%LGWUMx z&N=7%&dixR=UUIVy4PJU3D`K(aD8$%H0Q455_65Mf~^{K=ZBBK%;!E60nR}jkUPq0 z=E}2`OK|}h<+FSovU~sr?EupaZa`Z*e}qpu0c41PX4CjIXC^mC+E!cvkf4BKhh=wI z9vVpzmQ%Qu)5~(EFh{x{0vO|2n0;74M@nEc&UPE4@mn;aCLoD(WvL{Tw^Ow+C7L~D z-$duxp!+WyF}ZS#%&f_0kvTNsHh~qx8-ZKmoV$p0p}V|D^u%-AhFU2l{U5bkNM$B= z_qg(6D>R|>G$%K`IWPLQE7e>n*Byv+GZIqji4oEGT?jh;80g|6kS4}+LXFq}sH7$1 zVWBo0L={6=iB(wLWj7se1-i{ZIgB-N9>Z9h_8M-nM!`C)?-F)#jFcRsWgV5ylnonj zPnvaMaf~P>^zVv$w*?pLxNE06_E~i_maRjPQf_R*7&aHx`SI>DMKCW1+HpU&+{R00 zUac74$*U-}Z6~SsSW*+^r6x)pvZ+A`w&Q`VpEh>jy?AgZ8RiRAcFNXSHd_~V7qjJx z4=BSqJ zZ&^DpzHNb#cPvo%t_6NAfsZc_7{k(_gZ{}5Y5F<8d_j^qPBt#f@5?e{*4d#6y0ZL8 z#q(THHF3zCHg1`pi|$!ocXjgoFPzcjebg-%$P~?GA(SrlbDa@|y6#K2rz)hYg z;>^%Zi3G)&o?vEBrE2#3->P`%~!?qO53tmQF*T4Xi_81uegVL$S0vB zkS|)*q(Huu)TBhN5jE){*CJ|CAz%5`WEF`?hORc>*T_`r&1@>zo}?#r^K>uRGOTni vqYp6S3aqmk^h0baIC@V^KXH0$qF;Z2ndYA|TW8!*!}2_Ue8#?xsmS@C!^!!hnxy*`N_pby2+cRxn3~?01bT&1^@s6 diff --git a/Source/Configurator/src/__pycache__/fan.cpython-313.pyc b/Source/Configurator/src/__pycache__/fan.cpython-313.pyc deleted file mode 100644 index 3f07466d180521199b82b3fa4037d725ca58ec94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 371 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 LVF58nBnkfu4tU>w delta 2944 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 LaNc+G*@>w)5;Z@X diff --git a/Source/Configurator/src/__pycache__/kip.cpython-313.pyc b/Source/Configurator/src/__pycache__/kip.cpython-313.pyc index 0e1124c5c963d183911ef46e98194aa4dd10d597..75478c8948144559382ca771c636b3df523cea0b 100644 GIT binary patch delta 2488 zcmZuzX>3$g6ux)fEUz>3rpqi{r}L(r=`1Y;M2uLZsYqK=0qr<$BMigzwM;rpr}s_S zL}>gY5RBkO#U%j}B0n_7*hqpu`~!l~xJ4w*Ye_IJ2|rAo8nNBL#WqH$Mu*b0v;%yNPy{IR!vL?67|qc* zagzQpAro+bd~2L0poj23E9&{UrM|M2kT{JAOC&;abVHQCVQDlPG^+BCEXUg`VI*`A zbv3{wnYK!kYiFEIhb#w;)1vLj_{)0^?Kx3>Xy3PDBhQNg{+9FIHqAK9lyMagB{K)0 zCZQr(7)xeT+mtNxfUcI0x}IpPf?B$CEl|I8`n`PCHE1)V4rNf}rz>3C9u;}FyJf_r zNu!y3ayXM!lKE6&yJpI>Os=4bOi2wTp^J$yNt3c;&`f2s$(<>tMhu!+RdPcL)5KIh zpBzdRQYvmPFC5dP7RH#uWKj8_s2%*gJ7hJzxaoyW-y7YmYU*eAAC%VcncDq=M$>#t zorgB^iMoKf8HO_-KUo)|4t}}LYh4A3He6$hf8FGnGS+*918~uV1rUM&5hud|EQA2g zAq>5ySu<)TrxsGVw8A2&Ffc_E)QN3uDUMl&(2mf7umqtKVL3u0!aWEp5bi}-380z) zEHVmn@Ka4eQ#UB?o%+1#98EcKR2Ks9l|;;%btI|#OD(WlTWJ=i!7usn|;sse+3;nFG-@z+eDcIgUH`SvT|Wu zjwTip;tQW-(*q8tq?dE0LFR(&wjr@}8LR=~xcU8ZRnT41CCW2mrj-jj8%WL=HxAbF zH6b6Z=P$|a{0yu$EeF8Gf6HwhcRLt_RqsMry_xWqm$&mSzn}W}X1}-IU(&{HWixDX zaj=zhf8;iP2XubV_^WAz{|d9)d1cE|zP-WA6D^W{l!GlUFEU0K3rPV1a#CWkp`GKE|gq|pTE_T-TdJUhN zTA+T(YwdHIE`=KU9Hz_E2%5_d6KF0w1+06leF4k=(jXd!#>_MRWt%s8H}94GVOUJ7 zXxvcl6cRRAMwd8=85Z$H()m)!w}gs(>8Oy5adX1WKMn<{nIEog=Kq8wUwvtbyAz#z z!odgzuP%wEQthetR-z3cGT8wBvB5Xt<3r(=`|f5C(DC>J9pArgBUxWT2Yx)f{x;GT zlj_ZIqaP`w%dO4h){?C`J8XJ?q@4!A+6KNq;;VSAe3*A4L0g%YgJFy|!JUY5Iob^A z+Id@FryhyjQTrXb(K~gubtMmg$+y-ou5lr{!rBMNh2*%6^}o`7*l@$hkF;~8Zh_Fy z#|97{LD+z>5n&U;qXk`?Cu>u``qd0KIpyL+V!p7cWC3mr%$Y%wL6dZ9Nlx(-uAmd0;_)#rEeU8 zD`IfEy5^vHw%K=b^zBg`IqP)2zUtVj6OSER&FeZ((I`LPIpX+aov%MEd=|F$-)D)` z^3J9H19;o|#cAS@GMt*o7S!U~WKNIm*a2xD?@kj&@)InNLm$MZ2qqOWxe--=d07v3 z=otkAQGfCEca`D8$nf=H_#zaOg>JqJo0!eUivJAa>K$W46Io>qdjXViB}7F({w7dL zuMz(Yk**QX45^tRl{2JbhPbXv)sxogD%YemXExKyIhUD+=c-K9Gv}~V*IbhmAZmeT PjZC}dAEq*G*7y4l28Z|m literal 12402 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 S`fj<8`P{ujjE~tyhxGqQe4}pw diff --git a/Source/Configurator/src/__pycache__/license.cpython-313.pyc b/Source/Configurator/src/__pycache__/license.cpython-313.pyc index c77584916372cacb4cbe216cb6b8e48a1143d451..bccbf4d747f3ff39646d3d2a764edbc168f6c4e7 100644 GIT binary patch delta 44 zcmexe(_g!R+m110GLM~tRB(A_Npgm+zq77yVqS4(eqKy)erZv1YK-$_BRfw3ZA}l< delta 24 fcmeCL{av$x+m6v;GLM}CTYhq}k#6#2H#<)NaZ3m& diff --git a/Source/Configurator/src/__pycache__/main.cpython-313.pyc b/Source/Configurator/src/__pycache__/main.cpython-313.pyc deleted file mode 100644 index 46dd1ff39a5ff35e39cac0d73b95e6c0a779d346..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7504 zcmcIoeM}o^dLMgiY{oVQgCP(|CSQC6upxm2vPt#~mk&Z9kp~vo8_7F(#%31VW4$wm z#kU`HRdpkDy=0?a!&awTR8U^FCwv#^s_2cy*un^@80)5Wm9%{iS(e@Xc?W1o0Ds zArQfs81uO4mKl*W!ID9{9%{&w#9(Kn_hhkyDc{ zRHI2Za%-{{)oQX1)q%8(dv4XE`Z87n@@l?D)W}#-6H|qbu+1k4*1_1AszI_uqO;6} z>mUf$85}Tp>RRxkt{IYb1c!`~t}*sOb4f>ScLx6#Xa}!*MaMNHdwkGT8Zp(zT5KCb z^@17EY*lc?h}JdOGp)}HUem3HWE{E|onlV~ZyFw5OToU-8Pv|&gOj?=kbr+mM_`=2 z4v6h!JA;f7p=){>Y0XNi-vP>R1e$B`WWvkqWal$?0Kf~6;T)1 zi|i27REj!aCm-tU45{s;iaEkGGcAmjtqHCgK3!vu4%^B*{aCjd5)fMTlY@@>?fm_* z5vyx3r;RxVD;{U)VM`hNPjs&#zjcoH440`he|E4K!V=pdLKS53_!z#~QLS>tHT@ui(

lj7&P&yag- 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 X4rBdm6E#;`{j~!le_c<_owWTA=WWYU diff --git a/Source/Configurator/src/__pycache__/misc.cpython-313.pyc b/Source/Configurator/src/__pycache__/misc.cpython-313.pyc index 23b64b11cde5915a3698f09338a90a2a018fff07..be0a4ea8377e20c94d9fa7f9cbfb007d894cdbd6 100644 GIT binary patch delta 3497 zcmaJ@3v64}8NSE9H-02`?D&y~?Zl4LBu>*Nahg|S=g~GzOOv$Ct|L1)8Jb5!wf6HLdbJ(6b_rc_gUXJ^S4f0L3(z$hlJ6``#HxX4k zOw=q26&x)Q3y@kw4N|M9MQRguNbRB?X{lIav3ooKCP;duEjQdCbk?j#pdrPLuc^wm}ByKy3F;<&H?#8D4J zf>j?<3n-A{!y0IHc=N~~aCp9k{CS6w2=F^ccR?LWPzPw8!5$rT;UKHsHM(=__MrhW zD@@TidcuIERgAb9xd+t(>S42Xc*0qGv>LlI3k0{)a#&g!mJIB1nodThXnH)JkZ3P* zjWYJfkj!#dEza4Ys~XFxmX|lauyIMV=9<jQ-$l)S+e>}A(N++a@J4hMAK5Y(L{pt$s z#`$l;Hfv-|kxV`ceCid18NUKBGl%%*&@GvcPQ{`bDUy>?tkTWMF@~SqhlGLac)I`T zp=-SEnf0eUFE_r>c$u%ead!;gVDQ=h$lFiI^PO(03svxz`zX9`x2Q%9@B@1VL_CJC1X$Ezg<~EY{H+u-zZ5Qb23NZl2vm1|1GgDo zt*$F)k#pEQl6J>vd`5E1QbO97kz!N>H>&R|Ez0Gx4w;mMrVIz_f3GO5tbbMxFN<#i50}pOaNh_*uAZ8jeeI;s!|hT%;24bZSCGYzw>d zVq&}4A$FpB+-hQsD#nB^W(>w^y~4)4Q?_m~AhvX=zRqpQyOvkXjaD<4Z9%c8i>NR? z?$TewR$RT|+B~ypzDH+002$n!olBL*P*Cm!)GJ~ zg>9|=Rcq)pl`zflBK|)rUgcn_Z9A%nwI3r#;2-TyQUZpKx`x9hfAfaUWWT$9i!>g^ z?fZNJy^p!KdOl-p_z>*w_`r08b+K%%kR#C3xo+}F9Q$l^2mWOZ(O4`ZOH)xA&7^5o z&xU)aGZ`!t?0(7`mGwlN9UZ$0*#$}a8DSMxxu2C2$(rQJ^Z{fUPe%^KQ+RT87yO~K z!d}U==$Mv$>EzzD@{piS@ZZjk5u38a-WV9ANtv>$Lmy}4Fe3*UnL#3B{$jcBV=Y(m zwNvS-=>*n%dIFaixBMhL)s+@Xf0Q_$Sh&?yLZGHQSbn2s&1=JFhL=qKGsE+b&b6N? ze`R=f`=ZGYGui;}!(5KvcskJvMkTP=QzL8-Y3t zzwtZBg(oCxck&^@$cZ}mEYPCUhYG|(Ru53J0h)q!La}HPjf(VCkVzj4-YspuBmGve z#ZeN{=cK>I6N_jSZA_O?e#bkFXjkT}AorNnd7n#HI7{!$l!@gzK9yJjpZ2)!+JXa} zP~#Sy;OJfRjq_q}i_R4?u59hgfJa{$GUP@R@NRD{T<oax)I=&tdPvcWqG8-$I^(E&UIdDKT!` zmrjkxC#I>S1e&iH-)e96*AYMbrT?cbO6DI&b(E1`;3xkZ&wZBrr=GKxof789PmjMI zTPkZ^vTT?g`nanfe!eMIdZW~FYT$I;>)q#tC1=l4Y40L$y}tW_1<&T~WUz`WUVA%h z9lgD*=Pdr)*|IR}Iros;+47yT7ft-qI9SeKD6tP#^1tae4tn{E#rDB^{;iGn!FBv^ z?e;-G@2h}wTLNyjgIvv1ZuoUL%<5KZAwJ|M!7xxZwua4Wv3O_VsR=okq{^d}*~%p; z%jR6pvI}0x8)d_kUD}jA?p9JOkW9y>6H*U-1Ls%*$PaMv+<>p+Pn>m`=gBZxHfqQ= nvRqP0dY3nmBGS3+)RLZMYcbiOT6Xsl(s65xs+0^8MeY9p%KAjP delta 7924 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 H$L{|F1V2Nw diff --git a/Source/Configurator/src/__pycache__/preset.cpython-313.pyc b/Source/Configurator/src/__pycache__/preset.cpython-313.pyc index b8b44a6903286936f7f774979087250d350075fe..0e5e311008f843776c390c77fbc9a417e07fdf4a 100644 GIT binary patch delta 2044 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 literal 0 HcmV?d00001 diff --git a/Source/Configurator/src/cpu.py b/Source/Configurator/src/cpu.py index fabe0998..30376603 100644 --- a/Source/Configurator/src/cpu.py +++ b/Source/Configurator/src/cpu.py @@ -24,28 +24,20 @@ import dearpygui.dearpygui as dpg import common import kip as k import gpu as g +import settings as s def populate(): - freqs_hz_cpu = [ - 1020000, 1122000, 1224000, 1326000, 1428000, 1581000, 1683000, - 1785000, 1887000, 1963500, 2091000, 2193000, 2295000, 2397000, - 2499000, 2601000, 2703000, 2805000, 2907000 - ] - freqs_mhz_cpu = [ - 1020.0, 1122.0, 1224.0, 1326.0, 1428.0, 1581.0, 1683.0, - 1785.0, 1887.0, 1963.5, 2091.0, 2193.0, 2295.0, 2397.0, - 2499.0, 2601.0, 2703.0, 2805.0, 2907.0 - ] - freqs_mhz_cpu_label = [f"{f} MHz" for f in freqs_mhz_cpu] + + freqs_mhz_cpu_label = [f"{f} MHz" for f in s.freqs_mhz_cpu] offsets = list(range(0, 101, 5)) processed_offsets = ["Disabled" if v == 0 else f"-{v}mV" for v in offsets] - voltages = [0] + list(range(1000, 1160 + 1, 5)) # 0 first for Disabled + voltages = [0] + list(range(1000, 1160 + 1, s.mariko_voltage_step)) # 0 first for Disabled processed_voltages = ["Disabled" if v == 0 else f"{v}mV" for v in voltages] processed_voltages_default = ["Default" if v == 0 else f"{v}mV" for v in voltages] - voltages_e = [0] + list(range(1120, 1255 + 1, 5)) + [1257] # 0 first for Disabled + voltages_e = [0] + list(range(1120, 1255 + 1, s.mariko_voltage_step)) + [1257] # 0 first for Disabled processed_voltages_e = ["Disabled" if v == 0 else f"{v}mV" for v in voltages_e] processed_voltages_default_e = ["Default" if v == 0 else f"{v}mV" for v in voltages_e] - vmin_voltages = list(range(500, 700 + 1, 5)) # 0 first for Disabled + vmin_voltages = list(range(s.mariko_cpu_min_vmin, s.mariko_cpu_max_vmin + 1, s.mariko_voltage_step)) # 0 first for Disabled vmin_processed_voltages = ["Disabled" if v == 0 else f"{v}mV" for v in vmin_voltages] dpg.add_separator(label="Frequencies") diff --git a/Source/Configurator/src/defaults.py b/Source/Configurator/src/defaults.py index 2fba1969..33d683b3 100644 --- a/Source/Configurator/src/defaults.py +++ b/Source/Configurator/src/defaults.py @@ -20,7 +20,7 @@ along with this program. If not, see . """ -class Defaults: +class Defaults: # This almost always never needs to be updated as pulling from the kip takes priority def __init__(self): self.autosave = 0 self.custrev = 0 diff --git a/Source/Configurator/src/gpu.py b/Source/Configurator/src/gpu.py index 3f84b679..43ce1d16 100644 --- a/Source/Configurator/src/gpu.py +++ b/Source/Configurator/src/gpu.py @@ -25,6 +25,7 @@ import kip as k import common from pathlib import Path import ini +import settings as s def unimplemented(): pass @@ -58,33 +59,19 @@ def toggle_gpu_sched(sender, app_data): common.show_popup("Success", f"Set GPU Scheduling to {app_data}") def populate(): - offsets = list(range(0, 51, 5)) + offsets = list(range(0, s.mariko_gpu_offset_max + 1, s.mariko_voltage_step)) processed_offsets = ["Disabled" if v == 0 else f"-{v} mV" for v in offsets] - voltages = [0] + list(range(480, 960 + 1, 5)) # 0 first for Disabled + voltages = [0] + list(range(s.mariko_gpu_min_volt, s.mariko_gpu_max_volt + 1, s.mariko_voltage_step)) # 0 first for Disabled processed_voltages = ["Disabled" if v == 0 else f"{v} mV" for v in voltages] - voltages_e = [0] + list(range(700, 1100 + 1, 5)) # 0 first for Disabled + voltages_e = [0] + list(range(s.erista_gpu_min_volt, s.erista_gpu_max_volt + 1, s.mariko_voltage_step)) # 0 first for Disabled processed_voltages_e = ["Disabled" if v == 0 else f"{v} mV" for v in voltages_e] processed_voltages_default = ["Default" if v == 0 else f"{v} mV" for v in voltages] - voltages_vmin = [0] + list(range(480, 650 + 1, 5)) # 0 first for Disabled + voltages_vmin = [0] + list(range(s.mariko_gpu_min_volt, s.mariko_gpu_max_vmin + 1, s.mariko_voltage_step)) # 0 first for Disabled processed_voltages_vmin = ["Disabled" if v == 0 else f"{v} mV" for v in voltages_vmin] - voltages_vmin_e = [0] + list(range(700, 850 + 1, 5)) # 0 first for Disabled + voltages_vmin_e = [0] + list(range(s.erista_gpu_min_volt, s.erista_gpu_max_vmin + 1, s.mariko_voltage_step)) # 0 first for Disabled processed_voltages_vmin_e = ["Disabled" if v == 0 else f"{v} mV" for v in voltages_vmin_e] - freqs_khz = [ - 76800, 153600, 230400, 307200, 384000, 460800, 537600, 614400, 691200, 768000, - 844800, 921600, 998400, 1075200, 1152000, 1228800, 1267200, 1305600, 1344000, 1382400, 1420800, - 1459200, 1497600, 1536000 - ] - freqs_khz_e = [ - 76800, 153600, 230400, 307200, 384000, 460800, 537600, 614400, 691200, 768000, - 844800, 921600, 998400, 1075200 #, 1152000, 1228800 # Disabled by default as these freqs can cause board damage - ] - freqs_mhz = [ - 76.8, 153.6, 230.4, 307.2, 384.0, 460.8, 537.6, 614.4, 691.2, 768.0, - 844.8, 921.6, 998.4, 1075.2, 1152.0, 1228.8, 1267.2, 1305.6, 1344.0, 1382.4, - 1420.8, 1459.2, 1497.6, 1536.0 - ] - freqs_mhz_label = [f"{f} MHz" for f in freqs_mhz] + freqs_mhz_label = [f"{f} MHz" for f in s.freqs_mhz] dpg.add_separator(label="Frequencies") @@ -182,51 +169,67 @@ def populate(): dpg.add_separator(label="Custom Table (Mariko)") - for freq in freqs_khz: - if(freq > 1535000): + for freq in s.freqs_khz: + if(freq > s.mariko_meme_threshold): + mhz_color = s.danger_color mhz_label = f"{freq / 1000:.1f} MHz" - elif(freq > 1382400): - mhz_label = f"{freq / 1000:.1f} MHz (DANGEROUS)" - elif(freq > 1152000): - mhz_label = f"{freq / 1000:.1f} MHz (UNSAFE)" + safety_label = "" + elif(freq > s.mariko_dangerous_gpu_threshold): + mhz_color = s.danger_color + mhz_label = f"{freq / 1000:.1f} MHz" + safety_label = "(DANGEROUS)" + elif(freq > s.mariko_unsafe_gpu_threshold): + mhz_color = s.unsafe_color + mhz_label = f"{freq / 1000:.1f} MHz" + safety_label = "(UNSAFE)" else: mhz_label = f"{freq / 1000:.1f} MHz" + safety_label = "" + mhz_color = s.safe_color + mhz_tag = f"combo_{freq}" - if freq == 1536000: + if freq == s.mariko_meme_threshold: with dpg.group(horizontal=True): # align horizontally dpg.add_combo( items=processed_voltages, default_value="Disabled", - label=mhz_label, tag="g_volt_" + str(freq), callback=k.grab_kip_storage_values_no_mult ) - dpg.add_text("(") - dpg.add_image("coolerhd", width=16, height=16) - dpg.add_text(")") + dpg.add_text(f"{mhz_label} (", color=mhz_color) + dpg.add_image("coolerhd", width=20, height=20) + dpg.add_text(")", color=mhz_color) else: - dpg.add_combo( - items=processed_voltages, - default_value="Disabled", - label=mhz_label, - tag="g_volt_" + str(freq), - callback=k.grab_kip_storage_values_no_mult - ) + with dpg.group(horizontal=True): + dpg.add_combo( + items=processed_voltages, + default_value="Disabled", + tag="g_volt_" + str(freq), + callback=k.grab_kip_storage_values_no_mult + ) + dpg.add_text(default_value=f"{mhz_label} {safety_label}", color=mhz_color) dpg.add_separator(label="Custom Table (Erista)") - for freq in freqs_khz_e: - if(freq > 1151000): - mhz_label = f"{freq / 1000:.1f} MHz (DANGEROUS)" - elif(freq > 922000): - mhz_label = f"{freq / 1000:.1f} MHz (UNSAFE)" - else: + for freq in s.freqs_khz_e: + if(freq > s.erista_dangerous_gpu_threshold): mhz_label = f"{freq / 1000:.1f} MHz" - mhz_tag = f"combo_e_{freq}" - dpg.add_combo( - items=processed_voltages_e, - default_value="Disabled", - label=mhz_label, - tag="g_volt_e_" + str(freq), - callback=k.grab_kip_storage_values_no_mult - ) \ No newline at end of file + safety_label = "(DANGEROUS)" + mhz_color = s.danger_color + elif(freq > s.erista_unsafe_gpu_threshold): + mhz_color = s.unsafe_color + mhz_label = f"{freq / 1000:.1f} MHz" + safety_label = "(UNSAFE)" + else: + mhz_color = s.safe_color + mhz_label = f"{freq / 1000:.1f} MHz" + safety_label = "" + + with dpg.group(horizontal=True): + dpg.add_combo( + items=processed_voltages_e, + default_value="Disabled", + tag="g_volt_e_" + str(freq), + callback=k.grab_kip_storage_values_no_mult + ) + dpg.add_text(default_value=f"{mhz_label} {safety_label}", color=mhz_color) diff --git a/Source/Configurator/src/ini.py b/Source/Configurator/src/ini.py index 6f592a13..e51b364e 100644 --- a/Source/Configurator/src/ini.py +++ b/Source/Configurator/src/ini.py @@ -2,30 +2,7 @@ import os import re import common as c -def ensure_dir_exists(path): - path_str = str(path) - os.makedirs(os.path.dirname(path_str), exist_ok=True) - -import os -import re -import common as c - -def ensure_dir_exists(path): - os.makedirs(os.path.dirname(path), exist_ok=True) - -import os -import re -import common as c - def ensure_dir_exists(path: str): - """Ensure the parent directory of the INI file exists.""" - os.makedirs(os.path.dirname(path), exist_ok=True) - -import os -import re -import common as c - -def ensure_dir_exists(path): os.makedirs(os.path.dirname(path), exist_ok=True) def set_ini_values(ini_path, section, entries): diff --git a/Source/Configurator/src/installer.py b/Source/Configurator/src/installer.py index 72b42f93..48ac04e9 100644 --- a/Source/Configurator/src/installer.py +++ b/Source/Configurator/src/installer.py @@ -28,6 +28,7 @@ import urllib.request import zipfile import kip as k from defaults import d +import settings as s def autosave_toggle(sender, app_data): d.autosave=app_data @@ -42,9 +43,6 @@ def get_drives(): # Change if you plan to fork -kip_download_link="https://github.com/souldbminersmwc/Horizon-OC/releases/latest/download/loader.kip" -hoc_clk_download_link="https://github.com/souldbminersmwc/Horizon-OC/releases/latest/download/hoc-clk.zip" -ams_download_link="" def download_and_extract_zip(c, download_url, zip_filename="temp.zip", success_message="Installed file!"): """ @@ -92,7 +90,7 @@ def downloadLoader(): # This has to be different as it extracts to a custom loca else: try: directory_make = c.drive + "atmosphere/kips/" - urllib.request.urlretrieve(kip_download_link, directory_make + "hoc.kip") + urllib.request.urlretrieve(s.kip_download_link, directory_make + "hoc.kip") except Exception as e: c.show_popup(title="Error", content=f"Download failed:\n{e}") finally: @@ -109,7 +107,7 @@ def check_atmosphere(sender, app_data, user_data): k.kip_file_path = f"{atmosphere_path}/kips/hoc.kip" k.read_kip(c.drive + "atmosphere/kips/hoc.kip") print(f"Reading kip from drive {c.drive}") - k.load_all_vars() + s.load_all_vars() elif os.path.isdir(atmosphere_path) and os.path.isfile(package3_path): dpg.set_value("status_text", "Atmosphere install found!") else: diff --git a/Source/Configurator/src/kip.py b/Source/Configurator/src/kip.py index ca766238..a34580c4 100644 --- a/Source/Configurator/src/kip.py +++ b/Source/Configurator/src/kip.py @@ -3,157 +3,22 @@ import struct from defaults import d import common as c import gpu as g -import cpu -import defaults as df import re -import ctypes +import settings as s g_freq_str = None kip_file_path = None -variables = [ - ("custRev", "u32"), - ("mtcConf", "u32"), - ("commonCpuBoostClock", "u32"), - ("commonEmcMemVolt", "u32"), - ("eristaCpuMaxVolt", "u32"), - ("eristaEmcMaxClock", "u32"), - ("marikoCpuMaxVolt", "u32"), - ("marikoEmcMaxClock", "u32"), - ("marikoEmcVddqVolt", "u32"), - ("marikoCpuUV", "u32"), - ("marikoGpuUV", "u32"), - ("eristaCpuUV", "u32"), - ("eristaGpuUV", "u32"), - ("enableMarikoGpuUnsafeFreqs", "u32"), - ("enableEristaGpuUnsafeFreqs", "u32"), - ("enableMarikoCpuUnsafeFreqs", "u32"), - ("enableEristaCpuUnsafeFreqs", "u32"), - ("commonGpuVoltOffset", "u32"), - ("marikoEmcDvbShift", "u32"), - # advanced config - ("t1_tRCD", "u32"), - ("t2_tRP", "u32"), - ("t3_tRAS", "u32"), - ("t4_tRRD", "u32"), - ("t5_tRFC", "u32"), - ("t6_tRTW", "u32"), - ("t7_tWTR", "u32"), - ("t8_tREFI", "u32"), - ("mem_burst_latency", "u32"), - - ("g_volt_76800", "u32"), - ("g_volt_153600", "u32"), - ("g_volt_230400", "u32"), - ("g_volt_307200", "u32"), - ("g_volt_384000", "u32"), - ("g_volt_460800", "u32"), - ("g_volt_537600", "u32"), - ("g_volt_614400", "u32"), - ("g_volt_691200", "u32"), - ("g_volt_768000", "u32"), - ("g_volt_844800", "u32"), - ("g_volt_921600", "u32"), - ("g_volt_998400", "u32"), - ("g_volt_1075200", "u32"), - ("g_volt_1152000", "u32"), - ("g_volt_1228800", "u32"), - ("g_volt_1267200", "u32"), - ("g_volt_1305600", "u32"), - ("g_volt_1344000", "u32"), - ("g_volt_1382400", "u32"), - ("g_volt_1420800", "u32"), - ("g_volt_1459200", "u32"), - ("g_volt_1497600", "u32"), - ("g_volt_1536000", "u32"), - - - ("g_volt_e_76800", "u32"), - ("g_volt_e_153600", "u32"), - ("g_volt_e_230400", "u32"), - ("g_volt_e_307200", "u32"), - ("g_volt_e_384000", "u32"), - ("g_volt_e_460800", "u32"), - ("g_volt_e_537600", "u32"), - ("g_volt_e_614400", "u32"), - ("g_volt_e_691200", "u32"), - ("g_volt_e_768000", "u32"), - ("g_volt_e_844800", "u32"), - ("g_volt_e_921600", "u32"), - ("g_volt_e_998400", "u32"), - ("g_volt_e_1075200", "u32"), -# ("g_volt_e_1152000", "u32"), -# ("g_volt_e_1228800", "u32"), - ("marikoCpuVmin", "u32"), - ("eristaGpuVmin", "u32"), - ("marikoGpuVmin", "u32"), - ("marikoGpuVmax", "u32"), - -] - -fmt_map = { - "u32": "I", - "double": "d", -} def make_struct_format(vars_list): fmt = "=" for name, t in vars_list: - fmt += fmt_map[t] + fmt += s.fmt_map[t] if name == "tFAW": fmt += "4x" # i hate hardcoding but this is what it is return fmt -def load_all_vars(): - c.load_entry_object("custRev", 0) - c.load_entry_object("mtcConf", 0) - c.load_entry_object("commonCpuBoostClock", 1) - c.load_entry_object("commonEmcMemVolt", 2) - c.load_entry_object("eristaCpuMaxVolt", 3) - c.load_entry_object("eristaEmcMaxClock", 1) - c.load_entry_object("marikoCpuMaxVolt", 3) - c.load_entry_object("marikoEmcMaxClock", 1) - c.load_entry_object("marikoEmcVddqVolt", 2) - c.load_entry_object("marikoCpuUV", 5) - c.load_entry_object("marikoGpuUV", 4) - c.load_entry_object("eristaCpuUV", 5) - c.load_entry_object("eristaGpuUV", 4) - c.load_entry_object("enableMarikoGpuUnsafeFreqs", 0) - c.load_entry_object("enableEristaGpuUnsafeFreqs", 0) - c.load_entry_object("enableMarikoCpuUnsafeFreqs", 0) - c.load_entry_object("enableEristaCpuUnsafeFreqs", 0) - c.load_entry_object("commonGpuVoltOffset", 3) - c.load_entry_object("marikoEmcDvbShift", 0) - # Advanced memory config - c.load_entry_object("t1_tRCD", 5) - c.load_entry_object("t2_tRP", 5) - c.load_entry_object("t3_tRAS", 5) - c.load_entry_object("t4_tRRD", 5) - c.load_entry_object("t5_tRFC", 5) - c.load_entry_object("t6_tRTW", 5) - c.load_entry_object("t7_tWTR", 5) - c.load_entry_object("t8_tREFI", 5) - c.load_entry_object("mem_burst_latency", 5) - # GPU voltage arrays - for freq in [ - "76800", "153600", "230400", "307200", "384000", "460800", "537600", - "614400", "691200", "768000", "844800", "921600", "998400", "1075200", - "1152000", "1228800", "1267200", "1305600", "1344000", "1382400", - "1420800", "1459200", "1497600", "1536000" - ]: - c.load_entry_object(f"g_volt_{freq}", 3) - - for e_freq in [ - "76800", "153600", "230400", "307200", "384000", "460800", "537600", - "614400", "691200", "768000", "844800", "921600", "998400", "1075200"# , - # "1152000", "1228800" - ]: - c.load_entry_object(f"g_volt_e_{e_freq}", 3) - c.load_entry_object("marikoCpuVmin", 3) - c.load_entry_object("eristaGpuVmin", 3) - c.load_entry_object("marikoGpuVmin", 3) - c.load_entry_object("marikoGpuVmax", 3) def freq_to_label(freq): if freq > 1382400: @@ -168,7 +33,7 @@ def store(sender, app_data): kip_file_path = app_data['file_path_name'] print("Selected" + kip_file_path) read_kip(kip_file_path) - load_all_vars() + s.load_all_vars() def grab_kip_storage_values(sender, app_data): tag = dpg.get_item_alias(sender) @@ -217,7 +82,7 @@ def grab_value_freq_conversion(sender, app_data): def write_kip(): global kip_file_path MAGIC = b"CUST" - struct_fmt = make_struct_format(variables) + struct_fmt = make_struct_format(s.variables) struct_size = struct.calcsize(struct_fmt) if kip_file_path is None: msg = "You need to select a file to use Autosave!" if d.autosave else "You need to select a file to save the KIP!" @@ -231,7 +96,7 @@ def write_kip(): return pos = idx + len(MAGIC) values = [] - for attr_name, t in variables: + for attr_name, t in s.variables: val = getattr(d, attr_name) if t == "u32": val = int(val) & 0xFFFFFFFF @@ -250,7 +115,7 @@ def write_kip(): def read_kip(filename): MAGIC = b"CUST" - struct_fmt = make_struct_format(variables) + struct_fmt = make_struct_format(s.variables) struct_size = struct.calcsize(struct_fmt) with open(filename, "rb") as f: data = f.read() @@ -260,12 +125,12 @@ def read_kip(filename): pos = idx + len(MAGIC) raw = data[pos:pos + struct_size] values = struct.unpack(struct_fmt, raw) - for (attr_name, _), val in zip(variables, values): + for (attr_name, _), val in zip(s.variables, values): setattr(d, attr_name, val) print("=== value layout ===") offset = 0 - for (attr_name, t) in variables: - code = fmt_map[t] + for (attr_name, t) in s.variables: + code = s.fmt_map[t] align = 8 if code == "d" else 4 padding = (-offset) % align if padding: diff --git a/Source/Configurator/src/misc.py b/Source/Configurator/src/misc.py index b5e0e174..c55a62b4 100644 --- a/Source/Configurator/src/misc.py +++ b/Source/Configurator/src/misc.py @@ -28,8 +28,7 @@ import re import installer as ins from defaults import d import ram as r - -skinTarget = 54 # default value +import settings as s def get_ini_path(): if not common.drive or common.drive == 0: @@ -37,150 +36,12 @@ def get_ini_path(): return None return Path(str(common.drive)) / "atmosphere/config/system_settings.ini" -PROFILES = { - "V1_Erista": { - "tskin_pcb_coefficients_console_on_fwdbg": 'str!"[6396, 119440]"', - "tskin_pcb_coefficients_handheld_on_fwdbg": 'str!"[5817, 129580]"', - "tskin_soc_coefficients_console_on_fwdbg": 'str!"[6182, 112480]"', - "tskin_soc_coefficients_handheld_on_fwdbg": 'str!"[5464, 174190]"', - }, - "V2_Mariko": { - "tskin_pcb_coefficients_console_on_fwdbg": 'str!"[7338, 112161]"', - "tskin_pcb_coefficients_handheld_on_fwdbg": 'str!"[6357, 168124]"', - "tskin_soc_coefficients_console_on_fwdbg": 'str!"[6728, 129810]"', - "tskin_soc_coefficients_handheld_on_fwdbg": 'str!"[5675, 203453]"', - }, - "Lite_Mariko": { - "tskin_pcb_coefficients_console_on_fwdbg": 'str!"[7338, 112161]"', - "tskin_pcb_coefficients_handheld_on_fwdbg": 'str!"[5594, 209601]"', - "tskin_soc_coefficients_console_on_fwdbg": 'str!"[6728, 129810]"', - "tskin_soc_coefficients_handheld_on_fwdbg": 'str!"[5235, 199759]"', - }, - "OLED_Mariko": { - "tskin_pcb_coefficients_console_on_fwdbg": 'str!"[8051, -45213]"', - "tskin_pcb_coefficients_handheld_on_fwdbg": 'str!"[7176, -33954]"', - "tskin_soc_coefficients_console_on_fwdbg": 'str!"[7831, 57590]"', - "tskin_soc_coefficients_handheld_on_fwdbg": 'str!"[9029, 4274]"', - }, -} - -BATTERY_SAVE_OPTIONS = { - "bgtc": { - "enable_halfawake": "u32!0x0", - "minimum_interval_normal": "u32!0x7FFFFFFF", - "minimum_interval_save": "u32!0x7FFFFFFF", - "battery_threshold_save": "u32!0x64", - "battery_threshold_stop": "u32!0x64", - }, - "npns": { - "background_processing": "u8!0x0", - "sleep_periodic_interval": "u32!0x7FFFFFFF", - "sleep_processing_timeout": "u32!0x0", - "sleep_max_try_count": "u32!0x0", - }, - "ns.notification": { - "enable_download_task_list": "u8!0x0", - "enable_download_ticket": "u8!0x0", - "enable_network_update": "u8!0x0", - "enable_random_wait": "u8!0x0", - "enable_request_on_cold_boot": "u8!0x0", - "enable_send_rights_usage_status_request": "u8!0x0", - "enable_sync_elicense_request": "u8!0x0", - "enable_version_list": "u8!0x0", - "retry_interval_min": "u32!0x7FFFFFFF", - "retry_interval_max": "u32!0x7FFFFFFF", - "version_list_waiting_limit_bias": "u32!0x7FFFFFFF", - "version_list_waiting_limit_min": "u32!0x7FFFFFFF", - }, - "account": { - "na_required_for_network_service": "u8!0x0", - "na_license_verification_enabled": "u8!0x0", - }, - "account.daemon": { - "background_awaking_periodicity": "u32!0x7FFFFFFF", - "initial_schedule_delay": "u32!0x7FFFFFFF", - "profile_sync_interval": "u32!0x7FFFFFFF", - "na_info_refresh_interval": "u32!0x7FFFFFFF", - }, - "capsrv": { - "enable_album_screenshot_filedata_verification": "u8!0x0", - "enable_album_movie_filehash_verification": "u8!0x0", - "enable_album_movie_filesign_verification": "u8!0x0", - }, - "friends": { - "background_processing": "u8!0x0", - }, - "notification.presenter": { - "snooze_interval_in_seconds": "u32!0x7FFFFFFF", - "connection_retry_count": "u32!0x0", - "alarm_pattern_total_repeat_count": "u32!0x0", - "alarm_pattern_with_vibration_repeat_count": "u32!0x0", - }, - "prepo": { - "transmission_interval_min": "u32!0x7FFFFFFF", - "transmission_retry_interval_min": "u32!0x7FFFFFFF", - "transmission_retry_interval_max": "u32!0x7FFFFFFF", - "transmission_interval_in_sleep": "u32!0x7FFFFFFF", - "statistics_save_interval_min": "u32!0x7FFFFFFF", - "statistics_post_interval": "u32!0x7FFFFFFF", - "save_system_report": "u8!0x0", - }, - "olsc": { - "default_auto_upload_global_setting": "u8!0x0", - "default_auto_download_global_setting": "u8!0x0", - "autonomy_registration_interval_seconds": "u32!0x7FFFFFFF", - "network_service_license_info_cache_expiration_seconds": "u32!0x7FFFFFFF", - "postponed_transfer_task_processing_interval_seconds": "u32!0x7FFFFFFF", - "retry_offset_seconds": "u32!0x7FFFFFFF", - "network_trouble_detection_span_seconds": "u32!0x7FFFFFFF", - "network_connection_polling_interval_seconds": "u32!0x7FFFFFFF", - "is_save_data_backup_policy_check_required": "u8!0x0", - "is_global_transfer_task_autonomy_registration_enabled": "u8!0x0", - "is_on_event_transfer_task_registration_enabled": "u8!0x0", - "is_periodic_transfer_task_registration_enabled": "u8!0x0", - }, - "ntc": { - "is_autonomic_correction_enabled": "u8!0x0", - "autonomic_correction_interval_seconds": "u32!0x7FFFFFFF", - "autonomic_correction_failed_retry_interval_seconds": "u32!0x7FFFFFFF", - "autonomic_correction_immediate_try_count_max": "u32!0x0", - "autonomic_correction_immediate_try_interval_milliseconds": "u32!0x7FFFFFFF", - }, - "systemupdate": { - "bgnup_retry_seconds": "u32!0x7FFFFFFF", - }, - "ns.rights": { - "skip_account_validation_on_rights_check": "u8!0x1", - "next_available_time_of_unexpected_error": "u32!0x7FFFFFFF", - }, - "pctl": { - "intermittent_task_interval_seconds": "u32!0x7FFFFFFF", - }, - "sprofile": { - "adjust_polling_interval_by_profile": "u8!0x0", - "polling_interval_sec_max": "u32!0x7FFFFFFF", - "polling_interval_sec_min": "u32!0x7FFFFFFF", - }, -} - -PSM_OPTIONS = [ - {"name": "1024mA", "value": "u32!0x400"}, - {"name": "1280mA", "value": "u32!0x500"}, - {"name": "1536mA", "value": "u32!0x600"}, - {"name": "1660mA (Lite Default)", "value": "u32!0x67C"}, - {"name": "1792mA", "value": "u32!0x700"}, - {"name": "2048mA (Default)", "value": "u32!0x800"}, - {"name": "2304mA (UNSAFE)", "value": "u32!0x900"}, - {"name": "2560mA (UNSAFE)", "value": "u32!0xA00"}, - {"name": "2816mA (DANGEROUS)", "value": "u32!0xB00"}, - {"name": "3072mA (DANGEROUS)", "value": "u32!0xC00"}, -] def set_psm_value(sender, app_data): ini_path = get_ini_path() if not ini_path: return - value = next((x["value"] for x in PSM_OPTIONS if x["name"] == app_data), None) + value = next((x["value"] for x in s.PSM_OPTIONS if x["name"] == app_data), None) if value: ini.set_ini_values(str(ini_path), "psm", {"current_psm_mA": value}) common.show_popup("Success", f"Charge Limit set to {app_data}") @@ -220,11 +81,11 @@ def remove_tc_entries(): def set_ini_from_profile(sender, app_data, user_data): profile_name = user_data - if profile_name not in PROFILES: + if profile_name not in s.PROFILES: print(f"Profile '{profile_name}' not found.") return - entries = PROFILES[profile_name] + entries = s.PROFILES[profile_name] ini_path = get_ini_path() if not ini_path: return @@ -233,23 +94,14 @@ def set_ini_from_profile(sender, app_data, user_data): print(f"Applied profile {profile_name} under [tc]") def update_skin_target(sender, app_data): - global skinTarget - skinTarget = app_data - print("skinTarget =", skinTarget) + s.skinTarget = app_data + print("skinTarget =", s.skinTarget) ini_path = get_ini_path() if not ini_path: return - entries = { - "use_configurations_on_fwdbg": "u8!0x1", - "tskin_rate_table_console_on_fwdbg": f'str!"[[-1000000,40000,0,0],[36000,43000,51,51],[43000,49000,51,128],[49000,{skinTarget}000,128,255],[{skinTarget}000,1000000,255,255]]"', - "tskin_rate_table_handheld_on_fwdbg": f'str!"[[-1000000,40000,0,0],[36000,43000,51,51],[43000,49000,51,128],[49000,{skinTarget}000,128,255],[{skinTarget}000,1000000,255,255]]"', - "holdable_tskin": "u32!0xEA60", - "touchable_tskin": "u32!0xEA60" - } - - ini.set_ini_values(str(ini_path), "tc", entries) + ini.set_ini_values(str(ini_path), "tc", s.skin_t_entries) def toggle_battery_save(sender, user_data): @@ -259,7 +111,7 @@ def toggle_battery_save(sender, user_data): ini_path = Path(common.drive) / "atmosphere/config/system_settings.ini" - for section, entries in BATTERY_SAVE_OPTIONS.items(): + for section, entries in s.BATTERY_SAVE_OPTIONS.items(): if dpg.get_item_alias(sender) == "enable_battery_fix": # hardcoded but otherwise it doesnt work :( ini.set_ini_values(str(ini_path), section, entries) else: @@ -277,7 +129,7 @@ def populate(): dpg.add_slider_int( label="Skin Target (Recommended - 54°C)", min_value=50, max_value=60, - default_value=skinTarget, + default_value=s.skinTarget, callback=update_skin_target ) dpg.add_button(label="Reset Fan Curve", callback=remove_tc_entries) @@ -311,9 +163,6 @@ def populate(): reversenx_link = "https://github.com/masagrator/ReverseNX-RT/releases/latest/download/ReverseNX-RT-ovl.ovl" dpg.add_button(label="Install ReverseNX-RT", callback=lambda: ins.download_and_install(c=common, install_path=common.drive + "switch/.overlays/", download_url=reversenx_link, filename="ReverseNX-RT-ovl.ovl", success_message="Installed ReverseNX-RT!")) - status_monitor_link = "https://github.com/ppkantorski/Status-Monitor-Overlay/releases/latest/download/ Status-Monitor-Overlay.ovl " - dpg.add_button(label="Install Status Monitor", callback=lambda: ins.download_and_install(c=common, install_path=common.drive + "switch/.overlays/", download_url=status_monitor_link, filename=" Status-Monitor-Overlay.ovl", success_message="Installed Status Monitor!")) - dpg.add_separator(label="Danger Zone") dpg.add_text("These options are known to cause hardware issues, PMIC issues or overheating.\nUse with extreme caution!", color=(255, 165, 0, 255)) @@ -322,7 +171,7 @@ def populate(): dpg.add_spacer(height=10) - psm_items = [x["name"] for x in PSM_OPTIONS] + psm_items = [x["name"] for x in s.PSM_OPTIONS] dpg.add_combo(items=psm_items, label="Battery Charge Limit", callback=set_psm_value, tag="psm_dropdown", default_value="2048mA (Default)") dpg.add_spacer(height=5) @@ -341,21 +190,14 @@ def set_white_tiger_clocks(app_data): # 1400mv emc max # 1375mv cpu max # 750mv vdd2 mariko max - base_vddq_uv = [ - 0, 550000, 555000, 560000, 565000, 570000, 575000, 580000, - 585000, 590000, 595000, 600000, 605000, 610000, 615000, - 620000, 625000, 630000, 635000, 640000, 645000, 650000 - ] + base_vddq_uv = list(range(550000, 650001, 5000)) vddq_uv = [0] + list(range(250000, 750001, 5000)) if app_data else base_vddq_uv vddq_mv = [v // 1000 for v in vddq_uv] vddq_mv_label = ["Default (600 mV)" if f == 0 else f"{f} mV" for f in vddq_mv] dpg.configure_item("marikoEmcVddqVolt", items=vddq_mv_label) - base_voltages_uv = [ - 0, 1050000, 1062500, 1075000, 1087500, 1100000, 1112500, 1125000, - 1137500, 1150000, 1162500, 1175000, 1187500, 1200000, 1212500, 1237500 - ] + base_voltages_uv = list(range(1050000, 1212500 + 1, 12500)) voltages_uv = base_voltages_uv + list(range(1225000, 1400000 + 1, 12500)) if app_data else base_voltages_uv voltages_mv = [v / 1000 for v in voltages_uv] voltages_mv_label = ["Default (1175 mV)" if f == 0 else f"{f} mV" for f in voltages_mv] diff --git a/Source/Configurator/src/preset.py b/Source/Configurator/src/preset.py index 1c3f48e3..7f752c4e 100644 --- a/Source/Configurator/src/preset.py +++ b/Source/Configurator/src/preset.py @@ -20,237 +20,20 @@ along with this program. If not, see . import dearpygui.dearpygui as dpg from defaults import d import common as c -timing_vars = [ - "d.t1_tRCD", - "d.t2_tRP", - "d.t3_tRAS", - "d.t4_tRRD", - "d.t5_tRFC", - "d.t6_tRTW", - "d.t7_tWTR", - "d.t8_tREFI" -] - -timing_preset_default = [ - 0, # tRCD - 0, # tRP - 0, # tRAS - 0, # tRRD - 0, # tRFC - 0, # tRTW - 0, # tWTR - 0, # tREFI -] - -timing_preset_aamgcl_c = [ - 4, # tRCD - 4, # tRP - 5, # tRAS - 5, # tRRD - 5, # tRFC - 5, # tRTW - 7, # tWTR - 6, # tREFI -] - -timing_preset_aamgcl_st = [ - 4, # tRCD - 4, # tRP - 8, # tRAS - 6, # tRRD - 5, # tRFC - 7, # tRTW - 8, # tWTR - 6, # tREFI -] - -timing_preset_mgcj_c = [ - 3, # tRCD - 2, # tRP - 4, # tRAS - 2, # tRRD - 4, # tRFC - 4, # tRTW - 4, # tWTR - 6, # tREFI -] - -timing_preset_mgcj_st = [ - 4, # tRCD - 3, # tRP - 8, # tRAS - 2, # tRRD - 5, # tRFC - 4, # tRTW - 4, # tWTR - 6, # tREFI -] - -timing_preset_ab_mgcl_c = [ - 4, # tRCD - 4, # tRP - 4, # tRAS - 4, # tRRD - 4, # tRFC - 5, # tRTW - 6, # tWTR - 6, # tREFI -] - -timing_preset_ab_mgcl_st = [ - 4, # tRCD - 4, # tRP - 8, # tRAS - 5, # tRRD - 5, # tRFC - 6, # tRTW - 8, # tWTR - 6, # tREFI -] -timing_preset_hb_mgch_c = [ - 4, # tRCD - 4, # tRP - 4, # tRAS - 0, # tRRD - 1, # tRFC - 5, # tRTW - 4, # tWTR - 6, # tREFI -] -timing_preset_hb_mgch_st = [ - 4, # tRCD - 5, # tRP - 9, # tRAS - 1, # tRRD - 2, # tRFC - 6, # tRTW - 4, # tWTR - 6, # tREFI -] - -timing_preset_wtf_c = [ - 4, # tRCD - 4, # tRP - 2, # tRAS - 5, # tRRD - 4, # tRFC - 6, # tRTW - 3, # tWTR - 6, # tREFI -] - -timing_preset_wtf_st = [ - 5, # tRCD - 5, # tRP - 4, # tRAS - 5, # tRRD - 5, # tRFC - 6, # tRTW - 5, # tWTR - 6, # tREFI -] - -timing_preset_wte_c = [ - 2, # tRCD - 2, # tRP - 2, # tRAS - 2, # tRRD - 4, # tRFC - 4, # tRTW - 4, # tWTR - 6, # tREFI -] - -timing_preset_wte_st = [ - 3, # tRCD - 5, # tRP - 3, # tRAS - 3, # tRRD - 5, # tRFC - 4, # tRTW - 5, # tWTR - 6, # tREFI -] - -timing_preset_wtb_c = [ - 4, # tRCD - 4, # tRP - 5, # tRAS - 5, # tRRD - 2, # tRFC - 6, # tRTW - 5, # tWTR - 6, # tREFI -] - -timing_preset_wtb_st = [ - 6, # tRCD - 6, # tRP - 7, # tRAS - 7, # tRRD - 2, # tRFC - 6, # tRTW - 5, # tWTR - 6, # tREFI -] - -timing_preset_nee_c = [ - 3, # tRCD - 3, # tRP - 2, # tRAS - 2, # tRRD - 5, # tRFC - 5, # tRTW - 4, # tWTR - 6, # tREFI -] - -timing_preset_nee_st = [ - 4, # tRCD - 4, # tRP - 4, # tRAS - 3, # tRRD - 7, # tRFC - 6, # tRTW - 5, # tWTR - 6, # tREFI -] - -timing_preset_nme_c = [ - 2, # tRCD - 2, # tRP - 1, # tRAS - 0, # tRRD - 1, # tRFC - 4, # tRTW - 3, # tWTR - 6, # tREFI -] - -timing_preset_nme_st = [ - 3, # tRCD - 3, # tRP - 4, # tRAS - 0, # tRRD - 1, # tRFC - 4, # tRTW - 4, # tWTR - 6, # tREFI -] - +import settings as s def load_defaults(): - apply_timing_preset(timing_preset_default) + apply_timing_preset(s.timing_preset_default) def temporary_presets_unavailable(): c.show_popup_big("We need your help!", "This timing preset currently unavailable due to lack of data. If you have a ram module and want to contribute your data, reach out to me (soul_9017) on the OC discord") def apply_timing_preset(preset): - if len(preset) != len(timing_vars): + if len(preset) != len(s.timing_vars): raise ValueError("Preset invalid!") - for var_name, value in zip(timing_vars, preset): + for var_name, value in zip(s.timing_vars, preset): setattr(d, var_name.split('.')[-1], value) flag = 0 if var_name.endswith("tBL") else 5 @@ -265,25 +48,25 @@ def apply_reg_timings(sender, app_data): case "Choose your RAM Type!": c.show_popup("Error", "You must select a ram type to apply a preset") case "Samsung AA-MGCL/MGCR": - apply_timing_preset(timing_preset_aamgcl_c) + apply_timing_preset(s.timing_preset_aamgcl_c) case "SK Hynix NEI/NEE/x267": - apply_timing_preset(timing_preset_nee_c) + apply_timing_preset(s.timing_preset_nee_c) case "Micron WT:B": - apply_timing_preset(timing_preset_wtb_c) + apply_timing_preset(s.timing_preset_wtb_c) case "Micron AUT:B": - apply_timing_preset(timing_preset_wtb_c) + apply_timing_preset(s.timing_preset_wtb_c) case "Micron WT:F": - apply_timing_preset(timing_preset_wtf_c) + apply_timing_preset(s.timing_preset_wtf_c) case "Samsung AM-MGCJ": - apply_timing_preset(timing_preset_mgcj_c) + apply_timing_preset(s.timing_preset_mgcj_c) case "Micron WT:E": - apply_timing_preset(timing_preset_wte_c) + apply_timing_preset(s.timing_preset_wte_c) case "Samsung AB-MGCL": - apply_timing_preset(timing_preset_ab_mgcl_c) + apply_timing_preset(s.timing_preset_ab_mgcl_c) case "SK Hynix NME": - apply_timing_preset(timing_preset_nme_c) + apply_timing_preset(s.timing_preset_nme_c) case "Samsung HB-MGCH": - apply_timing_preset(timing_preset_hb_mgch_c) + apply_timing_preset(s.timing_preset_hb_mgch_c) case _: temporary_presets_unavailable() @@ -293,25 +76,25 @@ def apply_st_timings(sender, app_data): case "Choose your RAM Type!": c.show_popup("Error", "You must select a ram type to apply a preset") case "Samsung AA-MGCL/MGCR": - apply_timing_preset(timing_preset_aamgcl_st) + apply_timing_preset(s.timing_preset_aamgcl_st) case "SK Hynix NEI/NEE/x267": - apply_timing_preset(timing_preset_nee_st) + apply_timing_preset(s.timing_preset_nee_st) case "Micron WT:B": - apply_timing_preset(timing_preset_wtb_st) + apply_timing_preset(s.timing_preset_wtb_st) case "Micron AUT:B": - apply_timing_preset(timing_preset_wtb_st) + apply_timing_preset(s.timing_preset_wtb_st) case "Micron WT:F": - apply_timing_preset(timing_preset_wtf_st) + apply_timing_preset(s.timing_preset_wtf_st) case "Samsung AM-MGCJ": - apply_timing_preset(timing_preset_mgcj_st) + apply_timing_preset(s.timing_preset_mgcj_st) case "Micron WT:E": - apply_timing_preset(timing_preset_wte_st) + apply_timing_preset(s.timing_preset_wte_st) case "Samsung AB-MGCL": - apply_timing_preset(timing_preset_ab_mgcl_st) + apply_timing_preset(s.timing_preset_ab_mgcl_st) case "SK Hynix NME": - apply_timing_preset(timing_preset_nme_st) + apply_timing_preset(s.timing_preset_nme_st) case "Samsung HB-MGCH": - apply_timing_preset(timing_preset_hb_mgch_st) + apply_timing_preset(s.timing_preset_hb_mgch_st) case _: temporary_presets_unavailable() diff --git a/Source/Configurator/src/ram.py b/Source/Configurator/src/ram.py index 8457a891..ef7af652 100644 --- a/Source/Configurator/src/ram.py +++ b/Source/Configurator/src/ram.py @@ -25,33 +25,17 @@ import common import kip as k import preset from defaults import d +import settings as s def populate(): # Values in kHz - adjusted_freqs_khz = [ - 0, 1600000, 1633000, 1666000, 1700000, 1733000, 1766000, 1800000, 1833000, 1866000, 1900000, - 1933000, 1966000, 2000000, 2033000, 2066000, 2100000, 2133000, 2166000, 2200000, 2233000, - 2266000, 2300000, 2333000, 2366000, 2400000, 2433000, 2466000, 2500000, 2533000, 2566000, - 2600000, 2633000, 2666000, 2700000, 2733000, 2766000, 2800000, 2833000, 2866000, 2900000, - 2933000, 2966000, 3000000, 3033000, 3066000, 3100000, 3133000, 3166000, 3200000, 3233000, - 3266000, 3300000, 3333000, 3366000, 3400000, 3433000, 3466000, 3500000 - ] - voltages_uv = [ - 0, 1050000, 1062500, 1075000, 1087500, 1100000, 1112500, 1125000, - 1137500, 1150000, 1162500, 1175000, 1187500, 1200000, 1212500, 1237500 - ] - vddq_uv = [ - 0, 550000, 555000, 560000, 565000, 570000, 575000, 580000, 585000, 590000, 595000, - 600000, 605000, 610000, 615000, 620000, 625000, 630000, 635000, 640000, 645000, - 650000 - ] - voltages_mv = [v / 1000 for v in voltages_uv] + voltages_mv = [v / 1000 for v in s.voltages_uv] voltages_mv_label = ["Default (1175 mV)" if f == 0 else f"{f} mV" for f in voltages_mv] - vddq_mv = [v / 1000 for v in vddq_uv] + vddq_mv = [v / 1000 for v in s.vddq_uv] vddq_mv_label = ["Default (600 mV)" if f == 0 else f"{f} mV" for f in vddq_mv] # Values in MHz (converted) - values_mhz = [v / 1000 for v in adjusted_freqs_khz] + values_mhz = [v / 1000 for v in s.adjusted_freqs_khz] values_mhz_label_m = ["Default (1996.8 MHz)" if f == 0 else f"{f} MHz" for f in values_mhz] values_mhz_label_e = ["Default (1862.4 MHz)" if f == 0 else f"{f} MHz" for f in values_mhz] dvb = [i for i in range(10)] diff --git a/Source/Configurator/src/settings.py b/Source/Configurator/src/settings.py new file mode 100644 index 00000000..d97d7984 --- /dev/null +++ b/Source/Configurator/src/settings.py @@ -0,0 +1,603 @@ +import common as c + +# Links + +kip_download_link="https://github.com/souldbminersmwc/Horizon-OC/releases/latest/download/loader.kip" +hoc_clk_download_link="https://github.com/souldbminersmwc/Horizon-OC/releases/latest/download/hoc-clk.zip" +nx_ovlloader_link = "https://github.com/ppkantorski/nx-ovlloader/releases/latest/download/nx-ovlloader+.zip" +ultrahand_link = "https://github.com/ppkantorski/Ultrahand-Overlay/releases/latest/download/ovlmenu.ovl" +status_monitor_link = "https://github.com/ppkantorski/Status-Monitor-Overlay/releases/latest/download/ Status-Monitor-Overlay.ovl " +saltynx_link = "https://github.com/masagrator/SaltyNX/releases/latest/download/SaltyNX.zip" +reversenx_link = "https://github.com/masagrator/ReverseNX-RT/releases/latest/download/ReverseNX-RT-ovl.ovl" + +# Frequencies + +freqs_khz = [ + 76800, 153600, 230400, 307200, 384000, 460800, 537600, 614400, 691200, 768000, + 844800, 921600, 998400, 1075200, 1152000, 1228800, 1267200, 1305600, 1344000, 1382400, 1420800, + 1459200, 1497600, 1536000 +] +freqs_khz_e = [ + 76800, 153600, 230400, 307200, 384000, 460800, 537600, 614400, 691200, 768000, + 844800, 921600, 998400, 1075200 #, 1152000, 1228800 # Disabled by default as these freqs can cause board damage +] + +freqs_mhz = [ + 76.8, 153.6, 230.4, 307.2, 384.0, 460.8, 537.6, 614.4, 691.2, 768.0, + 844.8, 921.6, 998.4, 1075.2, 1152.0, 1228.8, 1267.2, 1305.6, 1344.0, 1382.4, + 1420.8, 1459.2, 1497.6, 1536.0 +] + +adjusted_freqs_khz = [ +0, 1600000, 1633000, 1666000, 1700000, 1733000, 1766000, 1800000, 1833000, 1866000, 1900000, +1933000, 1966000, 2000000, 2033000, 2066000, 2100000, 2133000, 2166000, 2200000, 2233000, +2266000, 2300000, 2333000, 2366000, 2400000, 2433000, 2466000, 2500000, 2533000, 2566000, +2600000, 2633000, 2666000, 2700000, 2733000, 2766000, 2800000, 2833000, 2866000, 2900000, +2933000, 2966000, 3000000, 3033000, 3066000, 3100000, 3133000, 3166000, 3200000, 3233000, +3266000, 3300000, 3333000, 3366000, 3400000, 3433000, 3466000, 3500000 +] +voltages_uv = [ +0, 1050000, 1062500, 1075000, 1087500, 1100000, 1112500, 1125000, +1137500, 1150000, 1162500, 1175000, 1187500, 1200000, 1212500, 1237500 +] +vddq_uv = [ +0, 550000, 555000, 560000, 565000, 570000, 575000, 580000, 585000, 590000, 595000, +600000, 605000, 610000, 615000, 620000, 625000, 630000, 635000, 640000, 645000, +650000 +] +freqs_hz_cpu = [ + 1020000, 1122000, 1224000, 1326000, 1428000, 1581000, 1683000, + 1785000, 1887000, 1963500, 2091000, 2193000, 2295000, 2397000, + 2499000, 2601000, 2703000, 2805000, 2907000 +] +freqs_mhz_cpu = [ + 1020.0, 1122.0, 1224.0, 1326.0, 1428.0, 1581.0, 1683.0, + 1785.0, 1887.0, 1963.5, 2091.0, 2193.0, 2295.0, 2397.0, + 2499.0, 2601.0, 2703.0, 2805.0, 2907.0 +] +# Loading/saving + +variables = [ + ("custRev", "u32"), + ("mtcConf", "u32"), + ("commonCpuBoostClock", "u32"), + ("commonEmcMemVolt", "u32"), + ("eristaCpuMaxVolt", "u32"), + ("eristaEmcMaxClock", "u32"), + ("marikoCpuMaxVolt", "u32"), + ("marikoEmcMaxClock", "u32"), + ("marikoEmcVddqVolt", "u32"), + ("marikoCpuUV", "u32"), + ("marikoGpuUV", "u32"), + ("eristaCpuUV", "u32"), + ("eristaGpuUV", "u32"), + ("enableMarikoGpuUnsafeFreqs", "u32"), + ("enableEristaGpuUnsafeFreqs", "u32"), + ("enableMarikoCpuUnsafeFreqs", "u32"), + ("enableEristaCpuUnsafeFreqs", "u32"), + ("commonGpuVoltOffset", "u32"), + ("marikoEmcDvbShift", "u32"), + # advanced config + ("t1_tRCD", "u32"), + ("t2_tRP", "u32"), + ("t3_tRAS", "u32"), + ("t4_tRRD", "u32"), + ("t5_tRFC", "u32"), + ("t6_tRTW", "u32"), + ("t7_tWTR", "u32"), + ("t8_tREFI", "u32"), + ("mem_burst_latency", "u32"), + ("marikoCpuVmin", "u32"), + ("eristaGpuVmin", "u32"), + ("marikoGpuVmin", "u32"), + ("marikoGpuVmax", "u32"), + ("g_volt_76800", "u32"), + ("g_volt_153600", "u32"), + ("g_volt_230400", "u32"), + ("g_volt_307200", "u32"), + ("g_volt_384000", "u32"), + ("g_volt_460800", "u32"), + ("g_volt_537600", "u32"), + ("g_volt_614400", "u32"), + ("g_volt_691200", "u32"), + ("g_volt_768000", "u32"), + ("g_volt_844800", "u32"), + ("g_volt_921600", "u32"), + ("g_volt_998400", "u32"), + ("g_volt_1075200", "u32"), + ("g_volt_1152000", "u32"), + ("g_volt_1228800", "u32"), + ("g_volt_1267200", "u32"), + ("g_volt_1305600", "u32"), + ("g_volt_1344000", "u32"), + ("g_volt_1382400", "u32"), + ("g_volt_1420800", "u32"), + ("g_volt_1459200", "u32"), + ("g_volt_1497600", "u32"), + ("g_volt_1536000", "u32"), + + + ("g_volt_e_76800", "u32"), + ("g_volt_e_153600", "u32"), + ("g_volt_e_230400", "u32"), + ("g_volt_e_307200", "u32"), + ("g_volt_e_384000", "u32"), + ("g_volt_e_460800", "u32"), + ("g_volt_e_537600", "u32"), + ("g_volt_e_614400", "u32"), + ("g_volt_e_691200", "u32"), + ("g_volt_e_768000", "u32"), + ("g_volt_e_844800", "u32"), + ("g_volt_e_921600", "u32"), + ("g_volt_e_998400", "u32"), + ("g_volt_e_1075200", "u32"), +# ("g_volt_e_1152000", "u32"), +# ("g_volt_e_1228800", "u32"), + + +] + +fmt_map = { + "u32": "I", + "double": "d", +} + +def load_all_vars(): + c.load_entry_object("custRev", 0) + c.load_entry_object("mtcConf", 0) + c.load_entry_object("commonCpuBoostClock", 1) + c.load_entry_object("commonEmcMemVolt", 2) + c.load_entry_object("eristaCpuMaxVolt", 3) + c.load_entry_object("eristaEmcMaxClock", 1) + c.load_entry_object("marikoCpuMaxVolt", 3) + c.load_entry_object("marikoEmcMaxClock", 1) + c.load_entry_object("marikoEmcVddqVolt", 2) + c.load_entry_object("marikoCpuUV", 5) + c.load_entry_object("marikoGpuUV", 4) + c.load_entry_object("eristaCpuUV", 5) + c.load_entry_object("eristaGpuUV", 4) + c.load_entry_object("enableMarikoGpuUnsafeFreqs", 0) + c.load_entry_object("enableEristaGpuUnsafeFreqs", 0) + c.load_entry_object("enableMarikoCpuUnsafeFreqs", 0) + c.load_entry_object("enableEristaCpuUnsafeFreqs", 0) + c.load_entry_object("commonGpuVoltOffset", 3) + c.load_entry_object("marikoEmcDvbShift", 0) + + # Advanced memory config + c.load_entry_object("t1_tRCD", 5) + c.load_entry_object("t2_tRP", 5) + c.load_entry_object("t3_tRAS", 5) + c.load_entry_object("t4_tRRD", 5) + c.load_entry_object("t5_tRFC", 5) + c.load_entry_object("t6_tRTW", 5) + c.load_entry_object("t7_tWTR", 5) + c.load_entry_object("t8_tREFI", 5) + c.load_entry_object("mem_burst_latency", 5) + c.load_entry_object("marikoCpuVmin", 3) + c.load_entry_object("eristaGpuVmin", 3) + c.load_entry_object("marikoGpuVmin", 3) + c.load_entry_object("marikoGpuVmax", 3) + # GPU voltage arrays + for freq in [ + "76800", "153600", "230400", "307200", "384000", "460800", "537600", + "614400", "691200", "768000", "844800", "921600", "998400", "1075200", + "1152000", "1228800", "1267200", "1305600", "1344000", "1382400", + "1420800", "1459200", "1497600", "1536000" + ]: + c.load_entry_object(f"g_volt_{freq}", 3) + + for e_freq in [ + "76800", "153600", "230400", "307200", "384000", "460800", "537600", + "614400", "691200", "768000", "844800", "921600", "998400", "1075200"# , + # "1152000", "1228800" + ]: + c.load_entry_object(f"g_volt_e_{e_freq}", 3) + + +# Timings + +timing_vars = [ + "d.t1_tRCD", + "d.t2_tRP", + "d.t3_tRAS", + "d.t4_tRRD", + "d.t5_tRFC", + "d.t6_tRTW", + "d.t7_tWTR", + "d.t8_tREFI" +] + +timing_preset_default = [ + 0, # tRCD + 0, # tRP + 0, # tRAS + 0, # tRRD + 0, # tRFC + 0, # tRTW + 0, # tWTR + 0, # tREFI +] + +timing_preset_aamgcl_c = [ + 4, # tRCD + 4, # tRP + 5, # tRAS + 5, # tRRD + 5, # tRFC + 5, # tRTW + 7, # tWTR + 6, # tREFI +] + +timing_preset_aamgcl_st = [ + 4, # tRCD + 4, # tRP + 8, # tRAS + 6, # tRRD + 5, # tRFC + 7, # tRTW + 8, # tWTR + 6, # tREFI +] + +timing_preset_mgcj_c = [ + 3, # tRCD + 2, # tRP + 4, # tRAS + 2, # tRRD + 4, # tRFC + 4, # tRTW + 4, # tWTR + 6, # tREFI +] + +timing_preset_mgcj_st = [ + 4, # tRCD + 3, # tRP + 8, # tRAS + 2, # tRRD + 5, # tRFC + 4, # tRTW + 4, # tWTR + 6, # tREFI +] + +timing_preset_ab_mgcl_c = [ + 4, # tRCD + 4, # tRP + 4, # tRAS + 4, # tRRD + 4, # tRFC + 5, # tRTW + 6, # tWTR + 6, # tREFI +] + +timing_preset_ab_mgcl_st = [ + 4, # tRCD + 4, # tRP + 8, # tRAS + 5, # tRRD + 5, # tRFC + 6, # tRTW + 8, # tWTR + 6, # tREFI +] +timing_preset_hb_mgch_c = [ + 4, # tRCD + 4, # tRP + 4, # tRAS + 0, # tRRD + 1, # tRFC + 5, # tRTW + 4, # tWTR + 6, # tREFI +] +timing_preset_hb_mgch_st = [ + 4, # tRCD + 5, # tRP + 9, # tRAS + 1, # tRRD + 2, # tRFC + 6, # tRTW + 4, # tWTR + 6, # tREFI +] + +timing_preset_wtf_c = [ + 4, # tRCD + 4, # tRP + 2, # tRAS + 5, # tRRD + 4, # tRFC + 6, # tRTW + 3, # tWTR + 6, # tREFI +] + +timing_preset_wtf_st = [ + 5, # tRCD + 5, # tRP + 4, # tRAS + 5, # tRRD + 5, # tRFC + 6, # tRTW + 5, # tWTR + 6, # tREFI +] + +timing_preset_wte_c = [ + 2, # tRCD + 2, # tRP + 2, # tRAS + 2, # tRRD + 4, # tRFC + 4, # tRTW + 4, # tWTR + 6, # tREFI +] + +timing_preset_wte_st = [ + 3, # tRCD + 5, # tRP + 3, # tRAS + 3, # tRRD + 5, # tRFC + 4, # tRTW + 5, # tWTR + 6, # tREFI +] + +timing_preset_wtb_c = [ + 4, # tRCD + 4, # tRP + 5, # tRAS + 5, # tRRD + 2, # tRFC + 6, # tRTW + 5, # tWTR + 6, # tREFI +] + +timing_preset_wtb_st = [ + 6, # tRCD + 6, # tRP + 7, # tRAS + 7, # tRRD + 2, # tRFC + 6, # tRTW + 5, # tWTR + 6, # tREFI +] + +timing_preset_nee_c = [ + 3, # tRCD + 3, # tRP + 2, # tRAS + 2, # tRRD + 5, # tRFC + 5, # tRTW + 4, # tWTR + 6, # tREFI +] + +timing_preset_nee_st = [ + 4, # tRCD + 4, # tRP + 4, # tRAS + 3, # tRRD + 7, # tRFC + 6, # tRTW + 5, # tWTR + 6, # tREFI +] + +timing_preset_nme_c = [ + 2, # tRCD + 2, # tRP + 1, # tRAS + 0, # tRRD + 1, # tRFC + 4, # tRTW + 3, # tWTR + 6, # tREFI +] + +timing_preset_nme_st = [ + 3, # tRCD + 3, # tRP + 4, # tRAS + 0, # tRRD + 1, # tRFC + 4, # tRTW + 4, # tWTR + 6, # tREFI +] + + +# INI + +skinTarget = 54 # default value + + +PROFILES = { + "V1_Erista": { + "tskin_pcb_coefficients_console_on_fwdbg": 'str!"[6396, 119440]"', + "tskin_pcb_coefficients_handheld_on_fwdbg": 'str!"[5817, 129580]"', + "tskin_soc_coefficients_console_on_fwdbg": 'str!"[6182, 112480]"', + "tskin_soc_coefficients_handheld_on_fwdbg": 'str!"[5464, 174190]"', + }, + "V2_Mariko": { + "tskin_pcb_coefficients_console_on_fwdbg": 'str!"[7338, 112161]"', + "tskin_pcb_coefficients_handheld_on_fwdbg": 'str!"[6357, 168124]"', + "tskin_soc_coefficients_console_on_fwdbg": 'str!"[6728, 129810]"', + "tskin_soc_coefficients_handheld_on_fwdbg": 'str!"[5675, 203453]"', + }, + "Lite_Mariko": { + "tskin_pcb_coefficients_console_on_fwdbg": 'str!"[7338, 112161]"', + "tskin_pcb_coefficients_handheld_on_fwdbg": 'str!"[5594, 209601]"', + "tskin_soc_coefficients_console_on_fwdbg": 'str!"[6728, 129810]"', + "tskin_soc_coefficients_handheld_on_fwdbg": 'str!"[5235, 199759]"', + }, + "OLED_Mariko": { + "tskin_pcb_coefficients_console_on_fwdbg": 'str!"[8051, -45213]"', + "tskin_pcb_coefficients_handheld_on_fwdbg": 'str!"[7176, -33954]"', + "tskin_soc_coefficients_console_on_fwdbg": 'str!"[7831, 57590]"', + "tskin_soc_coefficients_handheld_on_fwdbg": 'str!"[9029, 4274]"', + }, +} + +BATTERY_SAVE_OPTIONS = { + "bgtc": { + "enable_halfawake": "u32!0x0", + "minimum_interval_normal": "u32!0x7FFFFFFF", + "minimum_interval_save": "u32!0x7FFFFFFF", + "battery_threshold_save": "u32!0x64", + "battery_threshold_stop": "u32!0x64", + }, + "npns": { + "background_processing": "u8!0x0", + "sleep_periodic_interval": "u32!0x7FFFFFFF", + "sleep_processing_timeout": "u32!0x0", + "sleep_max_try_count": "u32!0x0", + }, + "ns.notification": { + "enable_download_task_list": "u8!0x0", + "enable_download_ticket": "u8!0x0", + "enable_network_update": "u8!0x0", + "enable_random_wait": "u8!0x0", + "enable_request_on_cold_boot": "u8!0x0", + "enable_send_rights_usage_status_request": "u8!0x0", + "enable_sync_elicense_request": "u8!0x0", + "enable_version_list": "u8!0x0", + "retry_interval_min": "u32!0x7FFFFFFF", + "retry_interval_max": "u32!0x7FFFFFFF", + "version_list_waiting_limit_bias": "u32!0x7FFFFFFF", + "version_list_waiting_limit_min": "u32!0x7FFFFFFF", + }, + "account": { + "na_required_for_network_service": "u8!0x0", + "na_license_verification_enabled": "u8!0x0", + }, + "account.daemon": { + "background_awaking_periodicity": "u32!0x7FFFFFFF", + "initial_schedule_delay": "u32!0x7FFFFFFF", + "profile_sync_interval": "u32!0x7FFFFFFF", + "na_info_refresh_interval": "u32!0x7FFFFFFF", + }, + "capsrv": { + "enable_album_screenshot_filedata_verification": "u8!0x0", + "enable_album_movie_filehash_verification": "u8!0x0", + "enable_album_movie_filesign_verification": "u8!0x0", + }, + "friends": { + "background_processing": "u8!0x0", + }, + "notification.presenter": { + "snooze_interval_in_seconds": "u32!0x7FFFFFFF", + "connection_retry_count": "u32!0x0", + "alarm_pattern_total_repeat_count": "u32!0x0", + "alarm_pattern_with_vibration_repeat_count": "u32!0x0", + }, + "prepo": { + "transmission_interval_min": "u32!0x7FFFFFFF", + "transmission_retry_interval_min": "u32!0x7FFFFFFF", + "transmission_retry_interval_max": "u32!0x7FFFFFFF", + "transmission_interval_in_sleep": "u32!0x7FFFFFFF", + "statistics_save_interval_min": "u32!0x7FFFFFFF", + "statistics_post_interval": "u32!0x7FFFFFFF", + "save_system_report": "u8!0x0", + }, + "olsc": { + "default_auto_upload_global_setting": "u8!0x0", + "default_auto_download_global_setting": "u8!0x0", + "autonomy_registration_interval_seconds": "u32!0x7FFFFFFF", + "network_service_license_info_cache_expiration_seconds": "u32!0x7FFFFFFF", + "postponed_transfer_task_processing_interval_seconds": "u32!0x7FFFFFFF", + "retry_offset_seconds": "u32!0x7FFFFFFF", + "network_trouble_detection_span_seconds": "u32!0x7FFFFFFF", + "network_connection_polling_interval_seconds": "u32!0x7FFFFFFF", + "is_save_data_backup_policy_check_required": "u8!0x0", + "is_global_transfer_task_autonomy_registration_enabled": "u8!0x0", + "is_on_event_transfer_task_registration_enabled": "u8!0x0", + "is_periodic_transfer_task_registration_enabled": "u8!0x0", + }, + "ntc": { + "is_autonomic_correction_enabled": "u8!0x0", + "autonomic_correction_interval_seconds": "u32!0x7FFFFFFF", + "autonomic_correction_failed_retry_interval_seconds": "u32!0x7FFFFFFF", + "autonomic_correction_immediate_try_count_max": "u32!0x0", + "autonomic_correction_immediate_try_interval_milliseconds": "u32!0x7FFFFFFF", + }, + "systemupdate": { + "bgnup_retry_seconds": "u32!0x7FFFFFFF", + }, + "ns.rights": { + "skip_account_validation_on_rights_check": "u8!0x1", + "next_available_time_of_unexpected_error": "u32!0x7FFFFFFF", + }, + "pctl": { + "intermittent_task_interval_seconds": "u32!0x7FFFFFFF", + }, + "sprofile": { + "adjust_polling_interval_by_profile": "u8!0x0", + "polling_interval_sec_max": "u32!0x7FFFFFFF", + "polling_interval_sec_min": "u32!0x7FFFFFFF", + }, +} + +PSM_OPTIONS = [ + {"name": "1024mA", "value": "u32!0x400"}, + {"name": "1280mA", "value": "u32!0x500"}, + {"name": "1536mA", "value": "u32!0x600"}, + {"name": "1660mA (Lite Default)", "value": "u32!0x67C"}, + {"name": "1792mA", "value": "u32!0x700"}, + {"name": "2048mA (Default)", "value": "u32!0x800"}, + {"name": "2304mA (UNSAFE)", "value": "u32!0x900"}, + {"name": "2560mA (UNSAFE)", "value": "u32!0xA00"}, + {"name": "2816mA (DANGEROUS)", "value": "u32!0xB00"}, + {"name": "3072mA (DANGEROUS)", "value": "u32!0xC00"}, +] + +skin_t_entries = { + "use_configurations_on_fwdbg": "u8!0x1", + "tskin_rate_table_console_on_fwdbg": f'str!"[[-1000000,40000,0,0],[36000,43000,51,51],[43000,49000,51,128],[49000,{skinTarget}000,128,255],[{skinTarget}000,1000000,255,255]]"', + "tskin_rate_table_handheld_on_fwdbg": f'str!"[[-1000000,40000,0,0],[36000,43000,51,51],[43000,49000,51,128],[49000,{skinTarget}000,128,255],[{skinTarget}000,1000000,255,255]]"', + "holdable_tskin": "u32!0xEA60", + "touchable_tskin": "u32!0xEA60" +} +# Thresholds + +mariko_meme_threshold = 1536000 + +mariko_dangerous_gpu_threshold = 1382400 +mariko_unsafe_gpu_threshold = 1152000 + +erista_dangerous_gpu_threshold = 1151000 +erista_unsafe_gpu_threshold = 922000 + +mariko_voltage_step = 5 +erista_voltage_step = 5 + +mariko_gpu_offset_max = 50 + +mariko_gpu_min_volt = 480 +erista_gpu_min_volt = 700 + + +mariko_gpu_max_volt = 960 +erista_gpu_max_volt = 1000 + +mariko_gpu_max_vmin = 700 +erista_gpu_max_vmin = 850 + +mariko_cpu_min_vmin = 700 +mariko_cpu_max_vmin = 750 + +# TODO: Make more stuff configurable + + +# COLORS +danger_color = (255, 0, 0, 255) +unsafe_color = (255, 165, 0, 255) +safe_color = (255, 255, 255, 255) \ No newline at end of file diff --git a/dist/README.md b/dist/README.md index eed6c8b5..6b3d0fa2 100644 --- a/dist/README.md +++ b/dist/README.md @@ -53,5 +53,5 @@ Run build.bat or cd into folder and run "python -m PyInstaller --onefile --add-d ## Credits meha for Switch-Oc-Suite
sys-clk team for sys-clk
-b0rd2auth for Ultrahand sys-clk fork
-Lightos and Sammybigio2010 for early testing
+b0rd2death for Ultrahand sys-clk fork
+Lightos and Sammybigio2011 for early testing
diff --git a/dist/atmosphere/kips/hoc.kip b/dist/atmosphere/kips/hoc.kip index 12834196675aaddf376f3ef597bd896824438e7f..f3345ffefd3684c679943d30d79a45ce29db0a10 100644 GIT binary patch delta 44741 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 ODj(tHcr!KPt^Wlj$X)FK delta 44911 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