240 Commits
2.0.2 ... main

Author SHA1 Message Date
bb9a477115 Merge tag 2.4.1 from upstream Horizon-OC
Some checks failed
Build Horizon OC Zeus / build (push) Failing after 5s
2026-06-05 23:17:20 +02:00
souldbminersmwc
90b950a17c hocclk: fix dvfs error 2026-06-05 15:40:53 -04:00
2bf443fb3c Merge tag 2.4.0 from upstream Horizon-OC
Some checks failed
Build Horizon OC Zeus / build (push) Failing after 6s
Bring main up to the 2.4.0 release while keeping German sysmodule
notifications and upstream kip.cpp fixes from the release.
2026-06-05 11:25:47 +02:00
souldbminersmwc
6be91a1b0e hocclk: correct small error 2026-06-04 20:16:17 -04:00
souldbminersmwc
88bfa9a4ec hocclk: format code
use clang format file provided for optimal formatting
2026-06-04 19:52:11 -04:00
souldbminersmwc
c6a8884c14 Update .clang-format 2026-06-04 19:34:58 -04:00
souldbminersmwc
06ec789e32 Update .clang-format 2026-06-04 19:29:31 -04:00
souldbminersmwc
82ce031851 hocclk: add input current override feature
Co-Authored-By: cat130504 <231865593+cat130504@users.noreply.github.com>
2026-06-04 19:29:25 -04:00
souldbminersmwc
2908d7520c hocclk: readd credits in submenu 2026-06-03 18:37:56 -04:00
souldbminersmwc
4cfdd28cb0 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-06-03 16:58:27 -04:00
souldbminersmwc
60d6bf3b26 hoc: more translation 2026-06-03 16:58:24 -04:00
Lightos1
6d6b5c93ef Update COMPILING.md 2026-06-03 08:07:50 +02:00
Lightos1
c7c485cc60 Update COMPILING.md 2026-06-03 08:07:19 +02:00
souldbminersmwc
ec0155be3e ldr: proper timings are better 2026-06-02 18:55:38 -04:00
souldbminersmwc
3a68a060c6 hocclk: remove credits
refer to the website for credits
2026-05-31 19:17:42 -04:00
souldbminersmwc
e34ec9d8d1 Update about_gui.cpp 2026-05-31 19:16:28 -04:00
souldbminersmwc
9a4e659b9c Update misc_gui.cpp 2026-05-31 18:25:45 -04:00
souldbminersmwc
afa4fa924a Update config.h 2026-05-31 14:09:46 -04:00
souldbminersmwc
7ebc999e4a hocclk: fix gm20b clocks 2026-05-30 22:00:03 -04:00
souldbminersmwc
6fcb2029fe hocclk: fix array OOB 2026-05-30 20:34:18 -04:00
souldbminersmwc
d21391fe79 hocclk: improve configurator seamlessness 2026-05-30 20:17:52 -04:00
souldbminersmwc
db62b6fb42 hocclk: fix flickering 2026-05-30 18:03:35 -04:00
souldbminersmwc
53bf78181c hoc: make hiopt default yet again 2026-05-30 17:51:22 -04:00
souldbminersmwc
8504bd786e all: fix errors 2026-05-30 17:40:59 -04:00
souldbminersmwc
5540a96af1 all: new GPU UV features 2026-05-30 17:32:06 -04:00
Lightos1
0d5558f876 pcv_erista: add experimental proper write timings 2026-05-30 17:39:49 +02:00
souldbminersmwc
a95c0fc23c hocclk: optimize kip routines 2026-05-29 18:18:51 -04:00
souldbminersmwc
1d56ed1504 hocclk: improve ui cohesiveness 2026-05-29 16:49:00 -04:00
souldbminersmwc
a8b43a650d hocclk: fix auto ram oc on erista 2026-05-29 16:21:52 -04:00
souldbminersmwc
aaa8ec1881 Update clock_manager.cpp 2026-05-29 16:17:01 -04:00
souldbminersmwc
bc6dd1a4f6 hocclk: fix compile error 2026-05-29 16:16:23 -04:00
souldbminersmwc
532a85b593 hocclk: fix some logic issues 2026-05-29 15:51:13 -04:00
souldbminersmwc
a18efcbed7 hocclk: fix gm20b driver bug at >1305mhz 2026-05-28 20:02:33 -04:00
souldbminersmwc
e52d57a961 Update kip.cpp 2026-05-28 19:50:27 -04:00
souldbminersmwc
6093cff721 hocclk: increase erista cpu min vmin to 750mV 2026-05-28 18:47:01 -04:00
souldbminersmwc
de62e8b33d hocclk: add lower auto ram oc freqs 2026-05-28 18:44:48 -04:00
souldbminersmwc
0d7608a4d5 hocclk: fix graph for erista 2026-05-28 18:43:16 -04:00
souldbminersmwc
397d96843b hocclk: make live cpu uv non experimental on erista 2026-05-28 16:44:19 -04:00
souldbminersmwc
fd6ceaaaf1 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-05-28 16:36:24 -04:00
souldbminersmwc
a35a3b241b hocclk: fix erista live cpu uv0 2026-05-28 16:36:21 -04:00
Lightos1
072e9e4076 ldr: improved dvb tables by b3711
Co-Authored-By: halop <4215938+halop@users.noreply.github.com
2026-05-28 19:05:21 +02:00
souldbminersmwc
3af3ad4a68 hocclk: fix clock reset bug 2026-05-27 20:51:44 -04:00
souldbminersmwc
d1308e0251 hocclk: add auto cpu ram oc 2026-05-27 19:32:56 -04:00
souldbminersmwc
e48cab36b7 hocclk: remove handheld TDP 2026-05-27 16:21:56 -04:00
souldbminersmwc
b2ba7354cd Update base_gui.cpp 2026-05-27 16:12:43 -04:00
souldbminersmwc
4f0e890e01 hocclk: fix pcv patch 38.4mhz clock bug 2026-05-27 15:59:05 -04:00
souldbminersmwc
86a2800e6e hocclk: fix compile error 2026-05-26 20:35:51 -04:00
souldbminersmwc
13550fbc20 hocclk: improve DVFS curve 2026-05-26 20:35:07 -04:00
souldbminersmwc
187d6d6422 Update board_volt.cpp 2026-05-26 19:51:04 -04:00
Souldbminer
060178aea6 Merge pull request #85 from Horizon-OC/erista-dvfs
WIP Erista dvfs
2026-05-26 19:50:31 -04:00
souldbminersmwc
715577a644 Update board_volt.cpp 2026-05-26 19:50:09 -04:00
souldbminersmwc
45332444ec wip erista dvfs 2026-05-26 19:44:46 -04:00
souldbminersmwc
fd3808fd82 Update misc_gui.cpp 2026-05-26 19:19:17 -04:00
souldbminersmwc
e13e2b1f41 hocclk: improve logo position 2026-05-26 19:15:07 -04:00
souldbminersmwc
6b26aa5574 hocclk: improve ui
yes i did vibecode this, no i don't care
2026-05-26 19:05:53 -04:00
souldbminersmwc
13f422fa29 hocclk: overlay logo 2026-05-26 16:10:13 -04:00
souldbminersmwc
fa66a09b04 hocclk: add timing tbreak graph 2026-05-25 16:00:23 -04:00
souldbminersmwc
5d9c7acc52 hocclk: add latency graph 2026-05-25 15:52:53 -04:00
souldbminersmwc
52076a0191 reapply erista mrf changes 2026-05-25 15:18:36 -04:00
Souldbminer
08936d9466 Merge pull request #84 from Horizon-OC/erista-mrf-shit
erista mrf
2026-05-25 15:02:40 -04:00
souldbminersmwc
45ed9afb04 Merge remote-tracking branch 'origin/main' into erista-mrf-shit 2026-05-25 15:01:52 -04:00
souldbminersmwc
1358b10616 hocclk: lower default 2026-05-25 14:55:52 -04:00
ca25cff7fa Merge upstream Horizon-OC main (749fd385)
Some checks failed
Build Horizon OC Zeus / build (push) Failing after 6s
Includes 2.3.1 changes: kip migration, erista GPU workaround, safety
fixes, and Mariko GPU boot voltage patch. Resolve dist binary conflicts
with upstream build artifacts.
2026-05-25 20:54:23 +02:00
souldbminersmwc
e9f5f59ddf ldr: add some comments 2026-05-25 13:28:58 -04:00
souldbminersmwc
67be6d9120 ldr: fix patch 2026-05-25 13:18:32 -04:00
Lightos1
749fd385ce revert erista mrf changes 2026-05-24 21:30:05 +02:00
Lightos1
65927cffce Revert "Update misc_gui.cpp"
This reverts commit fae0fa5d5f.
2026-05-24 21:21:00 +02:00
souldbminersmwc
10bcf4542d hocclk: fix safety features 2026-05-24 12:34:37 -04:00
Lightos1
8bc1aee110 add back comment 2026-05-24 16:46:28 +02:00
Lightos1
ca4b132f25 add initial garbage erista shit 2026-05-24 16:45:31 +02:00
souldbminersmwc
afeee4937c Update horizon-oc-overlay.ovl 2026-05-23 20:09:35 -04:00
souldbminersmwc
66308b152b hocclk: kip migration 2026-05-23 20:07:28 -04:00
souldbminersmwc
72dfdb53fc hocclk: fix small issue 2026-05-23 19:45:47 -04:00
souldbminersmwc
ee730ca68e all: add mariko gpu boot voltage patch 2026-05-23 19:43:54 -04:00
souldbminersmwc
2d0a2c4f6d hocclk: fix edge case with middle freqs 2026-05-23 16:40:04 -04:00
souldbminersmwc
8411a14b26 hocclk: fix ui issue 2026-05-22 17:50:36 -04:00
souldbminersmwc
99e9270314 hocclk: add erista gpu workaround 2026-05-22 17:48:21 -04:00
souldbminersmwc
58488f7f48 chore: add no exosphere build scripts 2026-05-22 17:40:49 -04:00
souldbminersmwc
c2238eb070 hocclk: perfect migration between kip versions 2026-05-22 16:48:48 -04:00
souldbminersmwc
4271efb4a7 hocclk/ldr: add kip migration skeleton 2026-05-22 16:35:56 -04:00
souldbminersmwc
fd9e5a2e08 add more docs and warnings 2026-05-22 16:16:06 -04:00
souldbminersmwc
4587b01152 hocclk: minor configurator changes 2026-05-22 16:13:16 -04:00
souldbminersmwc
fae0fa5d5f Update misc_gui.cpp 2026-05-22 16:10:18 -04:00
souldbminersmwc
059fe40339 hocclk: update configurator for new features 2026-05-22 16:10:12 -04:00
Lightos1
a617a7398a Implement Mariko-style MRF for erista
There is heavy code duplication because I'm lazy, but loader needs to be
refactored anyway at some point and this "works" for now.
2026-05-22 21:57:32 +02:00
souldbminersmwc
2f092f7955 hocclk: fix UV0 with live cpu uv 2026-05-19 17:15:12 -04:00
souldbminersmwc
003854d2bb hocclk: update live cpu uv more often 2026-05-19 17:06:54 -04:00
souldbminersmwc
f49e1a80a0 hocclk: erista finally gets some love
bugfixes and live CPU uv fixed (for erista at least)
2026-05-19 17:04:14 -04:00
souldbminersmwc
16ea883fa8 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-05-19 16:22:06 -04:00
souldbminersmwc
f787ed7fd8 hocclk: fix tpyos 2026-05-19 16:22:03 -04:00
Lightos1
63c7fb211d Code cleanup and improved dvb tables.
Thanks to: jimmy for testing and b3711 for many additional voltage scale improvements.

Co-Authored-By: halop <4215938+halop@users.noreply.github.com>
2026-05-19 20:02:09 +02:00
Lightos1
52e13f5e1e Merge pull request #81 from IMLeoCat/patch-1
Update README.md
2026-05-18 10:32:13 +02:00
d59f0b5900 build: fix macOS compile and dist packaging
Some checks failed
Build Horizon OC Zeus / build (push) Failing after 4s
Use portable sed for title_id extraction, copy hoc-clk output into dist/
correctly, and ensure overlay output directories exist. Rebuild dist after
upstream merge.
2026-05-17 10:58:03 +02:00
5403c3bdd8 Merge upstream Horizon-OC main (797bcf79) 2026-05-17 10:52:03 +02:00
souldbminersmwc
797bcf79a2 hocclk: fix resolution read bug
thx masa for pointing this out
2026-05-16 15:50:32 -04:00
e962de8373 hocclk: translate user notifications to German
Some checks failed
Build Horizon OC Zeus / build (push) Failing after 1m16s
2026-05-16 11:52:08 +02:00
souldbminersmwc
0d227cfb82 hocclk: add info about new feature 2026-05-13 19:52:11 -04:00
souldbminersmwc
3010c915a7 hocclk: add info to hocclk 2026-05-13 19:49:48 -04:00
souldbminersmwc
196933a6b3 hocclk: read voltage from i2c instead of rgltr 2026-05-12 17:00:46 -04:00
Lightos1
bfc93c6238 ldr: don't be an idiot, remove debug code 2026-05-12 21:29:27 +02:00
Lightos1
6d284d9c2b ldr: fix dvb brackets 2026-05-12 21:26:42 +02:00
Lightos1
7384404ac1 ldr: use DvbMeta struct 2026-05-12 20:05:02 +02:00
IMLeoCat
35de44d3fa Update README.md
The Installation part is outdated. add this line from "https://horizon-oc.github.io/guide.html".
2026-05-13 01:13:30 +08:00
Lightos1
1b07df5f08 Revert "change cust rev back to 2, it shouldn't have been changed in the first place"
This reverts commit d6c2ddf2ea.
2026-05-12 13:40:35 +02:00
Lightos1
34e1f39510 ldr: even more (partially guessed) labeling of CvbMeta 2026-05-12 13:07:46 +02:00
Lightos1
ef830ce3f6 ldr: label more of CvbMeta 2026-05-12 13:03:51 +02:00
Lightos1
d7e22b3ccc ldr: add partially labeled CvbMeta struct 2026-05-12 12:44:52 +02:00
Lightos1
d6c2ddf2ea change cust rev back to 2, it shouldn't have been changed in the first place 2026-05-12 11:22:51 +02:00
Lightos1
b4627ad171 ldr: minVolt -> MinVolt 2026-05-12 10:34:05 +02:00
Lightos1
381a1eafc4 ldr: properly clamp soc voltage 2026-05-12 10:32:14 +02:00
souldbminersmwc
f90ba2ca59 2.3.0 2026-05-11 19:07:44 -04:00
Lightos1
f97fdc9528 conversion script: fix 3200mhz 2026-05-11 21:34:01 +02:00
Lightos1
ed63a95488 conversion script: fix 3200mhz 2026-05-11 21:33:44 +02:00
Lightos1
e24512c9d6 raise vddq min validator to 400 2026-05-11 21:26:31 +02:00
Lightos1
1efd91d535 reaise vddq validator 2026-05-11 21:22:05 +02:00
Lightos1
3337738dcc conversion script: fix silly bugs 2026-05-11 19:58:08 +02:00
Lightos1
7f1f504c36 Merge branch 'main' of https://github.com/horizon-OC/Horizon-OC 2026-05-11 19:36:10 +02:00
Lightos1
2f21f23266 experimental: add improved dvb table (+ conversion script) 2026-05-11 19:35:48 +02:00
Lightos1
3c99ad0186 Update README.md 2026-05-11 17:22:54 +02:00
Lightos1
e4dd690ac9 Update README.md 2026-05-11 17:19:36 +02:00
Lightos1
9122768953 delete ams_patch.bat from the right branch 2026-05-10 22:44:32 +02:00
Lightos1
3539916cfd fix compilation errors 2026-05-10 22:36:29 +02:00
Lightos1
4bd776c8aa kip.cpp: improve version mismatch logging 2026-05-10 18:58:37 +02:00
souldbminersmwc
78cda43054 whoops i forgot code 2026-05-10 12:48:02 -04:00
souldbminersmwc
580db1f167 hocclk: fix gm20b driver 2026-05-10 12:47:49 -04:00
souldbminersmwc
ea9adbfa14 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-05-10 11:22:33 -04:00
souldbminersmwc
accfea86f1 hocmon: get real freqs from hocclk instead of clkrst 2026-05-10 11:22:31 -04:00
Lightos1
badf182529 build.sh: improve build process 2026-05-10 01:51:22 +02:00
souldbminersmwc
12f12c6b1e hocclk: fix cust rev detection 2026-05-09 19:13:05 -04:00
souldbminersmwc
dde723baee Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-05-09 19:04:44 -04:00
souldbminersmwc
27db54644e hocclk: fix 1267mhz clock voltage 2026-05-09 19:04:41 -04:00
Lightos1
138bcb6dc6 build.sh: alternatively I should consider not being stupid 2026-05-10 00:57:31 +02:00
Lightos1
05fa5034d3 Revert "build.sh: use make -j rather than -j8"
This reverts commit 8a98a57b4b.
Thansk to microslops amazing memory management, make -j sometimes runs
out of ram on my system when compiling libstratosphere. This can hang my
entire system and also corrupt ram??? WTF
2026-05-10 00:44:27 +02:00
Lightos1
8a98a57b4b build.sh: use make -j rather than -j8 2026-05-10 00:31:26 +02:00
souldbminersmwc
c12b0136f8 hocclk: add missing code and small change to overlay 2026-05-09 16:54:39 -04:00
souldbminersmwc
c4f7f0e713 hocclk: add mariko middle freq hack 2026-05-09 16:53:30 -04:00
Lightos1
935dd24129 move exosphere to /dist/Atmosphere/ 2026-05-09 22:51:57 +02:00
Lightos1
d72e05259a Update COMPILING.md 2026-05-09 22:46:33 +02:00
Lightos1
847ae19de9 add hoc notification icon -- thanks ppkantorski! 2026-05-09 22:44:35 +02:00
souldbminersmwc
8651e418ca Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-05-09 16:07:03 -04:00
souldbminersmwc
2e3ef0f3b0 add GM20B GPU clock driver 2026-05-09 16:06:57 -04:00
Lightos1
c018b10a7f soctherm: remove reduntant EnableSensor calls 2026-05-09 21:41:11 +02:00
souldbminersmwc
336ea0eddb hocclk: fix me being a idiot 2026-05-09 15:37:24 -04:00
Lightos1
d561c0e538 add speedo fuse reading and fix wafer coordinates 2026-05-09 14:20:43 +02:00
Lightos1
a7c1fe0d27 ldr: clean formating, fix tRC cap, map erista mtc indexes 2026-05-09 13:39:31 +02:00
Souldbminer
33582678c2 Update README.md 2026-05-08 22:44:06 -04:00
souldbminersmwc
3ca1f17e4d hocclk: major code refactor
move everything into its own directory, clean codebase up a lot
2026-05-08 22:43:14 -04:00
souldbminersmwc
65dfa8f48a Update board_fuse.cpp 2026-05-08 16:38:46 -04:00
souldbminersmwc
90ea18c881 hocclk: better HW info reading 2026-05-08 16:36:49 -04:00
souldbminersmwc
598136c64b hocclk: fixes and other stuff 2026-05-08 15:53:53 -04:00
Lightos1
848a788c5f add kip version detection + version mismatch warning 2026-05-08 20:44:28 +02:00
Lightos1
d443e069fd add more stable max index checks 2026-05-08 18:39:01 +02:00
Lightos1
b7e7f0f720 clarify stable struct 2026-05-08 18:18:32 +02:00
Lightos1
916e5c5ddf add stable max index checks 2026-05-08 18:10:32 +02:00
Lightos1
c766ab1569 add stable struct to HocClkContext 2026-05-08 17:58:27 +02:00
Lightos1
9ee4d79f77 Merge pull request #78 from dominatorul/patch-7
Enhance README with more MEM clock entries
2026-05-07 22:41:37 +02:00
Lightos1
d55d1ab319 Merge pull request #77 from th3-ne0undr5c0r/fr,-fr-CA
Add proper French support
2026-05-07 22:39:18 +02:00
Dominator
3be1eb6149 Enhance README with more MEM clock entries
Added additional memory clock values and clarified JEDEC standards.
2026-05-07 19:57:33 +03:00
th3-ne0undr5c0r
5e4f58975c Remove fr-ca support
remove French Canadian support as it is not supported.
2026-05-07 09:31:28 -06:00
th3-ne0undr5c0r
d0c257dbc0 Add proper French support
As title says, adds proper support for French. please keep in mind I have not yet tested/checked whether or not text clipping or formatting issues may be present.
2026-05-07 09:27:38 -06:00
Lightos1
ffb0ded210 Merge pull request #76 from redraz/patch-1
Update ru.json
2026-05-07 16:48:51 +02:00
redraz
396304c738 Update ru.json
I decided to make a proper translation into Russian
2026-05-07 17:04:22 +03:00
Lightos1
8c6baf9e2f add hocVersion to CustomizeTable in sysmodule 2026-05-06 08:56:25 +02:00
Lightos1
a24eec7256 add versioning to kip 2026-05-06 08:54:23 +02:00
Lightos1
77a45966da Revert cust change
This reverts commit 04d7e2f8e0.
2026-05-06 08:49:31 +02:00
Lightos1
04d7e2f8e0 Change cust rev
This now uses the minimum hoc-clk version the kip is compatible with.
2026-05-06 08:43:33 +02:00
souldbminersmwc
f5481d1c00 hocclk: dvfs bracket fix - thanks jotommy! 2026-05-05 15:41:42 -04:00
Lightos1
2e39421074 Refactor tsensor 2026-05-05 20:43:43 +02:00
souldbminersmwc
9cf901d487 Update aotag.hpp 2026-05-04 14:56:48 -04:00
souldbminersmwc
0cdc96f7f8 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-05-04 14:28:26 -04:00
souldbminersmwc
73fafa6337 aotag: fix nvidia Z
nvidia made a error with their driver somehow
2026-05-04 14:28:24 -04:00
Lightos1
cfae441656 fix boost mode exit 2026-05-04 18:33:38 +02:00
souldbminersmwc
bf6bfa3e57 aotag: calculate (hopefully) correct coeffs 2026-05-03 15:44:31 -04:00
souldbminersmwc
72f5e11c42 update aotag coeffs 2026-05-03 14:41:37 -04:00
souldbminersmwc
93b6974be5 Update aotag.cpp 2026-05-03 14:14:14 -04:00
th3-ne0undr5c0r
1f545a7030 Add French Canadian language support
As title says, adds support for French Canadian. please keep in mind I have not yet tested/checked whether or not text clipping or formatting issues may be present.
2026-05-02 23:13:51 -06:00
souldbminersmwc
73bcb384b5 add exosphere patch 2026-05-02 22:11:25 -04:00
souldbminersmwc
fab0b76a35 update binaries 2026-05-02 22:06:57 -04:00
souldbminersmwc
2f830bac53 hocclk: better aotag 2026-05-02 22:05:15 -04:00
souldbminersmwc
5bf7fdf60e Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-05-02 21:11:56 -04:00
souldbminersmwc
af4f00f682 hocclk: basic aotag support along with other changes 2026-05-02 21:11:54 -04:00
Lightos1
d4b09f147b add back emc data that I forgot 2026-05-02 16:17:09 +02:00
Lightos1
1b33e9982c update exosphere patches 2026-05-02 16:16:21 +02:00
souldbminersmwc
c998aa78ae hocclk: update credits 2026-05-02 10:12:42 -04:00
Souldbminer
2b5a27f86e Update README.md 2026-05-02 10:11:14 -04:00
Lightos1
52b1b8da81 fix gpu volt hijack logic 2026-05-01 22:49:19 +02:00
souldbminersmwc
f409f5b8c3 hocclk: dvfs logic refactor
make it a lot more stable
2026-04-30 19:58:48 -04:00
souldbminersmwc
77a7470149 fix clock reset bug
Co-Authored-By: ppkantorski <6467366+ppkantorski@users.noreply.github.com>
2026-04-30 19:36:10 -04:00
souldbminersmwc
1d9fa4c091 Update t210.c 2026-04-30 19:29:15 -04:00
souldbminersmwc
a16cf8a2ef hocclk: significantly reduce memory usage 2026-04-30 19:15:05 -04:00
souldbminersmwc
89418b7cd0 hocclk: some refactoring and commenting 2026-04-30 18:48:57 -04:00
Lightos1
00cf05d9c5 ldr: slightly clean up MemFreqMtcTable 2026-04-29 22:14:27 +02:00
Lightos1
39e7ba6b75 ldr: move R_SKIP after verifying mtc table to avoid triggering patch validations 2026-04-29 21:56:25 +02:00
Lightos1
d7f2cee3b1 Update README.md 2026-04-29 19:08:23 +02:00
Lightos1
3848bd7c83 Update README.md 2026-04-29 19:06:51 +02:00
Lightos1
693954930a remove oc_test 2026-04-29 18:55:14 +02:00
Lightos1
de89768c74 ldr:: panic::SmcError is now always included 2026-04-29 18:39:20 +02:00
Lightos1
8f243c8369 ldr: clean up includes 2026-04-29 18:35:42 +02:00
souldbminersmwc
fd91f376c4 bump version 2026-04-27 19:33:20 -04:00
souldbminersmwc
f0fe114303 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-04-27 19:23:47 -04:00
souldbminersmwc
1c64cf5db8 hocclk: add display color option for aula
this is very very subtle but can def make a difference to your experience
2026-04-27 19:23:44 -04:00
Lightos1
9eea39325d Update about_gui.cpp 2026-04-27 08:52:54 +02:00
Lightos1
9bb6b3383b Update README.md 2026-04-27 08:51:57 +02:00
Lightos1
fb3e976f2e ldr: fix 1333 latency max bug -- index 0 is a valid latency 2026-04-26 22:13:49 +02:00
Lightos1
ec4a1f974b variable should be lowercase 2026-04-25 23:15:39 +02:00
souldbminersmwc
fc4b3b8352 2.1.0 2026-04-25 16:40:55 -04:00
souldbminersmwc
5123f7b1de Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-04-25 16:39:31 -04:00
souldbminersmwc
3251d104c4 hocclk: rename UV tables to correct names 2026-04-25 16:30:10 -04:00
Lightos1
ea2d604c20 fix comment 2026-04-25 22:22:31 +02:00
souldbminersmwc
ae71cd447d ldr: add comment 2026-04-25 16:19:44 -04:00
souldbminersmwc
4261dd83f0 hoc: 133mhz step mode 2026-04-25 16:16:26 -04:00
souldbminersmwc
4dc01c024a hocclk: change capitilization 2026-04-25 15:59:05 -04:00
souldbminersmwc
9e26329173 hocclk: soc max volt dno side voltage 2026-04-25 15:57:37 -04:00
souldbminersmwc
36441e6dea add config support and update build script for soc vmax 2026-04-25 15:44:56 -04:00
Lightos1
cdf28607c9 move loader.json 2026-04-25 20:48:31 +02:00
Lightos1
b383fa7ec2 improve alignment 2026-04-25 20:30:46 +02:00
Lightos1
d7178ddd2c Add soc uncap 2026-04-25 20:22:23 +02:00
souldbminersmwc
9d149f0939 hocclk: fix trackbar reloading issues 2026-04-25 11:20:48 -04:00
souldbminersmwc
170dd79347 hocclk: cpu config rework 2026-04-25 11:06:22 -04:00
souldbminersmwc
d97d359ec2 hocclk: more configurator stuff 2026-04-24 17:00:59 -04:00
souldbminersmwc
9ff9e315a0 hocclk: improve kip saving mechanism 2026-04-24 16:42:59 -04:00
souldbminersmwc
cde560c4bd Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-04-24 16:35:25 -04:00
souldbminersmwc
a15860ba8d hocclk: make dram ti 2026-04-24 16:35:01 -04:00
Lightos1
76e6f1bd27 Merge pull request #71 from dominatorul/patch-4
Update README.md
2026-04-24 17:41:41 +02:00
Lightos1
2c1ad1b755 fix formating 2026-04-24 17:41:21 +02:00
Lightos1
2f2e5e9fb8 add new line 2026-04-24 17:38:28 +02:00
Lightos1
65b77a2d0b make step mode mariko only 2026-04-24 17:34:37 +02:00
Dominator
5d4812bde5 Update README.md
Updated clock specifications for MEM, CPU, and GPU with standardized terms.
2026-04-24 04:24:03 +03:00
souldbminersmwc
addd2de4d9 hocclk: add CPU LUT and add copyright 2026-04-23 18:50:51 -04:00
souldbminersmwc
0df8ce745f use original voltages 2026-04-22 18:06:27 -04:00
souldbminersmwc
62d055f163 hocclk: add missing -35mV step to configurator 2026-04-22 16:58:36 -04:00
souldbminersmwc
fa1510a40d Add B3's low ram freq DVFS
Co-Authored-By: halop <4215938+halop@users.noreply.github.com>
2026-04-22 16:56:09 -04:00
souldbminersmwc
e6942f95e7 hocclk: add BQ24193 temp driver 2026-04-22 16:40:51 -04:00
souldbminersmwc
94b63003ab hocclk: reorder options 2026-04-22 16:14:30 -04:00
souldbminersmwc
8aa20dc0cf hocclk: fix PLL ram mode and default to it 2026-04-22 15:49:07 -04:00
souldbminersmwc
db92c60cd2 hocclk: improve pll ram mode 2026-04-21 20:03:12 -04:00
souldbminersmwc
c8c7b233f5 hocclk: minor refactor 2026-04-21 19:52:31 -04:00
souldbminersmwc
5a9afcbb74 hocmon: rename tabs 2026-04-21 19:48:42 -04:00
souldbminersmwc
8127a0c3b7 hocclk: dram voltage color changes for mariko/erista 2026-04-21 19:48:27 -04:00
souldbminersmwc
7c5e746594 hocclk: ui changes 2026-04-21 19:46:21 -04:00
227 changed files with 17219 additions and 15341 deletions

View File

@@ -7,28 +7,41 @@ BasedOnStyle: LLVM
IndentWidth: 4 IndentWidth: 4
UseTab: Never UseTab: Never
BreakBeforeBraces: Linux # === Struct/Union/Class member indentation ===
# These options control indentation of struct members to ensure consistent
# 4-space indentation for all struct/union/class members
IndentAccessModifiers: false
AccessModifierOffset: 0
NamespaceIndentation: All
IndentPPDirectives: BeforeHash
BreakBeforeBraces: Attach
BraceWrapping: BraceWrapping:
AfterControlStatement: false AfterControlStatement: false
AfterFunction: true AfterFunction: false
AfterClass: false AfterClass: false
AfterStruct: false AfterStruct: false
# AfterStruct: false keeps struct opening brace on same line (K&R style)
# Struct members will still be indented with IndentWidth: 4
AfterUnion: false AfterUnion: false
AfterNamespace: false AfterNamespace: false
AfterEnum: false AfterEnum: false
BeforeCatch: false BeforeCatch: false
BeforeElse: false BeforeElse: false
IndentBraces: false IndentBraces: false
# IndentBraces: false ensures braces themselves are not indented,
# but content inside braces respects IndentWidth setting
ContinuationIndentWidth: 0
AlignAfterOpenBracket: false
AllowShortIfStatementsOnASingleLine: false AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false AllowShortLoopsOnASingleLine: false
AllowShortBlocksOnASingleLine: Always AllowShortBlocksOnASingleLine: Always
IndentCaseLabels: false # AllowShortFunctionsOnASingleLine: None enforces function bodies
SpaceAfterCStyleCast: true # to always be on separate lines, following K&R convention
AllowShortFunctionsOnASingleLine: None AllowShortFunctionsOnASingleLine: None
ColumnLimit: 80
IndentCaseLabels: true
SpaceAfterCStyleCast: false
ColumnLimit: 150
MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 1
Cpp11BracedListStyle: false Cpp11BracedListStyle: false
AlignTrailingComments: true AlignTrailingComments: true
@@ -39,7 +52,9 @@ IncludeBlocks: Regroup
IncludeCategories: IncludeCategories:
- Regex: '<[[:alnum:].]+>' - Regex: '<[[:alnum:].]+>'
Priority: 1 Priority: 1
# System headers (angle brackets) have highest priority
- Regex: '.*' - Regex: '.*'
Priority: 2 Priority: 2
# Project headers (quotes) have lower priority
SortIncludes: CaseSensitive SortIncludes: CaseSensitive
AlignEscapedNewlines: Left AlignEscapedNewlines: Left

View File

@@ -1,12 +1,9 @@
Horizon OC Zeus Compilation Instructions Horizon OC Compilation Instructions
1. Install devkitpro (https://devkitpro.org/wiki/Getting_Started) with switch-dev 1. Install devkitpro (https://devkitpro.org/wiki/Getting_Started) with switch-dev
2. Set up a development enviorment for compiling Atmosphere (https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/building.md) 2. Set up a development enviorment for compiling Atmosphere (https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/building.md)
3. Install GNU make and ENSURE THAT YOUR ENVIORMENT HAS A PYTHON3 COMMAND AVAILABLE! 3. Git clone atmosphere (git clone https://github.com/Atmosphere-NX/Atmosphere.git)
4. Git clone atmosphere (git clone https://github.com/Atmosphere-NX/Atmosphere.git) 4. Clone the Horizon OC develop branch (``git clone https://github.com/Horizon-OC/Horizon-OC.git --recurse-submodules``)
5. Clone the Horizon OC develop branch (git clone -b develop --single-branch https://github.com/Horizon-OC/Horizon-OC.git) 5. Create a new folder named ``build`` in the horizon oc repo
6. Create a new folder named "build" in the horizon oc repo 6. Copy atmosphere files into that build folder
7. Copy atmosphere files into that build folder 7. Run ./build.sh in the root directory
8. Copy Source/Atmosphere/stratosphere/loader/source/ldr_process_creation.cpp to build/stratosphere/loader/source/ldr_process_creation.cpp, replacing any files if prompted
9. Grab a copy of libultrahand (https://github.com/ppkantorski/libultrahand) and place it into Source/sys-clk/overlay/lib/libultrahand
10. Run ./build.sh in the root directory

View File

@@ -11,7 +11,7 @@
![VSCode](https://img.shields.io/badge/VSCode-0078D4?style=for-the-badge\&logo=visual%20studio%20code\&logoColor=white) ![VSCode](https://img.shields.io/badge/VSCode-0078D4?style=for-the-badge\&logo=visual%20studio%20code\&logoColor=white)
![Made with Notepad++](assets/np++.png?raw=true) ![Made with Notepad++](assets/np++.png?raw=true)
![C++](https://img.shields.io/badge/C%2B%2B-00599C?style=for-the-badge\&logo=c%2B%2B\&logoColor=white) ![C++](https://img.shields.io/badge/C%2B%2B-00599C?style=for-the-badge\&logo=c%2B%2B\&logoColor=white)
![Downloads](https://img.shields.io/github/downloads/souldbminersmwc/Horizon-OC/total.svg?style=for-the-badge) ![Downloads](https://img.shields.io/github/downloads/Horizon-OC/Horizon-OC/total.svg?style=for-the-badge)
--- ---
@@ -56,6 +56,7 @@ It enables advanced CPU, GPU, and RAM tuning with user-friendly configuration to
``` ```
kip1=atmosphere/kips/hoc.kip kip1=atmosphere/kips/hoc.kip
secmon=atmosphere/exosphere.bin
``` ```
*(No changes needed if using fusee.)* *(No changes needed if using fusee.)*
@@ -78,21 +79,64 @@ Refer to COMPILATION.md
--- ---
## Clock table ## Clock table
### MEM clocks ### MEM clocks (mhz)
* 3200 → max on mariko, JEDEC. * 3200 → max on mariko, JEDEC.
* 3166
* 3133
* 3100
* 3066
* 3033
* 3000
* 2966
* 2933 → JEDEC. * 2933 → JEDEC.
* 2900
* 2866
* 2833
* 2800
* 2766
* 2733
* 2700
* 2666 → JEDEC. * 2666 → JEDEC.
* 2633
* 2600
* 2566
* 2533
* 2500
* 2466
* 2433
* 2400 → max on erista, JEDEC. * 2400 → max on erista, JEDEC.
* 2133 → mariko safe max (4266 Modules), JEDEC. * 2366
* 1996 → JEDEC. * 2333
* 1866 → mariko safe max (3733 Modules), JEDEC. * 2300
* 1600 → official docked, boost mode, erista safe max, JEDEC. * 2266
* 2233
* 2200
* 2166
* 2133 → Mariko JEDEC standard max (4266 Modules)
* 2100
* 2066
* 2033
* 2000
* 1996 → JEDEC standard
* 1966
* 1933
* 1900
* 1866 → Mariko JEDEC standard max (3733 Modules)
* 1833
* 1800
* 1766
* 1733
* 1700
* 1666
* 1633
* 1600 → official docked, boost mode, Erista JEDEC standard max (3200 Modules), JEDEC.
* 1331 → official handheld, JEDEC. * 1331 → official handheld, JEDEC.
* 1065 * 1065
* 800 * 800
* 665 * 665
### CPU clocks ### CPU clocks (mhz)
* 2703 → mariko absolute max, dangerous * 2703 → mariko absolute max, dangerous
* 2601 → unsafe * 2601 → unsafe
* 2499 * 2499
@@ -115,17 +159,17 @@ Refer to COMPILATION.md
* 714 * 714
* 612 → sleep mode * 612 → sleep mode
### GPU clocks ### GPU clocks (mhz)
* 1536 → absolute max clock on mariko. very dangerous * 1536 → absolute max clock on mariko. very dangerous
* 1459 * 1459
* 1382 * 1382
* 1305 * 1305
* 1267 → NVIDIA T214 rating * 1267 → NVIDIA T214(mariko) rating
* 1228 → mariko HiOPT safe clock * 1228 → mariko High UV safe clock
* 1152 → mariko SLT max clock * 1152 → mariko hiOpt-15mV max clock
* 1075 → mariko no UV max clock. absolute max clock on erista. very dangerous * 1075 → mariko hiOpt max clock. absolute max clock on erista. very dangerous
* 998 → NVIDIA T210 rating * 998 → NVIDIA T210 (erista) rating
* 960 (erista only) → erista slt/hiopt safe max clock * 960 (erista only) → erista high uv/hiOpt-15mV safe max clock
* 921 → erista no UV max clock * 921 → erista no UV max clock
* 844 * 844
* 768 → official docked * 768 → official docked
@@ -142,31 +186,31 @@ Refer to COMPILATION.md
**Notes:** **Notes:**
1. On Erista, CPU in handheld is capped to 1581MHz 1. On Erista, CPU in handheld is capped to 1581MHz
2. GPU overclock is capped at 460MHz on erista in handheld 2. GPU overclock is capped at 460MHz on erista in handheld
3. On Mariko, cap with No uv is 614MHz, with SLT it is 691MHz and with HiOPT it's 768MHz 3. On Mariko, cap with hiOpt is 614MHz, with hiOpt-15mV it is 691MHz and with High UV it's 768MHz
4. Clocks higher than 768MHz on erista need the official charger is plugged in. 4. Clocks higher than 768MHz on erista need the official charger is plugged in.
5. On Mariko, cap with No uv is 844MHz, with SLT it is 921MHz and with HiOPT it's 998MHz
--- ---
## Credits ## Credits
* **Lightos's Cat** - Cat * **Lightos's Cat** - Cat
* **Souldbminer** - hoc-clk and loader development * **Souldbminer** - hoc-clk and loader development
* **Lightos** - Loader patches development, hoc-clk development, guides * **Lightos** - Loader patches development, hoc-clk development, guides
* **TDRR** - HOC Logo Design
* **tetetete-ctrl** - Website design
* **SciresM** - Atmosphere CFW * **SciresM** - Atmosphere CFW
* **CTCaer** - L4T, Hekate, proper RAM timings * **CTCaer** - L4T, Hekate, proper RAM timings
* **KazushiMe** - Switch OC Suite * **KazushiMe** - Switch OC Suite
* **Hanai3bi (Meha)** - Switch OC Suite, EOS, sys-clk-eos * **Hanai3bi (Meha)** - Switch OC Suite, EOS, sys-clk-eos
* **NaGaa95** - L4T-OC kernel, Status Monitor fork * **NaGaa95** - L4T-OC kernel, Status Monitor fork
* **B3711 (halop)** - EOS * **B3711 (halop)** - EOS, contributions
* **sys-clk team (m4xw, p-sam, natinusala)** - sys-clk * **sys-clk team (m4xw, p-sam, natinusala)** - sys-clk
* **Dominatorul** - Soctherm driver, guides, general help * **Dominatorul** - Soctherm driver, guides, general help
* **b0rd2death** - Ultrahand sys-clk & Status Monitor fork * **ppkantorski** - Ultrahand sys-clk & Status Monitor fork
* **MasaGratoR and ZachyCatGames** - General help * **MasaGratoR and ZachyCatGames** - General help
* **MasaGratoR** - Status Monitor & Display Refresh Rate driver * **MasaGratoR** - Status Monitor & Display Refresh Rate driver
* **Dominatorul, Samybigio, Arcdelta, Miki, Happy, Flopsider, Winnerboi77, Blaise, Alvise, TDRR, agjeococh, frost, letum00, and Xenshen** - Testing * **Dominatorul, Samybigio, Arcdelta, Miki, Happy, Winnerboi77, Blaise, Alvise, agjeococh, frost, letum00, and Xenshen** - Testing
* **Samybigio2011, Miki** - Italian translations * **Samybigio2011, Miki** - Italian translations
* **angelblaster** - Korean translations * **angelblaster** - Korean translations
* **q1332348216-glitch** - Chinese translations * **q1332348216-glitch** - Chinese translations
* **th3-ne0undr5c0r** - French translations
* **Nvidia** - [Tegra X1 Technical Reference Manual](https://developer.nvidia.com/embedded/dlc/tegra-x1-technical-reference-manual), soctherm driver, L4T * **Nvidia** - [Tegra X1 Technical Reference Manual](https://developer.nvidia.com/embedded/dlc/tegra-x1-technical-reference-manual), soctherm driver, L4T

View File

@@ -14,9 +14,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define __ACCESS_TABLE_NAME__ EmcAccessTable1 #define __ACCESS_TABLE_NAME__ RtcPmcAccessTable
#define __ACCESS_TABLE_ADDRESS__ MemoryRegionPhysicalDeviceExternalMemoryController1.GetAddress() #define __ACCESS_TABLE_ADDRESS__ MemoryRegionPhysicalDeviceRtcPmc.GetAddress()
#define __ACCESS_TABLE_INC__ "secmon_emc_access_table_data.inc" #define __ACCESS_TABLE_INC__ "secmon_rtc_pmc_access_table_data.inc"
#include "secmon_define_access_table.inc" #include "secmon_define_access_table.inc"

File diff suppressed because it is too large Load Diff

View File

@@ -99,18 +99,16 @@ namespace ams::secmon::smc {
#include "secmon_define_pmc_access_table.inc" #include "secmon_define_pmc_access_table.inc"
#include "secmon_define_mc_access_table.inc" #include "secmon_define_mc_access_table.inc"
#include "secmon_define_emc_access_table.inc" #include "secmon_define_emc_access_table.inc"
#include "secmon_define_emc1_access_table.inc" #include "secmon_define_rtc_pmc_access_table.inc"
#include "secmon_define_emc2_access_table.inc"
#include "secmon_define_mc01_access_table.inc" #include "secmon_define_mc01_access_table.inc"
constexpr const AccessTableEntry AccessTables[] = { constexpr const AccessTableEntry AccessTables[] = {
{ PmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDevicePmc.GetAddress(), PmcAccessTable::Address, PmcAccessTable::Size, }, { PmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDevicePmc.GetAddress(), PmcAccessTable::Address, PmcAccessTable::Size, },
{ McAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceMemoryController.GetAddress(), McAccessTable::Address, McAccessTable::Size, }, { McAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceMemoryController.GetAddress(), McAccessTable::Address, McAccessTable::Size, },
{ EmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceExternalMemoryController.GetAddress(), EmcAccessTable::Address, EmcAccessTable::Size, }, { EmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceExternalMemoryController.GetAddress(), EmcAccessTable::Address, EmcAccessTable::Size, },
{ EmcAccessTable1::ReducedAccessTable.data(), MemoryRegionVirtualDeviceExternalMemoryController1.GetAddress(), EmcAccessTable1::Address, EmcAccessTable1::Size, }, { RtcPmcAccessTable::ReducedAccessTable.data(), MemoryRegionVirtualDeviceRtcPmc.GetAddress(), RtcPmcAccessTable::Address, RtcPmcAccessTable::Size, },
{ EmcAccessTable2::ReducedAccessTable.data(), MemoryRegionVirtualDeviceExternalMemoryController2.GetAddress(), EmcAccessTable2::Address, EmcAccessTable2::Size, }, { Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController0.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController0.GetAddress(), Mc01AccessTable::Size, },
{ Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController0.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController0.GetAddress(), Mc01AccessTable::Size, }, { Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController1.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController1.GetAddress(), Mc01AccessTable::Size, },
{ Mc01AccessTable::ReducedAccessTable.data(), Mc01AccessTable::Address + MemoryRegionVirtualDeviceMemoryController1.GetAddress(), Mc01AccessTable::Address + MemoryRegionPhysicalDeviceMemoryController1.GetAddress(), Mc01AccessTable::Size, },
}; };
constexpr bool IsAccessAllowed(const AccessTableEntry &entry, uintptr_t address) { constexpr bool IsAccessAllowed(const AccessTableEntry &entry, uintptr_t address) {

View File

@@ -0,0 +1,88 @@
{
"name": "Loader",
"title_id": "0x0100000000000001",
"main_thread_stack_size": "0x4000",
"main_thread_priority": 49,
"default_cpu_id": 3,
"process_category": 1,
"use_secure_memory": true,
"immortal": true,
"kernel_capabilities": [
{
"type": "handle_table_size",
"value": 128
},
{
"type": "syscalls",
"value": {
"svcSetHeapSize" : "0x01",
"svcSetMemoryPermission" : "0x02",
"svcSetMemoryAttribute" : "0x03",
"svcMapMemory" : "0x04",
"svcUnmapMemory" : "0x05",
"svcQueryMemory" : "0x06",
"svcExitProcess" : "0x07",
"svcCreateThread" : "0x08",
"svcStartThread" : "0x09",
"svcExitThread" : "0x0A",
"svcSleepThread" : "0x0B",
"svcGetThreadPriority" : "0x0C",
"svcSetThreadPriority" : "0x0D",
"svcGetThreadCoreMask" : "0x0E",
"svcSetThreadCoreMask" : "0x0F",
"svcGetCurrentProcessorNumber" : "0x10",
"svcSignalEvent" : "0x11",
"svcClearEvent" : "0x12",
"svcMapSharedMemory" : "0x13",
"svcUnmapSharedMemory" : "0x14",
"svcCreateTransferMemory" : "0x15",
"svcCloseHandle" : "0x16",
"svcResetSignal" : "0x17",
"svcWaitSynchronization" : "0x18",
"svcCancelSynchronization" : "0x19",
"svcArbitrateLock" : "0x1A",
"svcArbitrateUnlock" : "0x1B",
"svcWaitProcessWideKeyAtomic" : "0x1C",
"svcSignalProcessWideKey" : "0x1D",
"svcGetSystemTick" : "0x1E",
"svcConnectToNamedPort" : "0x1F",
"svcSendSyncRequestLight" : "0x20",
"svcSendSyncRequest" : "0x21",
"svcSendSyncRequestWithUserBuffer" : "0x22",
"svcSendAsyncRequestWithUserBuffer" : "0x23",
"svcGetProcessId" : "0x24",
"svcGetThreadId" : "0x25",
"svcBreak" : "0x26",
"svcOutputDebugString" : "0x27",
"svcReturnFromException" : "0x28",
"svcGetInfo" : "0x29",
"svcWaitForAddress" : "0x34",
"svcSignalToAddress" : "0x35",
"svcSynchronizePreemptionState" : "0x36",
"svcCreateSession" : "0x40",
"svcAcceptSession" : "0x41",
"svcReplyAndReceiveLight" : "0x42",
"svcReplyAndReceive" : "0x43",
"svcReplyAndReceiveWithUserBuffer" : "0x44",
"svcCreateEvent" : "0x45",
"svcReadWriteRegister" : "0x4E",
"svcQueryIoMapping" : "0x55",
"svcSetProcessMemoryPermission" : "0x73",
"svcMapProcessMemory" : "0x74",
"svcUnmapProcessMemory" : "0x75",
"svcMapProcessCodeMemory" : "0x77",
"svcUnmapProcessCodeMemory" : "0x78",
"svcCreateProcess" : "0x79",
"svcCallSecureMonitor" : "0x7F"
}
}, {
"type": "map",
"value": {
"address": "0x7000F000",
"is_ro": false,
"size": "0x00001000",
"is_io": true
}
}
]
}

View File

@@ -1,51 +0,0 @@
TARGET_EXEC := test
BUILD_DIR := ./build
SRC_DIRS := ./
# CXX := clang++ g++-12
# Find all the C and C++ files we want to compile
# Note the single quotes around the * expressions. Make will incorrectly expand these otherwise.
SRCS := $(shell find $(SRC_DIRS) -name '*.cpp' -or -name '*.c' -or -name '*.s')
# String substitution for every C/C++ file.
# As an example, hello.cpp turns into ./build/hello.cpp.o
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
# String substitution (suffix version without %).
# As an example, ./build/hello.cpp.o turns into ./build/hello.cpp.d
DEPS := $(OBJS:.o=.d)
# Every folder in ./src will need to be passed to GCC so that it can find header files
INC_DIRS := $(shell find $(SRC_DIRS) -type d)
# Add a prefix to INC_DIRS. So moduleA would become -ImoduleA. GCC understands this -I flag
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
CPPFLAGS := $(INC_FLAGS) -Wall -Werror -Wno-unused-result -std=c++20 -Og -g
# The final build step.
$(TARGET_EXEC): $(OBJS)
@echo "Linking $@"
@$(CXX) $(OBJS) -o $@ $(LDFLAGS)
# Build step for C source
$(BUILD_DIR)/%.c.o: %.c
@mkdir -p $(dir $@)
@echo "$<"
@$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
# Build step for C++ source
$(BUILD_DIR)/%.cpp.o: %.cpp
@mkdir -p $(dir $@)
@echo "$<"
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
.PHONY: clean
clean:
@rm -r $(BUILD_DIR) $(TARGET_EXEC)
# Include the .d makefiles. The - at the front suppresses the errors of missing
# Makefiles. Initially, all the .d files will be missing, and we don't want those
# errors to show up.
-include $(DEPS)

View File

@@ -37,27 +37,27 @@ volatile CustomizeTable C = {
.commonEmcMemVolt = 1175000, /* LPDDR4(X) JEDEC Specification */ .commonEmcMemVolt = 1175000, /* LPDDR4(X) JEDEC Specification */
.eristaEmcMaxClock = 1600000, /* Maximum HB-MGCH ram rating */ .eristaEmcMaxClock = 1600000, /* Maximum HB-MGCH ram rating */
.eristaEmcMaxClock1 = 1600000,
.eristaEmcMaxClock2 = 1600000,
/* Available: 66MHz step rate, 100MHz step rate and jedec. */ /* Available: 66MHz step rate, 100MHz step rate, 133MHz step rate and jedec. */
/* Jedec freqs are 1333MHz, 1600MHz, 1866MHz, 2133MHz, 2400MHz, 2666MHz, 2933MHz, 3200MHz. */ /* Jedec freqs are 1333MHz, 1600MHz, 1866MHz, 2133MHz, 2400MHz, 2666MHz, 2933MHz, 3200MHz. */
.stepMode = StepMode_66MHz, .stepMode = StepMode_66MHz,
.marikoEmcMaxClock = 2133000, /* 1866MHz @ 1866tWRL is guaranteed to work on all Mariko units */ .marikoEmcMaxClock = 2133000, /* 1866MHz @ 1866tWRL is guaranteed to work on all Mariko units */
.marikoEmcVddqVolt = 600000, .marikoEmcVddqVolt = 600000,
.emcDvbShift = 0,
// Primary .emcDvbShift = 0,
.t1_tRCD = 0, .marikoSocVmax = 0, /* 0 = stock limits (1450 - 1597 is 1050mV, 1598-1708 is 1025mV, 1709+ is 1000mV). */
.t2_tRP = 0,
.t3_tRAS = 0, /* Primary. */
// Secondary .t1_tRCD = 0,
.t4_tRRD = 0, .t2_tRP = 0,
.t5_tRFC = 0, .t3_tRAS = 0,
.t6_tRTW = 0, /* Secondary. */
.t7_tWTR = 0, .t4_tRRD = 0,
.t8_tREFI = 0, .t5_tRFC = 0,
.t6_tRTW = 0,
.t7_tWTR = 0,
.t8_tREFI = 0,
/* At 1333WL, for some reason (incorrect ram timing config in mtc table?), tRP causes crashes at high reductions - 2 seems to be the most common limit. */ /* At 1333WL, for some reason (incorrect ram timing config in mtc table?), tRP causes crashes at high reductions - 2 seems to be the most common limit. */
/* This is a lazy workaround until I find the issue... */ /* This is a lazy workaround until I find the issue... */
@@ -65,54 +65,38 @@ volatile CustomizeTable C = {
/* Frequency where non low timings gets used. */ /* Frequency where non low timings gets used. */
.timingEmcTbreak = DISABLED, .timingEmcTbreak = DISABLED,
.low_t6_tRTW = DISABLED, .low_t6_tRTW = 0,
.low_t7_tWTR = DISABLED, .low_t7_tWTR = 0,
.readLatency = { .readLatency = {
DISABLED, /* 1333 */ 0,
DISABLED, /* 1600 */ 0,
DISABLED, /* 1866 */ 0,
DISABLED, /* 2133 */ 0,
}, },
.writeLatency = { .writeLatency = {
DISABLED, /* 1333 */ 0,
DISABLED, /* 1600 */ 0,
DISABLED, /* 1866 */ 0,
DISABLED, /* 2133 */ 0,
}, },
/* You can mix and match different latencies if needed */ .eristaCpuUV = 0,
/* .eristaCpuVmin = 800,
* Read:
* 2133RL = 40
* 1866RL = 36
* 1600RL = 32
* 1331RL = 28
* Write:
* 2133WL = 18
* 1866WL = 16
* 1600WL = 14
* 1331WL = 12
*/
.mem_burst_read_latency = RL_1600,
.mem_burst_write_latency = WL_1600,
.eristaCpuUV = 0,
.eristaCpuVmin = 800,
.eristaCpuMaxVolt = 1200, .eristaCpuMaxVolt = 1200,
/* Unlocks up to 2397 Mhz CPU, usage is not recommended. */ /* Unlocks up to 2397 Mhz CPU, usage is not recommended. */
.eristaCpuUnlock = DISABLED, .eristaCpuUnlock = DISABLED,
.marikoCpuUVLow = 0, // No undervolt .marikoCpuUVLow = 0, // No undervolt
.marikoCpuUVHigh = 0, // No undervolt .marikoCpuUVHigh = 0, // No undervolt
.tableConf = TBREAK_1683, .tableConf = TBREAK_1683,
.marikoCpuLowVmin = 620, .marikoCpuLowVmin = 620,
.marikoCpuHighVmin = 750, .marikoCpuHighVmin = 750,
/* 1120mV is NVIDIA rating */ /* 1120mV is NVIDIA rating */
.marikoCpuMaxVolt = 1120, .marikoCpuMaxVolt = 1120,
/* Supported values: 1963500, 2091000, 2193000, 2295000, 2397000, 2499000, 2601000, 2703000. */ /* Supported values: 1963500, 2091000, 2193000, 2295000, 2397000, 2499000, 2601000, 2703000. */
/* 1963500 is official rating of T214/Mariko, fully safe. */ /* 1963500 is official rating of T214/Mariko, fully safe. */
@@ -123,29 +107,24 @@ volatile CustomizeTable C = {
/* 2703000 is potentially dangerous and not advised. */ /* 2703000 is potentially dangerous and not advised. */
.marikoCpuMaxClock = 1963500, .marikoCpuMaxClock = 1963500,
.eristaCpuBoostClock = 1785000, // Default boost clock .eristaCpuBoostClock = 1785000, /* Default boost clock */
.marikoCpuBoostClock = 1963500, // Default boost clock .marikoCpuBoostClock = 1963500, /* Default boost clock */
.eristaGpuUV = 0, .eristaGpuUV = 0,
.eristaGpuVmin = 810, .eristaGpuVmin = 810,
.marikoGpuUV = 0, .marikoGpuUV = 2,
/* Vmin past 795mV won't work due boot voltage being 800mV (can be adjusted though). */
/* Vmin past 795mV won't work due boot voltage being 800mV. */
.marikoGpuVmin = 610, .marikoGpuVmin = 610,
.marikoGpuBootVolt = 800, /* Used during boot and when temp is <20°C */
.marikoGpuVmax = 800, .marikoGpuVmax = 800,
.commonGpuVoltOffset = 0, .commonGpuVoltOffset = 0,
/* Speedo is automatically set by hoc-clk on first boot */
.gpuSpeedo = 1450,
/* Setting DEACTIVATED_GPU_FREQ on any freq will disable it and all freqs greater than it. (the latter is a bug :/) */ /* Setting DEACTIVATED_GPU_FREQ on any freq will disable it and all freqs greater than it. (the latter is a bug :/) */
/* AUTO: Voltage is optimally chosen; with commonGpuVoltOffset applied. */ /* AUTO: Voltage is optimally chosen; with commonGpuVoltOffset applied. */
/* AUTO only works up to 1305 GPU on Mariko and 998 GPU on Erista (it is reccomended to manually set your 998MHz voltage though) */ /* AUTO only works up to 1305 GPU on Mariko and 998 GPU on Erista (it is reccomended to manually set your 998MHz voltage though) */
/* You can overwrite auto with any voltage (in mv) of your choice - offset will not be applied. */ /* You can overwrite auto with any voltage (in mv) of your choice - offset will not be applied. */
.eristaGpuVoltArray = { .eristaGpuVoltArray = {
AUTO /* 76 */, AUTO /* 76 */,
AUTO /* 115 */, AUTO /* 115 */,
@@ -478,6 +457,47 @@ volatile CustomizeTable C = {
}, },
.marikoGpuDvfsTable = { .marikoGpuDvfsTable = {
{ 76800, {}, { 610000, } },
{ 153600, {}, { 610000, } },
{ 230400, {}, { 610000, } },
{ 307200, {}, { 610000, } },
{ 384000, {}, { 610000, } },
{ 460800, {}, { 610000, } },
{ 537600, {}, { 801688, -10900, -163, 298, -10599, 162 } },
{ 614400, {}, { 824214, -5743, -452, 238, -6325, 81 } },
{ 691200, {}, { 848830, -3903, -552, 119, -4030, -2 } },
{ 768000, {}, { 891575, -4409, -584, 0, -2849, 39 } },
{ 844800, {}, { 940071, -5367, -602, -60, -63, -93 } },
{ 921600, {}, { 986765, -6637, -614, -179, 1905, -13 } },
{ 998400, {}, { 1098475, -13529, -497, -179, 3626, 9 } },
// { 1075200, {}, { 1163644, -12688, -648, 0, 1077, 40 } },
// { 1152000, {}, { 1204812, -9908, -830, 0, 1469, 110 } },
// { 1228800, {}, { 1277303, -11675, -859, 0, 3722, 313 } },
// { 1267200, {}, { 1335531, -12567, -867, 0, 3681, 559 } },
// { 1305600, {}, { 1374130, -13725, -859, 0, 4442, 576 } },
},
.marikoGpuDvfsTableSLT = {
{ 76800, {}, { 590000, } },
{ 153600, {}, { 590000, } },
{ 230400, {}, { 590000, } },
{ 307200, {}, { 590000, } },
{ 384000, {}, { 590000, } },
{ 460800, {}, { 795089, -11096, -163, 298, -10421, 162 } },
{ 537600, {}, { 795089, -11096, -163, 298, -10421, 162 } },
{ 614400, {}, { 820606, -6285, -452, 238, -6182, 81 } },
{ 691200, {}, { 846289, -4565, -552, 119, -3958, -2 } },
{ 768000, {}, { 888720, -5110, -584, 0, -2849, 39 } },
{ 844800, {}, { 936634, -6089, -602, -60, -99, -93 } },
{ 921600, {}, { 982562, -7373, -614, -179, 1797, -13 } },
{ 998400, {}, { 1090179, -14125, -497, -179, 3518, 9 } },
{ 1075200, {}, { 1155798, -13465, -648, 0, 1077, 40 } },
// { 1152000, {}, { 1198568, -10904, -830, 0, 1469, 110 } },
// { 1228800, {}, { 1269988, -12707, -859, 0, 3722, 313 } },
// { 1267200, {}, { 1308155, -13694, -867, 0, 3681, 559 } },
},
.marikoGpuDvfsTableHiOPT = {
{ 76800, { }, { GPU_MIN_MIN_VOLT, } }, { 76800, { }, { GPU_MIN_MIN_VOLT, } },
{ 153600, { }, { GPU_MIN_MIN_VOLT, } }, { 153600, { }, { GPU_MIN_MIN_VOLT, } },
{ 230400, { }, { GPU_MIN_MIN_VOLT, } }, { 230400, { }, { GPU_MIN_MIN_VOLT, } },
@@ -492,12 +512,12 @@ volatile CustomizeTable C = {
{ 921600, { }, { 970060,-10108, -614,-179, 1508, -13 } }, { 921600, { }, { 970060,-10108, -614,-179, 1508, -13 } },
{ 998400, { }, { 1065665,-16075, -497,-179, 3213, 9 } }, { 998400, { }, { 1065665,-16075, -497,-179, 3213, 9 } },
{ 1075200, { }, { 1132576,-16093, -648, 0, 1077, 40 } }, { 1075200, { }, { 1132576,-16093, -648, 0, 1077, 40 } },
// { 1152000, { }, { 1180029,-14534, -830, 0, 1469, 110 } }, { 1152000, { }, { 1180029,-14534, -830, 0, 1469, 110 } },
// { 1228800, { }, { 1248293,-16383, -859, 0, 3722, 313 } }, // { 1228800, { }, { 1248293,-16383, -859, 0, 3722, 313 } },
// { 1267200, { }, { 1286399,-17475, -867, 0, 3681, 559 } }, // { 1267200, { }, { 1286399,-17475, -867, 0, 3681, 559 } },
}, },
.marikoGpuDvfsTableSLT = { .marikoGpuDvfsTableHiOPT15 = {
{ 76800, { }, { GPU_MIN_MIN_VOLT, } }, { 76800, { }, { GPU_MIN_MIN_VOLT, } },
{ 153600, { }, { GPU_MIN_MIN_VOLT, } }, { 153600, { }, { GPU_MIN_MIN_VOLT, } },
{ 230400, { }, { GPU_MIN_MIN_VOLT, } }, { 230400, { }, { GPU_MIN_MIN_VOLT, } },
@@ -513,11 +533,11 @@ volatile CustomizeTable C = {
{ 998400, { }, { 1065665, -16075, -497, -179, 3213, 9 } }, { 998400, { }, { 1065665, -16075, -497, -179, 3213, 9 } },
{ 1075200, { }, { 1132576, -16093, -648, 0, 1077, 40 } }, { 1075200, { }, { 1132576, -16093, -648, 0, 1077, 40 } },
{ 1152000, { }, { 1180029, -14534, -830, 0, 1469, 110 } }, { 1152000, { }, { 1180029, -14534, -830, 0, 1469, 110 } },
{ 1228800, { }, { 1238293, -16383, -859, 0, 3722, 313 } }, // { 1228800, { }, { 1238293, -16383, -859, 0, 3722, 313 } },
// { 1267200, { }, { 1276399, -17475, -867, 0, 3681, 559 } }, // { 1267200, { }, { 1276399, -17475, -867, 0, 3681, 559 } },
}, },
.marikoGpuDvfsTableHiOPT = { .marikoGpuDvfsTableHighUV = {
{ 76800, { }, { GPU_MIN_MIN_VOLT, } }, { 76800, { }, { GPU_MIN_MIN_VOLT, } },
{ 153600, { }, { GPU_MIN_MIN_VOLT, } }, { 153600, { }, { GPU_MIN_MIN_VOLT, } },
{ 230400, { }, { GPU_MIN_MIN_VOLT, } }, { 230400, { }, { GPU_MIN_MIN_VOLT, } },

View File

@@ -20,19 +20,18 @@
#pragma once #pragma once
#define CUST_REV 2 #define CUST_REV 4
#define KIP_VERSION 240
#include "oc_common.hpp" #include "oc_common.hpp"
#include "pcv/pcv_common.hpp" #include "pcv/pcv_common.hpp"
namespace ams::ldr::hoc { namespace ams::ldr::hoc {
#include "mtc_timing_table.hpp"
enum TableConfig: u32 { enum TableConfig: u32 {
DEFAULT_TABLE = 1, DEFAULT_TABLE = 1,
TBREAK_1581 = 2, TBREAK_1581 = 2,
TBREAK_1683 = 3, TBREAK_1683 = 3,
EXTREME_TABLE = 4, EXTREME_TABLE = 4,
}; };
@@ -40,21 +39,9 @@ enum StepMode: u32 {
StepMode_66MHz = 0, StepMode_66MHz = 0,
StepMode_100MHz = 1, StepMode_100MHz = 1,
StepMode_Jedec = 2, StepMode_Jedec = 2,
StepMode_133MHz = 3,
}; };
/*
* Read:
* 2133RL = 40
* 1866RL = 36
* 1600RL = 32
* 1331RL = 28
* Write:
* 2133WL = 18
* 1866WL = 16
* 1600WL = 14
* 1331WL = 12
*/
enum ReadLatency: u32 { enum ReadLatency: u32 {
RL_2133 = 40, RL_2133 = 40,
RL_1866 = 36, RL_1866 = 36,
@@ -74,25 +61,21 @@ using CustomizeGpuDvfsTable = pcv::cvb_entry_t[pcv::DvfsTableEntryLimit];
static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(CustomizeGpuDvfsTable)); static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(CustomizeGpuDvfsTable));
static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(pcv::cvb_entry_t) * pcv::DvfsTableEntryLimit); static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(pcv::cvb_entry_t) * pcv::DvfsTableEntryLimit);
constexpr uint32_t ERISTA_MTC_MAGIC = 0x43544D45; // EMTC struct CustomizeTable {
constexpr uint32_t MARIKO_MTC_MAGIC = 0x43544D4D; // MMTC u8 cust[4] = {'C', 'U', 'S', 'T'};
u32 custRev = CUST_REV;
u32 kipVersion = KIP_VERSION;
typedef struct CustomizeTable {
u8 cust[4] = {'C', 'U', 'S', 'T'};
u32 custRev = CUST_REV;
u32 placeholder;
u32 hpMode; u32 hpMode;
u32 commonEmcMemVolt; u32 commonEmcMemVolt;
u32 eristaEmcMaxClock; u32 eristaEmcMaxClock;
u32 eristaEmcMaxClock1;
u32 eristaEmcMaxClock2;
StepMode stepMode; StepMode stepMode;
u32 marikoEmcMaxClock; u32 marikoEmcMaxClock;
u32 marikoEmcVddqVolt; u32 marikoEmcVddqVolt;
u32 emcDvbShift; s32 emcDvbShift;
u32 marikoSocVmax;
// advanced config // advanced config
u32 t1_tRCD; u32 t1_tRCD;
u32 t2_tRP; u32 t2_tRP;
@@ -112,9 +95,6 @@ typedef struct CustomizeTable {
u32 readLatency[4]; u32 readLatency[4];
u32 writeLatency[4]; u32 writeLatency[4];
u32 mem_burst_read_latency;
u32 mem_burst_write_latency;
u32 eristaCpuUV; u32 eristaCpuUV;
u32 eristaCpuVmin; u32 eristaCpuVmin;
u32 eristaCpuMaxVolt; u32 eristaCpuMaxVolt;
@@ -136,11 +116,10 @@ typedef struct CustomizeTable {
u32 marikoGpuUV; u32 marikoGpuUV;
u32 marikoGpuVmin; u32 marikoGpuVmin;
u32 marikoGpuBootVolt;
u32 marikoGpuVmax; u32 marikoGpuVmax;
u32 commonGpuVoltOffset; s32 commonGpuVoltOffset;
u32 gpuSpeedo;
u32 eristaGpuVoltArray[27]; u32 eristaGpuVoltArray[27];
u32 marikoGpuVoltArray[24]; u32 marikoGpuVoltArray[24];
@@ -166,8 +145,10 @@ typedef struct CustomizeTable {
CustomizeGpuDvfsTable marikoGpuDvfsTable; CustomizeGpuDvfsTable marikoGpuDvfsTable;
CustomizeGpuDvfsTable marikoGpuDvfsTableSLT; CustomizeGpuDvfsTable marikoGpuDvfsTableSLT;
CustomizeGpuDvfsTable marikoGpuDvfsTableHiOPT; CustomizeGpuDvfsTable marikoGpuDvfsTableHiOPT;
CustomizeGpuDvfsTable marikoGpuDvfsTableHiOPT15;
CustomizeGpuDvfsTable marikoGpuDvfsTableHighUV;
} CustomizeTable; };
extern volatile CustomizeTable C; extern volatile CustomizeTable C;

View File

@@ -14,16 +14,126 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stratosphere.hpp>
#include "../mtc_timing_value.hpp" #include "../mtc_timing_value.hpp"
namespace ams::ldr::hoc::pcv::erista { namespace ams::ldr::hoc::pcv::erista {
void CalculateTimings(double tCK_avg) { void SwitchLatency(volatile u32 &latency, u32 index, u32 latencyStep) {
tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL - (C.t6_tRTW * 3) + finetRTW; latency += index * latencyStep;
}
static s32 GetMaxLatencyIndex(volatile u32 *latencyArray, u32 latencySize) {
s32 maxIndex = -1;
for (u32 i = 0; i < latencySize; ++i) {
if (latencyArray[i]) {
maxIndex = i;
}
}
return maxIndex;
}
void AutoLatency(volatile u32 &latency, u32 freq, u32 latencyStep) {
if (freq > 1600'000 && freq <= 1866'000) { /* 1866tRWL */
latency += latencyStep * 2;
} else { /* 2133tRWL */
latency += latencyStep * 3;
}
}
void HandleLatency(u32 freq, volatile u32 &latency, volatile u32 *latencyArray, u32 indexMax, u32 latencyStep) {
for (u32 i = 0; i <= indexMax; ++i) {
if (latencyArray[i] != 0 && freq <= latencyArray[i]) {
SwitchLatency(latency, i, latencyStep);
return;
}
}
SwitchLatency(latency, indexMax, latencyStep);
}
void HandleLatency(u32 freq) {
static s32 rlIndexMax = GetMaxLatencyIndex(C.readLatency, std::size(C.readLatency));
static s32 wlIndexMax = GetMaxLatencyIndex(C.writeLatency, std::size(C.writeLatency));
constexpr u32 ReadLatencyStep = 4;
constexpr u32 WriteLatencyStep = 2;
bool autoLatencyRead = false, autoLatencyWrite = false;
if (rlIndexMax == -1) {
AutoLatency(RL, freq, ReadLatencyStep);
autoLatencyRead = true;
}
if (wlIndexMax == -1) {
AutoLatency(WL, freq, WriteLatencyStep);
autoLatencyWrite = true;
}
if (autoLatencyRead && autoLatencyWrite) {
return;
}
if (!autoLatencyRead) {
HandleLatency(freq, RL, C.readLatency, rlIndexMax, ReadLatencyStep);
}
if (!autoLatencyWrite) {
HandleLatency(freq, WL, C.writeLatency, wlIndexMax, WriteLatencyStep);
}
}
void CalculateMrw2() {
static const u8 rlMapDBI[8] = {
6, 12, 16, 22, 28, 32, 36, 40
};
static const u8 wlMapSetA[8] = {
4, 6, 8, 10, 12, 14, 16, 18
};
u32 rlIndex = 0;
u32 wlIndex = 0;
for (u32 i = 0; i < std::size(rlMapDBI); ++i) {
if (rlMapDBI[i] == 32) {
rlIndex = i;
break;
}
}
for (u32 i = 0; i < std::size(wlMapSetA); ++i) {
if (wlMapSetA[i] == WL) {
wlIndex = i;
break;
}
}
/* DBI is always enabled. */
mrw2 = static_cast<u8>(((rlIndex & 0x7) | ((wlIndex & 0x7) << 3) | ((0 & 0x1) << 6)));
}
void CalculateTimings(double tCK_avg, u32 freq) {
RL = RL_1331;
WL = WL_1331;
HandleLatency(freq);
CalculateMrw2();
tR2P = CEIL((RL * 0.426) - 2.0);
tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL - (C.t6_tRTW * 3) + finetRTW;
tW2P = (CEIL(WL * 1.7303) * 2) - 5;
tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL + (2.694 / tCK_avg), static_cast<double>(tW2P))) + (BL / 2)); tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL + (2.694 / tCK_avg), static_cast<double>(tW2P))) + (BL / 2));
tW2R = FLOOR(MAX((5.020 / tCK_avg) + 1.130, WL - MAX(-CEIL(0.258 * (WL - RL)), 1.964)) * 1.964) + WL - CEIL(tWTR / tCK_avg) + finetWTR; tW2R = FLOOR(MAX((5.020 / tCK_avg) + 1.130, WL - MAX(-CEIL(0.258 * (WL - RL)), 1.964)) * 1.964) + WL - CEIL(tWTR / tCK_avg) + finetWTR;
wdv = WL;
wsv = WL - 2;
wev = 0xA + (WL - 14);
u32 obdlyHigh = 3 / FLOOR(MIN(static_cast<double>(2), tCK_avg * (WL - 7)));
u32 obdlyLow = MAX(WL - FLOOR((126.0 / CEIL(tCK_avg + 8.601))), 0.0);
obdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(obdlyHigh, obdlyLow);
pdex2rw = CEIL((CEIL(12.335 - tCK_avg) + (7.430 / tCK_avg) - CEIL(tCK_avg * 11.361))); pdex2rw = CEIL((CEIL(12.335 - tCK_avg) + (7.430 / tCK_avg) - CEIL(tCK_avg * 11.361)));
tCLKSTOP = FLOOR(MIN(8.488 / tCK_avg, 23.0)) + 8.0; tCLKSTOP = FLOOR(MIN(8.488 / tCK_avg, 23.0)) + 8.0;

View File

@@ -18,6 +18,6 @@
namespace ams::ldr::hoc::pcv::erista { namespace ams::ldr::hoc::pcv::erista {
void CalculateTimings(double tCK_avg); void CalculateTimings(double tCK_avg, u32 freq);
} }

View File

@@ -26,16 +26,16 @@ namespace ams::ldr::hoc::pcv::mariko {
return; return;
} }
/* Fallback. */ /* > 3200 */
rext = 0x1A; rext = 0x1E;
} }
void SwitchLatency(volatile u32 &latency, u32 index, u32 latencyStep) { void SwitchLatency(volatile u32 &latency, u32 index, u32 latencyStep) {
latency += index * latencyStep; latency += index * latencyStep;
} }
static u32 GetMaxLatencyIndex(volatile u32 *latencyArray, u32 latencySize) { static s32 GetMaxLatencyIndex(volatile u32 *latencyArray, u32 latencySize) {
u32 maxIndex = 0; s32 maxIndex = -1;
for (u32 i = 0; i < latencySize; ++i) { for (u32 i = 0; i < latencySize; ++i) {
if (latencyArray[i]) { if (latencyArray[i]) {
maxIndex = i; maxIndex = i;
@@ -46,7 +46,7 @@ namespace ams::ldr::hoc::pcv::mariko {
} }
void AutoLatency(volatile u32 &latency, u32 freq, u32 latencyStep) { void AutoLatency(volatile u32 &latency, u32 freq, u32 latencyStep) {
if (freq > 1600'000 && freq <= 1866'000) { /* 1866tRWL */ if (freq > 1600'000 && freq <= 1862'400) { /* 1866tRWL */
latency += latencyStep * 2; latency += latencyStep * 2;
} else { /* 2133tRWL */ } else { /* 2133tRWL */
latency += latencyStep * 3; latency += latencyStep * 3;
@@ -65,18 +65,18 @@ namespace ams::ldr::hoc::pcv::mariko {
} }
void HandleLatency(u32 freq) { void HandleLatency(u32 freq) {
static u32 rlIndexMax = GetMaxLatencyIndex(C.readLatency, std::size(C.readLatency)); static s32 rlIndexMax = GetMaxLatencyIndex(C.readLatency, std::size(C.readLatency));
static u32 wlIndexMax = GetMaxLatencyIndex(C.writeLatency, std::size(C.writeLatency)); static s32 wlIndexMax = GetMaxLatencyIndex(C.writeLatency, std::size(C.writeLatency));
constexpr u32 ReadLatencyStep = 4; constexpr u32 ReadLatencyStep = 4;
constexpr u32 WriteLatencyStep = 2; constexpr u32 WriteLatencyStep = 2;
bool autoLatencyRead = false, autoLatencyWrite = false; bool autoLatencyRead = false, autoLatencyWrite = false;
if (rlIndexMax == 0) { if (rlIndexMax == -1) {
AutoLatency(RL, freq, ReadLatencyStep); AutoLatency(RL, freq, ReadLatencyStep);
autoLatencyRead = true; autoLatencyRead = true;
} }
if (wlIndexMax == 0) { if (wlIndexMax == -1) {
AutoLatency(WL, freq, WriteLatencyStep); AutoLatency(WL, freq, WriteLatencyStep);
autoLatencyWrite = true; autoLatencyWrite = true;
} }
@@ -120,6 +120,7 @@ namespace ams::ldr::hoc::pcv::mariko {
} }
} }
/* DBI is always enabled. */
mrw2 = static_cast<u8>(((rlIndex & 0x7) | ((wlIndex & 0x7) << 3) | ((0 & 0x1) << 6))); mrw2 = static_cast<u8>(((rlIndex & 0x7) | ((wlIndex & 0x7) << 3) | ((0 & 0x1) << 6)));
} }
@@ -138,27 +139,27 @@ namespace ams::ldr::hoc::pcv::mariko {
tRPpbIndex = MIN(C.t2_tRP_cap, C.t2_tRP); tRPpbIndex = MIN(C.t2_tRP_cap, C.t2_tRP);
} }
tRCD = tRCD_values[C.t1_tRCD]; tRCD = tRCD_values[C.t1_tRCD];
tRPpb = tRP_values[tRPpbIndex]; tRPpb = tRP_values[tRPpbIndex];
tRAS = tRAS_values[C.t3_tRAS]; tRAS = tRAS_values[C.t3_tRAS];
tRRD = tRRD_values[C.t4_tRRD]; tRRD = tRRD_values[C.t4_tRRD];
tRFCpb = tRFC_values[C.t5_tRFC]; tRFCpb = tRFC_values[C.t5_tRFC];
u32 tRTW = C.t6_tRTW; u32 tRTW = C.t6_tRTW;
u32 tWTR = 10 - tWTR_values[C.t7_tWTR]; u32 tWTR = 10 - tWTR_values[C.t7_tWTR];
if (freq < C.timingEmcTbreak) { if (freq < C.timingEmcTbreak) {
tRTW = C.low_t6_tRTW; tRTW = C.low_t6_tRTW;
tWTR = 10 - tWTR_values[C.low_t7_tWTR]; tWTR = 10 - tWTR_values[C.low_t7_tWTR];
} }
s32 finetRTW = C.fineTune_t6_tRTW; s32 finetRTW = C.fineTune_t6_tRTW;
s32 finetWTR = C.fineTune_t7_tWTR; s32 finetWTR = C.fineTune_t7_tWTR;
tRC = tRAS + tRPpb; tRC = tRAS + tRPpb;
tRFCab = tRFCpb * 2; tRFCab = tRFCpb * 2;
tXSR = static_cast<double>(tRFCab + 7.5); tXSR = static_cast<double>(tRFCab + 7.5);
tFAW = static_cast<u32>(tRRD * 4.0); tFAW = static_cast<u32>(tRRD * 4.0);
tRPab = tRPpb + 3; tRPab = tRPpb + 3;
tR2P = CEIL((RL * 0.426) - 2.0); tR2P = CEIL((RL * 0.426) - 2.0);
tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL - (tRTW * 3) + finetRTW; tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL - (tRTW * 3) + finetRTW;

View File

@@ -14,7 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../mtc_timing_value.hpp" #include "../oc_common.hpp"
#include "timing_tables.hpp" #include "timing_tables.hpp"
namespace ams::ldr::hoc::pcv::mariko { namespace ams::ldr::hoc::pcv::mariko {

View File

@@ -15,7 +15,7 @@
*/ */
#pragma once #pragma once
#include "../mtc_timing_value.hpp" #include <stratosphere.hpp>
namespace ams::ldr::hoc::pcv::mariko { namespace ams::ldr::hoc::pcv::mariko {

View File

@@ -33,10 +33,6 @@ namespace ams::ldr::hoc {
/* Burst latency, not to be confused with base latency (tWRL). */ /* Burst latency, not to be confused with base latency (tWRL). */
const u32 BL = 16; const u32 BL = 16;
/* Base latency for read and write (tWRL). */
const u32 RL = C.mem_burst_read_latency;
const u32 WL = C.mem_burst_write_latency;
/* Precharge to Precharge Delay. (tCK) */ /* Precharge to Precharge Delay. (tCK) */
const u32 tPPD = 4; const u32 tPPD = 4;
@@ -87,19 +83,30 @@ namespace ams::ldr::hoc {
const u32 tFAW = static_cast<u32>(tRRD * 4.0); const u32 tFAW = static_cast<u32>(tRRD * 4.0);
const double tRPab = tRPpb + 3; const double tRPab = tRPpb + 3;
const u32 tR2P = CEIL((RL * 0.426) - 2.0); inline u32 RL;
inline u32 WL;
inline u32 tR2P;
inline u32 tR2W; inline u32 tR2W;
inline u32 rext; inline u32 rext;
const u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5; inline u32 tW2P;
inline u32 tWTPDEN; inline u32 tWTPDEN;
inline u32 tW2R; inline u32 tW2R;
inline u32 wdv;
inline u32 wsv;
inline u32 wev;
inline u32 obdly;
inline u32 pdex2rw; inline u32 pdex2rw;
inline u32 tCLKSTOP; inline u32 tCLKSTOP;
inline double pdex2mrr; inline double pdex2mrr;
inline u8 mrw2;
} }
namespace pcv::mariko { namespace pcv::mariko {

View File

@@ -18,17 +18,16 @@
#pragma once #pragma once
#ifdef ATMOSPHERE_IS_STRATOSPHERE #include <stratosphere.hpp>
#include <stratosphere.hpp> #include <vapours/results/results_common.hpp>
#include <vapours/results/results_common.hpp> #define LOGGING(fmt, ...) ((void)0)
#define LOGGING(fmt, ...) ((void)0) #define CRASH(msg, ...) { ams::diag::AbortImpl(msg, __PRETTY_FUNCTION__, "", 0); __builtin_unreachable(); }
#define CRASH(msg, ...) { ams::diag::AbortImpl(msg, __PRETTY_FUNCTION__, "", 0); __builtin_unreachable(); }
#else
#include "oc_test.hpp"
#endif
#include "customize.hpp" #include "customize.hpp"
#include "oc_log.hpp"
#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING)
#include "oc_log.hpp"
#endif
#define PATCH_OFFSET(offset, value) \ #define PATCH_OFFSET(offset, value) \
static_assert(sizeof(__typeof__(offset)) <= sizeof(u64)); \ static_assert(sizeof(__typeof__(offset)) <= sizeof(u64)); \
@@ -52,6 +51,8 @@ namespace ams::ldr {
R_DEFINE_ERROR_RESULT(UnsuccessfulPatcher, 1014); R_DEFINE_ERROR_RESULT(UnsuccessfulPatcher, 1014);
R_DEFINE_ERROR_RESULT(SafetyCheckFailure, 1015); R_DEFINE_ERROR_RESULT(SafetyCheckFailure, 1015);
R_DEFINE_ERROR_RESULT(InvalidMtcTablePattern, 1016); R_DEFINE_ERROR_RESULT(InvalidMtcTablePattern, 1016);
R_DEFINE_ERROR_RESULT(InvalidSocVoltPattern, 1017);
R_DEFINE_ERROR_RESULT(InvalidSocVoltLimit, 1018);
} }
namespace ams::ldr::hoc { namespace ams::ldr::hoc {
@@ -65,38 +66,42 @@ namespace ams::ldr::hoc {
size_t maximum_patched_count = 0; size_t maximum_patched_count = 0;
patternFn pattern_search_fn = nullptr; patternFn pattern_search_fn = nullptr;
Pointer value_search; Pointer value_search;
size_t patched_count = 0; size_t patched_count = 0;
Result Apply(Pointer* ptr) { Result Apply(Pointer *ptr) {
Result res = patcher_fn(ptr); Result res = patcher_fn(ptr);
if (R_SUCCEEDED(res)) if (R_SUCCEEDED(res)) {
patched_count++; patched_count++;
}
return res; return res;
} }
Result SearchAndApply(Pointer* ptr) { Result SearchAndApply(Pointer *ptr) {
bool searchOk = false; bool searchOk = false;
if (pattern_search_fn) { if (pattern_search_fn) {
if (pattern_search_fn(ptr)) searchOk = true; if (pattern_search_fn(ptr)) {
searchOk = true;
}
} else { } else {
if (value_search == *(ptr)) searchOk = true; if (value_search == *(ptr)) {
searchOk = true;
}
} }
if (searchOk) if (searchOk) {
return Apply(ptr); return Apply(ptr);
}
R_THROW(ldr::ResultUnsuccessfulPatcher()); R_THROW(ldr::ResultUnsuccessfulPatcher());
} }
Result CheckResult() { Result CheckResult() {
#ifndef ATMOSPHERE_IS_STRATOSPHERE
R_UNLESS(patched_count > 0, ldr::ResultUnsuccessfulPatcher()); R_UNLESS(patched_count > 0, ldr::ResultUnsuccessfulPatcher());
#endif
if (maximum_patched_count) if (maximum_patched_count) {
R_UNLESS(patched_count <= maximum_patched_count, ldr::ResultUnsuccessfulPatcher()); R_UNLESS(patched_count <= maximum_patched_count, ldr::ResultUnsuccessfulPatcher());
}
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -87,7 +87,7 @@ namespace ams::ldr::hoc {
static bool initDone = false; static bool initDone = false;
log_ctx_t *log_ctx = (log_ctx_t*)working_buf; log_ctx_t *log_ctx = (log_ctx_t*)working_buf;
SmcCopyFromIram(working_buf, IRAM_LOG_CTX_ADDR, sizeof(working_buf)); R_DISCARD(SmcCopyFromIram(working_buf, IRAM_LOG_CTX_ADDR, sizeof(working_buf)));
if (!initDone) { if (!initDone) {
initDone = true; initDone = true;
@@ -103,21 +103,25 @@ namespace ams::ldr::hoc {
va_end(args); va_end(args);
if (res < 0 || res >= (static_cast<s32>(max_log_sz - log_ctx->end))) { if (res < 0 || res >= (static_cast<s32>(max_log_sz - log_ctx->end))) {
SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf)); R_DISCARD(SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf)));
return; return;
} }
log_ctx->end += res; log_ctx->end += res;
SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf)); R_DISCARD(SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf)));
} }
#endif #endif
#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) #if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING)
void ViewLog() { void ViewLog() {
if (spl::GetSocType() == spl::SocType_Mariko) {
return;
}
constexpr size_t PageSize = 4096; constexpr size_t PageSize = 4096;
for (size_t ofs = 0; ofs < fatal_handler_bin_size; ofs += PageSize) { for (size_t ofs = 0; ofs < fatal_handler_bin_size; ofs += PageSize) {
memcpy(&working_buf, fatal_handler_bin + ofs, std::min(fatal_handler_bin_size - ofs, PageSize)); memcpy(&working_buf, fatal_handler_bin + ofs, std::min(fatal_handler_bin_size - ofs, PageSize));
SmcCopyToIram(ATMOSPHERE_IRAM_PAYLOAD_BASE + ofs, &working_buf, std::min(fatal_handler_bin_size - ofs, PageSize)); R_DISCARD(SmcCopyToIram(ATMOSPHERE_IRAM_PAYLOAD_BASE + ofs, &working_buf, std::min(fatal_handler_bin_size - ofs, PageSize)));
} }
SmcRebootToIramPayload(); SmcRebootToIramPayload();

View File

@@ -1,214 +0,0 @@
/*
* Copyright (C) Switch-OC-Suite
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef ATMOSPHERE_IS_STRATOSPHERE
#include "oc_test.hpp"
#include "oc_loader.hpp"
void* loadExec(const char* file_loc, size_t* out_size) {
FILE* fp = fopen(file_loc, "rb");
if (!fp) {
fprintf(stderr, "Cannot open file: \"%s\"\n", file_loc);
exit(-1);
}
if (fseek(fp, 0, SEEK_END) < 0) {
fprintf(stderr, "fseek error\n");
exit(-1);
}
long size = ftell(fp);
if (size == -1L) {
fprintf(stderr, "\"%s\" is a directory", file_loc);
exit(-1);
}
fseek(fp, 0, SEEK_SET);
void* buf = malloc(size);
fread(buf, size, 1, fp);
fclose(fp);
if (size < 8192) {
fprintf(stderr, "File is too small to process: \"%s\" (%ld B)\n", file_loc, size);
exit(-1);
}
*out_size = size;
return buf;
}
void saveExec(const char* file_loc, const void* buf, size_t size) {
FILE* fp = fopen(file_loc, "wb");
if (!fp) {
fprintf(stderr, "Cannot write to \"%s\"\n", file_loc);
exit(-1);
}
printf("Saving to \"%s\"...\n", file_loc);
fwrite(buf, size, 1, fp);
fclose(fp);
}
Result Test_PcvDvfsTable() {
using namespace ams::ldr::hoc::pcv;
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&mariko::CpuCvbTableDefault)) == 18);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&erista::CpuCvbTableDefault)) == 16);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&mariko::GpuCvbTableDefault)) == 17);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&erista::GpuCvbTableDefault)) == 12);
cvb_entry_t last_mariko_cpu_cvb_entry_default = { 1963500, { 1675751, -38635, 27 }, { 1120000 } };
assert(memcmp(GetDvfsTableLastEntry((cvb_entry_t *)(&mariko::CpuCvbTableDefault)), (void *)&last_mariko_cpu_cvb_entry_default, sizeof(last_mariko_cpu_cvb_entry_default)) == 0);
assert(GetDvfsTableLastEntry((cvb_entry_t *)(&erista::GpuCvbTableDefault))->freq == 921600);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoCpuDvfsTableSLT)) == 25);
// Customized table default
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.eristaCpuDvfsTable)) == 19);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoCpuDvfsTable)) == 21);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoCpuDvfsTableSLT)) == 22);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.eristaGpuDvfsTable)) == 12);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoGpuDvfsTable)) == 17);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoGpuDvfsTableSLT)) == 17);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::hoc::C.marikoGpuDvfsTableHiOPT)) == 17);
constexpr size_t limit = ams::ldr::hoc::pcv::DvfsTableEntryLimit;
cvb_entry_t customized_table[limit] = {};
for (size_t i = 0; i < limit; i++) {
assert(GetDvfsTableEntryCount(customized_table) == i);
auto p = GetDvfsTableLastEntry(customized_table);
if (p)
assert(p->freq == i);
customized_table[i].freq = i + 1;
}
R_SUCCEED();
}
void unitTest() {
UnitTest test[] = {
{ "PCV DVFS Table", &Test_PcvDvfsTable }
};
for (auto &t : test) {
t.Test();
}
}
int main(int argc, char** argv) {
unitTest();
const char* pcv_opt = "pcv";
const char* ptm_opt = "ptm";
const char* save_opt = "-s";
const char* mariko_ext = ".mariko";
const char* erista_ext = ".erista";
enum EXE_OPTION {
EXE_PCV,
EXE_PTM,
UNKNOWN
};
EXE_OPTION exe_opt = UNKNOWN;
if (argc > 2) {
if (!strcmp(argv[1], pcv_opt))
exe_opt = EXE_PCV;
if (!strcmp(argv[1], ptm_opt))
exe_opt = EXE_PTM;
}
if ((argc != 3 && argc != 4) || exe_opt == UNKNOWN) {
fprintf(stderr, "Usage:\n"\
" %s %s | %s [%s] <exec_path>\n\n"\
" %s : Save patched executable with extension \"%s\" / \"%s\"\n"
, argv[0], pcv_opt, ptm_opt, save_opt
, save_opt, mariko_ext, erista_ext);
return -1;
}
bool save_patched = false;
char* exec_path = argv[2];
if (argc == 4 && !strcmp(argv[2], save_opt)) {
save_patched = true;
exec_path = argv[3];
}
size_t file_size;
void* file_buffer = loadExec(exec_path, &file_size);
size_t exec_path_len = strlen(reinterpret_cast<const char *>(exec_path));
size_t exec_path_patched_len = exec_path_len + std::max(strlen(mariko_ext), strlen(erista_ext)) + 1;
if (exe_opt == EXE_PCV) {
ams::ldr::hoc::pcv::SafetyCheck();
{
void* erista_buf = malloc(file_size);
std::memcpy(erista_buf, file_buffer, file_size);
printf("Patching %s for Erista...\n", pcv_opt);
ams::ldr::hoc::pcv::erista::Patch(reinterpret_cast<uintptr_t>(erista_buf), file_size);
if (save_patched) {
char* exec_path_erista = reinterpret_cast<char *>(malloc(exec_path_patched_len));
strncpy(exec_path_erista, exec_path, exec_path_patched_len);
strncat(exec_path_erista, erista_ext, exec_path_patched_len);
saveExec(exec_path_erista, erista_buf, file_size);
free(exec_path_erista);
}
free(erista_buf);
}
{
void* mariko_buf = malloc(file_size);
std::memcpy(mariko_buf, file_buffer, file_size);
printf("Patching %s for Mariko...\n", pcv_opt);
ams::ldr::hoc::pcv::mariko::Patch(reinterpret_cast<uintptr_t>(mariko_buf), file_size);
if (save_patched) {
char* exec_path_mariko = reinterpret_cast<char *>(malloc(exec_path_patched_len));
strncpy(exec_path_mariko, exec_path, exec_path_patched_len);
strncat(exec_path_mariko, mariko_ext, exec_path_patched_len);
saveExec(exec_path_mariko, mariko_buf, file_size);
free(exec_path_mariko);
}
free(mariko_buf);
}
}
if (exe_opt == EXE_PTM) {
void* mariko_buf = malloc(file_size);
std::memcpy(mariko_buf, file_buffer, file_size);
printf("Patching %s (Mariko Only)...\n", ptm_opt);
ams::ldr::hoc::ptm::Patch(reinterpret_cast<uintptr_t>(mariko_buf), file_size);
if (save_patched) {
char* exec_path_mariko = reinterpret_cast<char *>(malloc(exec_path_patched_len));
strncpy(exec_path_mariko, exec_path, exec_path_patched_len);
strncat(exec_path_mariko, mariko_ext, exec_path_patched_len);
saveExec(exec_path_mariko, mariko_buf, file_size);
free(exec_path_mariko);
}
free(mariko_buf);
}
free(file_buffer);
printf("Passed!\n\n");
return 0;
}
#endif

View File

@@ -1,81 +0,0 @@
/*
* Copyright (C) Switch-OC-Suite
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef ATMOSPHERE_IS_STRATOSPHERE
#include <cassert>
#include <algorithm>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef int32_t s32;
typedef uint64_t u64;
typedef int Result;
#define R_SUCCEEDED(arg) (arg == 0)
#define R_FAILED(arg) (arg != 0)
#define LOGGING(fmt, ...) { printf(fmt "\n", ##__VA_ARGS__); }
#define CRASH(msg, ...) { fprintf(stderr, "%s\nFailed in %s!\n", msg, __PRETTY_FUNCTION__); exit(-1); }
#define R_SUCCEED() { return 0; }
#define R_THROW(err) { return err; }
#define R_TRY(expr) { Result _rc = (expr); if (R_FAILED(_rc)) { return _rc; } }
#define R_UNLESS(expr, rc) { if (!(expr)) { return rc; } }
#define R_DEFINE_ERROR_RESULT(name, rc) \
inline Result Result##name() { return rc; }
#define HEXDUMP(ptr, len) \
{ \
const uint8_t* p = reinterpret_cast<const uint8_t *>(ptr); \
size_t i, j; \
for (i = 0; i < len; i += 16) { \
printf("%06zx: ", i); \
for (j = 0; j < 16 && i + j < len; j++) \
printf("%02x ", p[i + j]); \
for (; j < 16; j++) \
printf(" "); \
for (j = 0; j < 16 && i + j < len; j++) \
printf("%c", isprint(p[i + j]) ? p[i + j] : '.'); \
printf("\n"); \
} \
} \
typedef struct UnitTest {
using Func = Result(*)();
const char* description;
Func fun = nullptr;
void Test() {
Result res = fun();
if (R_FAILED(res)) {
CRASH(description);
}
}
} UnitTest;
#endif

View File

@@ -22,20 +22,20 @@
namespace ams::ldr::hoc::pcv { namespace ams::ldr::hoc::pcv {
Result MemFreqPllmLimit(u32* ptr) { Result MemFreqPllmLimit(u32 *ptr) {
clk_pll_param* entry = reinterpret_cast<clk_pll_param *>(ptr); clk_pll_param *entry = reinterpret_cast<clk_pll_param *>(ptr);
R_UNLESS(entry->freq == entry->vco_max, ldr::ResultInvalidMemPllmEntry()); R_UNLESS(entry->freq == entry->vco_max, ldr::ResultInvalidMemPllmEntry());
// Double the max clk simply // Double the max clk simply
u32 max_clk = entry->freq * 2; u32 max_clk = entry->freq * 2;
entry->freq = max_clk; entry->freq = max_clk;
entry->vco_max = max_clk; entry->vco_max = max_clk;
R_SUCCEED(); R_SUCCEED();
} }
Result MemVoltHandler(u32* ptr) { Result MemVoltHandler(u32 *ptr) {
// ptr value might be default_uv or max_uv // ptr value might be default_uv or max_uv
regulator* entries[2] = { regulator *entries[2] = {
reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_1.default_uv)), reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_1.default_uv)),
reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_1.max_uv)), reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_1.max_uv)),
}; };
@@ -44,16 +44,16 @@ namespace ams::ldr::hoc::pcv {
constexpr u32 uv_min = 600'000; constexpr u32 uv_min = 600'000;
auto validator = [](regulator* entry) { auto validator = [](regulator* entry) {
R_UNLESS(entry->id == 1, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->id == 1, ldr::ResultInvalidRegulatorEntry());
R_UNLESS(entry->type == 1, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->type == 1, ldr::ResultInvalidRegulatorEntry());
R_UNLESS(entry->type_1.volt_reg == 0x17, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->type_1.volt_reg == 0x17, ldr::ResultInvalidRegulatorEntry());
R_UNLESS(entry->type_1.step_uv == uv_step, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->type_1.step_uv == uv_step, ldr::ResultInvalidRegulatorEntry());
R_UNLESS(entry->type_1.min_uv == uv_min, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->type_1.min_uv == uv_min, ldr::ResultInvalidRegulatorEntry());
R_SUCCEED(); R_SUCCEED();
}; };
regulator* entry = nullptr; regulator *entry = nullptr;
for (auto& i : entries) { for (auto &i : entries) {
if (R_SUCCEEDED(validator(i))) { if (R_SUCCEEDED(validator(i))) {
entry = i; entry = i;
} }
@@ -76,24 +76,25 @@ namespace ams::ldr::hoc::pcv {
} }
void SafetyCheck() { void SafetyCheck() {
// if (C.custRev != CUST_REV)
// CRASH("Triggered");
struct sValidator { struct sValidator {
volatile u32 value; volatile u32 value;
u32 min; u32 min;
u32 max; u32 max;
bool value_required = false;
u32 panic; u32 panic;
bool value_required = false;
Result check() { Result check() {
if (!value_required && !value) if (!value_required && !value) {
R_SUCCEED(); R_SUCCEED();
}
if (min && value < min) if (min && value < min) {
R_THROW(ldr::ResultSafetyCheckFailure()); R_THROW(ldr::ResultSafetyCheckFailure());
if (max && value > max) }
if (max && value > max) {
R_THROW(ldr::ResultSafetyCheckFailure()); R_THROW(ldr::ResultSafetyCheckFailure());
}
R_SUCCEED(); R_SUCCEED();
} }
@@ -102,28 +103,24 @@ namespace ams::ldr::hoc::pcv {
u32 eristaCpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaCpuDvfsTable)->freq); u32 eristaCpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaCpuDvfsTable)->freq);
u32 marikoCpuDvfsMaxFreq; u32 marikoCpuDvfsMaxFreq;
if (C.marikoCpuUVHigh) { if (C.marikoCpuUVHigh) {
marikoCpuDvfsMaxFreq = static_cast<u32>( marikoCpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoCpuDvfsTableSLT)->freq);
GetDvfsTableLastEntry(C.marikoCpuDvfsTableSLT)->freq
);
} else { } else {
marikoCpuDvfsMaxFreq = static_cast<u32>( marikoCpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoCpuDvfsTable)->freq);
GetDvfsTableLastEntry(C.marikoCpuDvfsTable)->freq
);
} }
u32 eristaGpuDvfsMaxFreq; u32 eristaGpuDvfsMaxFreq;
switch (C.eristaGpuUV) { switch (C.eristaGpuUV) {
case 0: case 0:
eristaGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq); eristaGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq);
break; break;
case 1: case 1:
eristaGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaGpuDvfsTableSLT)->freq); eristaGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaGpuDvfsTableSLT)->freq);
break; break;
case 2: case 2:
eristaGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaGpuDvfsTableHiOPT)->freq); eristaGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaGpuDvfsTableHiOPT)->freq);
break; break;
default: default:
eristaGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq); eristaGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq);
break; break;
} }
u32 marikoGpuDvfsMaxFreq; u32 marikoGpuDvfsMaxFreq;
@@ -137,41 +134,43 @@ namespace ams::ldr::hoc::pcv {
case 2: case 2:
marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT)->freq); marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT)->freq);
break; break;
case 3:
marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT15)->freq);
break;
case 4:
marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTableHighUV)->freq);
break;
default: default:
marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTable)->freq); marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT)->freq);
break; break;
} }
using namespace ams::ldr::hoc::pcv;
sValidator validators[] = { sValidator validators[] = {
{ C.eristaCpuBoostClock, 1020'000, 2397'000, true, panic::Cpu }, { C.eristaCpuBoostClock, 1020'000, 2397'000, panic::Cpu, true },
{ C.marikoCpuBoostClock, 1020'000, 2703'000, true, panic::Cpu }, { C.marikoCpuBoostClock, 1020'000, 2703'000, panic::Cpu, true },
{ C.eristaCpuMaxVolt, 1000, 1260, false, panic::Cpu }, { C.eristaCpuMaxVolt, 1000, 1260, panic::Cpu, },
{ C.marikoCpuMaxVolt, 1000, 1200, false, panic::Cpu }, { C.marikoCpuMaxVolt, 1000, 1200, panic::Cpu, },
{ eristaCpuDvfsMaxFreq, 1785'000, 2397'000, false, panic::Cpu }, { eristaCpuDvfsMaxFreq, 1785'000, 2397'000, panic::Cpu, },
{ marikoCpuDvfsMaxFreq, 1785'000, 2703'000, false, panic::Cpu }, { marikoCpuDvfsMaxFreq, 1785'000, 2703'000, panic::Cpu, },
{ C.commonEmcMemVolt, 912'500, 1350'000, false, panic::Emc }, // Official burst vmax for the RAMs is 1500mV { C.commonEmcMemVolt, 912'500, 1350'000, panic::Emc, }, /* Official vmax for the RAMs is 1400-1500mV */
{ GET_MAX_OF_ARR(erista::maxEmcClocks), 1600'000, 2600'000, false, panic::Emc }, { C.eristaEmcMaxClock, 1600'000, 2600'000, panic::Emc, },
{ C.marikoEmcMaxClock, 1600'000, 3500'000, false, panic::Emc }, { C.marikoEmcMaxClock, 1600'000, 3500'000, panic::Emc, },
{ C.marikoEmcVddqVolt, 250'000, 700'000, false, panic::Emc }, { C.marikoEmcVddqVolt, 400'000, 750'000, panic::Emc, },
{ eristaGpuDvfsMaxFreq, 768'000, 1152'000, false, panic::Gpu }, { C.marikoSocVmax, 1000, 1200, panic::Emc, },
{ marikoGpuDvfsMaxFreq, 768'000, 1536'000, false, panic::Gpu }, { eristaGpuDvfsMaxFreq, 768'000, 1152'000, panic::Gpu, },
{ C.marikoGpuVmax, 800, 960, false, panic::Gpu }, { marikoGpuDvfsMaxFreq, 768'000, 1536'000, panic::Gpu, },
{ C.marikoGpuVmax, 800, 960, panic::Gpu, },
}; };
for (auto &v : validators) { for (auto &v : validators) {
if (R_FAILED(v.check())) { if (R_FAILED(v.check())) {
#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) panic::SmcError(v.panic);
panic::SmcError(v.panic);
#endif
CRASH("Validation FAIL"); CRASH("Validation FAIL");
} }
} }
} }
void Patch(uintptr_t mapped_nso, size_t nso_size) { void Patch(uintptr_t mapped_nso, size_t nso_size) {
#ifdef ATMOSPHERE_IS_STRATOSPHERE
SafetyCheck(); SafetyCheck();
bool isMariko = (spl::GetSocType() == spl::SocType_Mariko); bool isMariko = (spl::GetSocType() == spl::SocType_Mariko);
@@ -180,8 +179,6 @@ namespace ams::ldr::hoc::pcv {
} else { } else {
erista::Patch(mapped_nso, nso_size); erista::Patch(mapped_nso, nso_size);
} }
#endif
} }
} }

View File

@@ -24,7 +24,6 @@
#include "pcv_common.hpp" #include "pcv_common.hpp"
#include "pcv_erista.hpp" #include "pcv_erista.hpp"
#include "pcv_mariko.hpp" #include "pcv_mariko.hpp"
#include "pcv_asm.hpp"
namespace ams::ldr::hoc::pcv { namespace ams::ldr::hoc::pcv {
@@ -119,34 +118,40 @@ namespace ams::ldr::hoc::pcv {
cvb_entry_t *customize_table; cvb_entry_t *customize_table;
if (isMariko) { if (isMariko) {
switch (C.marikoGpuUV) { switch (C.marikoGpuUV) {
case 0: case 0:
customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTable); customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTable);
break; break;
case 1: case 1:
customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTableSLT); customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTableSLT);
break; break;
case 2: case 2:
customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTableHiOPT); customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTableHiOPT);
break; break;
default: case 3:
customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTable); customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTableHiOPT15);
break; break;
} case 4:
customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTableHighUV);
break;
default:
customize_table = const_cast<cvb_entry_t *>(C.marikoGpuDvfsTableHiOPT);
break;
}
} else { } else {
switch (C.eristaGpuUV) { switch (C.eristaGpuUV) {
case 0: case 0:
customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTable); customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTable);
break; break;
case 1: case 1:
customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTableSLT); customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTableSLT);
break; break;
case 2: case 2:
customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTableHiOPT); customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTableHiOPT);
break; break;
default: default:
customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTable); customize_table = const_cast<cvb_entry_t *>(C.eristaGpuDvfsTable);
break; break;
} }
} }
size_t default_entry_count = GetDvfsTableEntryCount(default_table); size_t default_entry_count = GetDvfsTableEntryCount(default_table);
@@ -170,14 +175,14 @@ namespace ams::ldr::hoc::pcv {
PATCH_OFFSET(&(entry->cvb_pll_param.c0), (C.marikoGpuVoltArray[i] * 1000)); PATCH_OFFSET(&(entry->cvb_pll_param.c0), (C.marikoGpuVoltArray[i] * 1000));
ClearCvbPllEntry(entry); ClearCvbPllEntry(entry);
} else { } else {
PATCH_OFFSET(&(entry->cvb_pll_param.c0), (entry->cvb_pll_param.c0 - C.commonGpuVoltOffset * 1000)); PATCH_OFFSET(&(entry->cvb_pll_param.c0), (u32)((s32)entry->cvb_pll_param.c0 + C.commonGpuVoltOffset * 1000));
} }
} else { } else {
if (C.eristaGpuVoltArray[i] != 0) { if (C.eristaGpuVoltArray[i] != 0) {
PATCH_OFFSET(&(entry->cvb_pll_param.c0), (C.eristaGpuVoltArray[i] * 1000)); PATCH_OFFSET(&(entry->cvb_pll_param.c0), (C.eristaGpuVoltArray[i] * 1000));
ClearCvbPllEntry(entry); ClearCvbPllEntry(entry);
} else { } else {
PATCH_OFFSET(&(entry->cvb_pll_param.c0), (entry->cvb_pll_param.c0 - C.commonGpuVoltOffset * 1000)); PATCH_OFFSET(&(entry->cvb_pll_param.c0), (u32)((s32)entry->cvb_pll_param.c0 + C.commonGpuVoltOffset * 1000));
} }
} }
++entry; ++entry;
@@ -185,7 +190,7 @@ namespace ams::ldr::hoc::pcv {
if (C.commonGpuVoltOffset && !(isMariko ? C.marikoGpuUV : C.eristaGpuUV)) { if (C.commonGpuVoltOffset && !(isMariko ? C.marikoGpuUV : C.eristaGpuUV)) {
cvb_entry_t *entry = static_cast<cvb_entry_t *>(gpu_cvb_table_head); cvb_entry_t *entry = static_cast<cvb_entry_t *>(gpu_cvb_table_head);
for (size_t i = 0; i < customize_entry_count; ++i) { for (size_t i = 0; i < customize_entry_count; ++i) {
PATCH_OFFSET(&(entry->cvb_pll_param.c0), (entry->cvb_pll_param.c0 - C.commonGpuVoltOffset * 1000)); PATCH_OFFSET(&(entry->cvb_pll_param.c0), (u32)((s32)entry->cvb_pll_param.c0 + C.commonGpuVoltOffset * 1000));
++entry; ++entry;
} }
} }
@@ -196,26 +201,6 @@ namespace ams::ldr::hoc::pcv {
Result MemFreqPllmLimit(u32 *ptr); Result MemFreqPllmLimit(u32 *ptr);
Result MemVoltHandler(u32 *ptr); // Used for Erista MEM Vdd2 + EMC Vddq or Mariko MEM Vdd2 Result MemVoltHandler(u32 *ptr); // Used for Erista MEM Vdd2 + EMC Vddq or Mariko MEM Vdd2
template <typename T>
Result MemMtcCustomizeTable(T *dst, T *src) {
constexpr u32 mtc_magic = std::is_same_v<T, MarikoMtcTable> ? MARIKO_MTC_MAGIC : ERISTA_MTC_MAGIC;
R_UNLESS(src->rev == mtc_magic, ldr::ResultInvalidMtcMagic());
constexpr u32 ZERO_VAL = UINT32_MAX;
// Skip params from dvfs_ver to clock_src;
for (size_t offset = offsetof(T, clk_src_emc); offset < sizeof(T); offset += sizeof(u32)) {
u32 *src_ent = reinterpret_cast<u32 *>(reinterpret_cast<size_t>(src) + offset);
u32 *dst_ent = reinterpret_cast<u32 *>(reinterpret_cast<size_t>(dst) + offset);
u32 src_val = *src_ent;
if (src_val){
PATCH_OFFSET(dst_ent, src_val == ZERO_VAL ? 0 : src_val);
}
}
R_SUCCEED();
};
void SafetyCheck(); void SafetyCheck();
void Patch(uintptr_t mapped_nso, size_t nso_size); void Patch(uintptr_t mapped_nso, size_t nso_size);

View File

@@ -24,7 +24,17 @@
namespace ams::ldr::hoc::pcv { namespace ams::ldr::hoc::pcv {
constexpr u32 NopIns = 0x1f2003d5; constexpr u32 NopIns = 0xD503201F;
template <typename Compare>
u32 *ScanAssembly(u32 *ptr, u32 scanLimit, u32 pattern, Compare comp) {
for (u32 i = 0; i < scanLimit; ++i) {
if (comp(pattern, ptr[i])) {
return ptr + i;
}
}
return nullptr;
}
inline auto asm_compare_no_rd = [](u32 ins1, u32 ins2) { inline auto asm_compare_no_rd = [](u32 ins1, u32 ins2) {
return ((ins1 ^ ins2) >> 5) == 0; return ((ins1 ^ ins2) >> 5) == 0;
@@ -61,4 +71,99 @@ namespace ams::ldr::hoc::pcv {
return ((ins1 & ImmMask) ^ (ins2 & ImmMask)) == 0; return ((ins1 & ImmMask) ^ (ins2 & ImmMask)) == 0;
}; };
/* Csel (Conditional Select) */
/*
SF | Op | S | | RM | Cond | 0 | 0 | Rn | Rd
31 | 30 | 29 | 28 27 26 25 24 23 | 20 19 18 17 16 | 15 14 13 12 | 11 | 10 | 9 8 7 6 5 | 4 3 2 1 0
*/
inline auto AsmCbzCompareOpcodeOnly = [](u32 ins1, u32 ins2) {
return ((ins1 ^ ins2) >> 24) == 0;
};
inline auto AsmBlCompareOpcodeOnly = [](u32 ins1, u32 ins2) {
return ((ins1 ^ ins2) >> 26) == 0;
};
inline bool AsmComparePrologue(u32 ins1, u32 ins2, u32 ins3, u32 cmp1, u32 cmp2, u32 cmp3) {
constexpr u32 StpImmMask = ~((((1u << 7) - 1u) << 15));
bool firstMatch = (ins1 & StpImmMask) == (cmp1 & StpImmMask);
constexpr u32 StpRegsImmMask = ~(((1u << 5) - 1u) |(((1u << 5) - 1u) << 10) | (((1u << 7) - 1u) << 15));
bool secondMatch = (ins2 & StpRegsImmMask) == (cmp2 & StpRegsImmMask);
constexpr u32 MovMask = ~((1u << 5) - 1u);
bool thirdMatch = (ins3 & MovMask) == (cmp3 & MovMask);
return firstMatch && secondMatch && thirdMatch;
}
inline auto AsmCompareCselNoReg = [](u32 ins1, u32 ins2) {
constexpr u32 ClearReg = ~(((1 << 10) - 1) | (((1 << 5) - 1) << 16));
return ((ins1 & ClearReg) ^ (ins2 & ClearReg)) == 0;
};
/* Mul */
/*
SF | Op54 | Op31 | RM | o0 | RA | RN | RD
31 | 30 29 28 27 26 25 24 | 23 22 21 | 20 19 18 17 16 | 15 | 14 13 12 11 10 | 9 8 7 6 5 | 4 3 2 1 0
*/
inline auto AsmCompareMullNoReg = [](u32 ins1, u32 ins2) {
constexpr u32 ClearReg = ~(((1 << 10) - 1) | (((1 << 5) - 1) << 16));
return ((ins1 & ClearReg) ^ (ins2 & ClearReg)) == 0;
};
/* Mul */
/* MUL W11, W24, W26 */
/* multiplies by 1000, mV -> uV */
/*
SF | Op54 | Op31 | RM | o0 | RA | RN | RD
31 | 30 29 28 27 26 25 24 | 23 22 21 | 20 19 18 17 16 | 15 | 14 13 12 11 10 | 9 8 7 6 5 | 4 3 2 1 0
*/
inline auto AsmGetMullRn = [](u32 ins) {
constexpr u32 Mask = ((1 << 5) - 1) << 5;
return (ins & Mask) >> 5;
};
inline auto AsmGetMullRm = [](u32 ins) {
constexpr u32 Mask = ((1 << 5) - 1) << 16;
return (ins & Mask) >> 16;
};
/* Subs (Shifted register) */
/*
SF | Op | S | | Shift | 0 | RM | Imm6 | Rn | Rd
31 | 30 | 29 | 28 27 26 25 24 | 23 22 | 21 | 20 19 18 17 16 | 15 14 13 12 11 10 | 9 8 7 6 5 | 4 3 2 1 0
*/
inline auto AsmSubsSetRn = [](u32 ins, u8 rn) {
constexpr u32 RnMaskClear = ~(((1u << 5) - 1u) << 5);
constexpr u32 RnMaskSet = (1u << 5) - 1u;
return (ins & RnMaskClear) | ((static_cast<u32>(rn) & RnMaskSet) << 5);
};
/* Subs (Immediate) */
/*
SF | Op | S | | Sh | Imm12 | Rn | Rd
31 | 30 | 29 | 28 27 26 25 24 23 | 22 | 21 20 19 18 17 16 15 14 13 12 11 10 | 9 8 7 6 5 | 4 3 2 1 0
*/
inline auto AsmSubsSetImm12 = [](u32 ins, u16 imm12) {
constexpr u32 ClearMask = ~(((1u << 12) - 1) << 10);
constexpr u32 SetImm12Mask = ( 1u << 12) - 1;
return (ins & ClearMask) | ((imm12 & SetImm12Mask) << 10);
};
inline auto AsmSubsCompareNoReg = [](u32 ins1, u32 ins2) {
return ((ins1 ^ ins2) >> 10) == 0;
};
inline auto AsmCompareBrConNoImm19 = [](u32 ins1, u32 ins2) {
constexpr u32 ClearImm19 = ~(((1 << 19) - 1) << 5);
return (ins1 & ClearImm19) == (ins2 & ClearImm19);
};
} }

View File

@@ -18,35 +18,37 @@
#pragma once #pragma once
#include "../mtc_timing_table.hpp"
namespace ams::ldr::hoc::pcv { namespace ams::ldr::hoc::pcv {
typedef struct cvb_coefficients { struct cvb_coefficients {
s32 c0 = 0; s32 c0 = 0;
s32 c1 = 0; s32 c1 = 0;
s32 c2 = 0; s32 c2 = 0;
s32 c3 = 0; s32 c3 = 0;
s32 c4 = 0; s32 c4 = 0;
s32 c5 = 0; s32 c5 = 0;
} cvb_coefficients; };
typedef struct cvb_entry_t { struct cvb_entry_t {
u64 freq; u64 freq;
cvb_coefficients cvb_dfll_param; cvb_coefficients cvb_dfll_param;
cvb_coefficients cvb_pll_param; cvb_coefficients cvb_pll_param;
} cvb_entry_t; };
static_assert(sizeof(cvb_entry_t) == 0x38); static_assert(sizeof(cvb_entry_t) == 0x38);
typedef struct cvb_cpu_dfll_data { struct CvbCpuDfllData {
u32 tune0_low; u32 tune0_low;
u32 tune0_high; u32 tune0_high;
u32 tune1_low; u32 tune1_low;
u32 tune1_high; u32 tune1_high;
unsigned int tune_high_min_millivolts; u32 tune_high_min_millivolts;
unsigned int tune_high_margin_millivolts; u32 tune_high_margin_millivolts;
unsigned long dvco_calibration_max; u64 dvco_calibration_max;
} cvb_cpu_dfll_data; };
typedef struct __attribute__((packed)) div_nmp { struct __attribute__((packed)) div_nmp {
u8 divn_shift; u8 divn_shift;
u8 divn_width; u8 divn_width;
u8 divm_shift; u8 divm_shift;
@@ -56,9 +58,9 @@ namespace ams::ldr::hoc::pcv {
u8 override_divn_shift; u8 override_divn_shift;
u8 override_divm_shift; u8 override_divm_shift;
u8 override_divp_shift; u8 override_divp_shift;
} div_nmp; };
typedef struct __attribute__((packed)) clk_pll_param { struct __attribute__((packed)) clk_pll_param {
u32 freq; u32 freq;
u32 input_min; u32 input_min;
u32 input_max; u32 input_max;
@@ -72,9 +74,9 @@ namespace ams::ldr::hoc::pcv {
struct div_nmp *div_nmp; struct div_nmp *div_nmp;
u32 unk_1[4]; u32 unk_1[4];
void (*unk_fn)(u64* unk_struct); // set_defaults? void (*unk_fn)(u64* unk_struct); // set_defaults?
} clk_pll_param; };
typedef struct __attribute__((packed)) dvfs_rail { struct __attribute__((packed)) dvfs_rail {
u32 id; u32 id;
u32 unk_0[5]; u32 unk_0[5];
u32 freq; u32 freq;
@@ -84,9 +86,9 @@ namespace ams::ldr::hoc::pcv {
u32 step_mv; u32 step_mv;
u32 max_mv; u32 max_mv;
u32 unk_2[11]; u32 unk_2[11];
} dvfs_rail; };
typedef struct __attribute__((packed)) regulator { struct __attribute__((packed)) regulator {
u64 id; u64 id;
const char* name; const char* name;
u32 type; u32 type;
@@ -110,9 +112,28 @@ namespace ams::ldr::hoc::pcv {
} type_2_3; } type_2_3;
}; };
u32 unk_x[60]; u32 unk_x[60];
} regulator; };
static_assert(sizeof(regulator) == 0x120); static_assert(sizeof(regulator) == 0x120);
struct __attribute__((packed)) CvbMeta {
u64 socType;
CvbCpuDfllData dfllData; /* Maybe? */
u32 unkZero2[6];
u32 unkMagic;
u32 unkZero3;
u32 highVmin;
u32 unkStepMaybe;
u32 vmin;
u32 unkZero4[3];
u32 pllMinMilliVolts;
u32 vmax;
u32 unkScale2;
u32 speedoScale;
u32 voltageScale;
u32 unkZero5;
};
static_assert(sizeof(CvbMeta) == 0x78);
constexpr u32 CpuClkOSLimit = 1785'000; constexpr u32 CpuClkOSLimit = 1785'000;
constexpr u32 GpuClkOsLimit = 921'600; constexpr u32 GpuClkOsLimit = 921'600;
constexpr u32 EmcClkOSLimit = 1600'000; constexpr u32 EmcClkOSLimit = 1600'000;
@@ -124,11 +145,11 @@ namespace ams::ldr::hoc::pcv {
constexpr size_t DvfsTableEntryLimit = DvfsTableEntryCount - 1; constexpr size_t DvfsTableEntryLimit = DvfsTableEntryCount - 1;
template<typename T> template<typename T>
size_t GetDvfsTableEntryCount(T* table_head) { size_t GetDvfsTableEntryCount(T *table_head) {
using NT = std::remove_const_t<std::remove_volatile_t<T>>; using NT = std::remove_const_t<std::remove_volatile_t<T>>;
auto is_empty = [](NT* entry) { auto is_empty = [](NT* entry) {
uint8_t* m = reinterpret_cast<uint8_t *>(entry); u8 *m = reinterpret_cast<u8 *>(entry);
for (size_t i = 0; i < sizeof(NT); i++) { for (size_t i = 0; i < sizeof(NT); i++) {
if (*(m + i)) { if (*(m + i)) {
return false; return false;
@@ -137,7 +158,7 @@ namespace ams::ldr::hoc::pcv {
return true; return true;
}; };
NT* table = const_cast<NT *>(table_head); NT *table = const_cast<NT *>(table_head);
size_t count = 0; size_t count = 0;
while (count < DvfsTableEntryLimit) { while (count < DvfsTableEntryLimit) {
if (is_empty(table++)) { if (is_empty(table++)) {
@@ -149,10 +170,10 @@ namespace ams::ldr::hoc::pcv {
} }
template<typename T> template<typename T>
T* GetDvfsTableLastEntry(T* table_head) { T *GetDvfsTableLastEntry(T *table_head) {
using NT = std::remove_const_t<std::remove_volatile_t<T>>; using NT = std::remove_const_t<std::remove_volatile_t<T>>;
NT* table = const_cast<NT *>(table_head); NT *table = const_cast<NT *>(table_head);
size_t count = GetDvfsTableEntryCount(table_head); size_t count = GetDvfsTableEntryCount(table_head);
if (!count) { if (!count) {
return nullptr; return nullptr;

View File

@@ -3,6 +3,8 @@
* *
* Copyright (c) 2023 hanai3Bi * Copyright (c) 2023 hanai3Bi
* *
* Copyright (c) B3711
*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors * Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@@ -18,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <vector>
#include "pcv.hpp" #include "pcv.hpp"
#include "../mtc_timing_value.hpp" #include "../mtc_timing_value.hpp"
#include "../erista/calculate_timings_erista.hpp" #include "../erista/calculate_timings_erista.hpp"
@@ -66,11 +69,12 @@ namespace ams::ldr::hoc::pcv::erista {
} }
Result CpuVoltDfll(u32* ptr) { Result CpuVoltDfll(u32* ptr) {
cvb_cpu_dfll_data *entry = reinterpret_cast<cvb_cpu_dfll_data *>(ptr); CvbCpuDfllData *entry = reinterpret_cast<CvbCpuDfllData *>(ptr);
R_UNLESS(entry->tune0_low == 0xFFEAD0FF, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune0_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); R_UNLESS(entry->tune0_low == 0xFFEAD0FF, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune1_low == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); R_UNLESS(entry->tune0_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune1_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); R_UNLESS(entry->tune1_low == 0x0, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune1_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry());
if (!C.eristaCpuUV) { if (!C.eristaCpuUV) {
R_SKIP(); R_SKIP();
@@ -100,6 +104,7 @@ namespace ams::ldr::hoc::pcv::erista {
default: default:
break; break;
} }
R_SUCCEED(); R_SUCCEED();
} }
@@ -121,10 +126,10 @@ namespace ams::ldr::hoc::pcv::erista {
} }
if (C.eristaGpuVmin) { if (C.eristaGpuVmin) {
PATCH_OFFSET(ptr , C.eristaGpuVmin); PATCH_OFFSET(ptr, C.eristaGpuVmin);
PATCH_OFFSET(ptr + 3, C.eristaGpuVmin); PATCH_OFFSET(ptr + 3, C.eristaGpuVmin);
PATCH_OFFSET(ptr + 6, C.eristaGpuVmin); PATCH_OFFSET(ptr + 6, C.eristaGpuVmin);
PATCH_OFFSET(ptr + 9, C.eristaGpuVmin); PATCH_OFFSET(ptr + 9, C.eristaGpuVmin);
PATCH_OFFSET(ptr + 12, C.eristaGpuVmin); PATCH_OFFSET(ptr + 12, C.eristaGpuVmin);
} }
@@ -134,17 +139,13 @@ namespace ams::ldr::hoc::pcv::erista {
Result GpuFreqMaxAsm(u32 *ptr32) { Result GpuFreqMaxAsm(u32 *ptr32) {
// Check if both two instructions match the pattern // Check if both two instructions match the pattern
u32 ins1 = *ptr32, ins2 = *(ptr32 + 1); u32 ins1 = *ptr32, ins2 = *(ptr32 + 1);
if (!(asm_compare_no_rd(ins1, GpuAsmPattern[0]) && asm_compare_no_rd(ins2, GpuAsmPattern[1]))) if (!(asm_compare_no_rd(ins1, GpuAsmPattern[0]) && asm_compare_no_rd(ins2, GpuAsmPattern[1]))) {
R_THROW(ldr::ResultInvalidGpuFreqMaxPattern()); R_THROW(ldr::ResultInvalidGpuFreqMaxPattern());
}
// Both instructions should operate on the same register // Both instructions should operate on the same register
u8 rd = asm_get_rd(ins1); u8 rd = asm_get_rd(ins1);
if (rd != asm_get_rd(ins2)) if (rd != asm_get_rd(ins2)) {
R_THROW(ldr::ResultInvalidGpuFreqMaxPattern());
/* Verify the limit. */
/* TODO: Make this a little bit cleaner at some point. */
if (AsmGetImm16(ins1) != (GpuClkOsLimit & 0xFFFF) || AsmGetImm16(ins2) != (GpuClkOsLimit >> 16)) {
R_THROW(ldr::ResultInvalidGpuFreqMaxPattern()); R_THROW(ldr::ResultInvalidGpuFreqMaxPattern());
} }
@@ -163,10 +164,13 @@ namespace ams::ldr::hoc::pcv::erista {
max_clock = GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq; max_clock = GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq;
break; break;
} }
u32 asm_patch[2] = { u32 asm_patch[2] = {
asm_set_rd(asm_set_imm16(GpuAsmPattern[0], max_clock), rd), asm_set_rd(asm_set_imm16(GpuAsmPattern[0], max_clock), rd),
asm_set_rd(asm_set_imm16(GpuAsmPattern[1], max_clock >> 16), rd)}; asm_set_rd(asm_set_imm16(GpuAsmPattern[1], max_clock >> 16), rd)
PATCH_OFFSET(ptr32, asm_patch[0]); };
PATCH_OFFSET(ptr32, asm_patch[0]);
PATCH_OFFSET(ptr32 + 1, asm_patch[1]); PATCH_OFFSET(ptr32 + 1, asm_patch[1]);
R_SUCCEED(); R_SUCCEED();
@@ -210,13 +214,15 @@ namespace ams::ldr::hoc::pcv::erista {
} }
u32 trefbw = refresh_raw + 0x40; u32 trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF)); trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
CalculateTimings(tCK_avg); const u32 dyn_self_ref_control = (static_cast<u32>(7605.0 / tCK_avg) + 260) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000);
CalculateTimings(tCK_avg, table->rate_khz);
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast<u32>(0xB8))); WRITE_PARAM_ALL_REG(table, emc_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast<u32>(0xB9)));
WRITE_PARAM_ALL_REG(table, emc_ras, MIN(GET_CYCLE_CEIL(tRAS), static_cast<u32>(0x7F))); WRITE_PARAM_ALL_REG(table, emc_ras, MIN(GET_CYCLE_CEIL(tRAS), static_cast<u32>(0x7F)));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD)); WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb)); WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb));
@@ -239,7 +245,6 @@ namespace ams::ldr::hoc::pcv::erista {
WRITE_PARAM_ALL_REG(table, emc_refresh, refresh_raw); WRITE_PARAM_ALL_REG(table, emc_refresh, refresh_raw);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, refresh_raw / 4); WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, refresh_raw / 4);
WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw); WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw);
const u32 dyn_self_ref_control = (static_cast<u32>(7605.0 / tCK_avg) + 260) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000);
WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control); WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control);
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, pdex2rw); WRITE_PARAM_ALL_REG(table, emc_pdex2wr, pdex2rw);
WRITE_PARAM_ALL_REG(table, emc_pdex2rd, pdex2rw); WRITE_PARAM_ALL_REG(table, emc_pdex2rd, pdex2rw);
@@ -252,16 +257,17 @@ namespace ams::ldr::hoc::pcv::erista {
WRITE_PARAM_ALL_REG(table, emc_rw2pden, tWTPDEN); WRITE_PARAM_ALL_REG(table, emc_rw2pden, tWTPDEN);
/* Accept imperfection or prepare for suffering. */ /* Accept imperfection or prepare for suffering. */
// #if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING)
// WRITE_PARAM_ALL_REG(table, emc_einput, einput); // WRITE_PARAM_ALL_REG(table, emc_einput, einput);
// WRITE_PARAM_ALL_REG(table, emc_einput_duration, einput_duration); // WRITE_PARAM_ALL_REG(table, emc_einput_duration, einput_duration);
// WRITE_PARAM_ALL_REG(table, emc_obdly, obdly); WRITE_PARAM_ALL_REG(table, emc_obdly, obdly);
// WRITE_PARAM_ALL_REG(table, emc_ibdly, ibdly); // WRITE_PARAM_ALL_REG(table, emc_ibdly, ibdly);
// WRITE_PARAM_ALL_REG(table, emc_wdv_mask, wdv); // WRITE_PARAM_ALL_REG(table, emc_wdv_mask, wdv);
// WRITE_PARAM_ALL_REG(table, emc_quse_width, quse_width); // WRITE_PARAM_ALL_REG(table, emc_quse_width, quse_width);
// WRITE_PARAM_ALL_REG(table, emc_quse, quse); // WRITE_PARAM_ALL_REG(table, emc_quse, quse);
// WRITE_PARAM_ALL_REG(table, emc_wdv, wdv); WRITE_PARAM_ALL_REG(table, emc_wdv, wdv);
// WRITE_PARAM_ALL_REG(table, emc_wsv, wsv); WRITE_PARAM_ALL_REG(table, emc_wsv, wsv);
// WRITE_PARAM_ALL_REG(table, emc_wev, wev); WRITE_PARAM_ALL_REG(table, emc_wev, wev);
// WRITE_PARAM_ALL_REG(table, emc_qrst, qrst); // WRITE_PARAM_ALL_REG(table, emc_qrst, qrst);
// WRITE_PARAM_ALL_REG(table, emc_tr_qrst, qrst); // WRITE_PARAM_ALL_REG(table, emc_tr_qrst, qrst);
// WRITE_PARAM_ALL_REG(table, emc_qsafe, qsafe); // WRITE_PARAM_ALL_REG(table, emc_qsafe, qsafe);
@@ -274,22 +280,21 @@ namespace ams::ldr::hoc::pcv::erista {
// WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, rdv); // WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, rdv);
// WRITE_PARAM_ALL_REG(table, emc_rdv_mask, rdv + 2); // WRITE_PARAM_ALL_REG(table, emc_rdv_mask, rdv + 2);
// WRITE_PARAM_ALL_REG(table, emc_tr_rdv, rdv); // WRITE_PARAM_ALL_REG(table, emc_tr_rdv, rdv);
// ams::ldr::hoc::pcv::mariko::CalculateMrw2(); table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast<u32>(mrw2);
// table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast<u32>(mrw2);
// table->dram_timings.rl = RL; // table->dram_timings.rl = RL;
// #endif
/* This needs some clean up. */
constexpr double MC_ARB_DIV = 4.0; constexpr double MC_ARB_DIV = 4.0;
constexpr u32 MC_ARB_SFA = 2; constexpr u32 MC_ARB_SFA = 2;
table->burst_mc_regs.mc_emem_arb_cfg = table->rate_khz / (33.3 * 1000) / MC_ARB_DIV; table->burst_mc_regs.mc_emem_arb_cfg = table->rate_khz / (33.3 * 1000) / MC_ARB_DIV;
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2; table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2; table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(tR2P / MC_ARB_DIV); table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(tR2P / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(tW2P / MC_ARB_DIV) + MC_ARB_SFA; table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(tW2P / MC_ARB_DIV) + MC_ARB_SFA;
@@ -325,8 +330,8 @@ namespace ams::ldr::hoc::pcv::erista {
table->la_scale_regs.mc_ptsa_grant_decrement = grant_decrement; table->la_scale_regs.mc_ptsa_grant_decrement = grant_decrement;
constexpr u32 MaskHigh = 0xFF00FFFF; constexpr u32 MaskHigh = 0xFF00FFFF;
constexpr u32 Mask2 = 0xFFFFFF00; constexpr u32 Mask2 = 0xFFFFFF00;
constexpr u32 Mask3 = 0xFF00FF00; constexpr u32 Mask3 = 0xFF00FF00;
const u32 allowance1 = static_cast<u32>(0x32000 / (table->rate_khz / 0x3E8)) & 0xFF; const u32 allowance1 = static_cast<u32>(0x32000 / (table->rate_khz / 0x3E8)) & 0xFF;
const u32 allowance2 = static_cast<u32>(0x9C40 / (table->rate_khz / 0x3E8)) & 0xFF; const u32 allowance2 = static_cast<u32>(0x9C40 / (table->rate_khz / 0x3E8)) & 0xFF;
@@ -354,71 +359,182 @@ namespace ams::ldr::hoc::pcv::erista {
table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & Mask2) | allowance1; table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & Mask2) | allowance1;
table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & Mask2) | allowance1; table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & Mask2) | allowance1;
table->dram_timings.t_rp = tRFCpb; table->dram_timings.t_rp = tRFCpb;
table->dram_timings.t_rfc = tRFCab; table->dram_timings.t_rfc = tRFCab;
table->emc_cfg_2 = 0x11083D; table->emc_cfg_2 = 0x11083D;
table->min_volt = std::min(static_cast<u32>(1050), 900 + C.emcDvbShift * 25); table->min_volt = std::clamp(900 + (C.emcDvbShift * 25), 900, 1050);
}
namespace {
std::vector<u32> newEmcList;
u32 *nsoStart;
}
/* The silicon instructs; the children obey... */
void MtcGenerateFreqTables() {
newEmcList.clear();
newEmcList.reserve(DvfsTableEntryCount);
newEmcList.insert(newEmcList.end(), std::begin(EmcListDefault), std::end(EmcListDefault));
if (C.eristaEmcMaxClock <= EmcClkOSLimit) {
return;
}
/* This is scuffed, but Eristas step rate is... weird? */
/* 1766MHz seems to cause crashes with other freqs near it... why is anyones guess... */
u32 freqsLow[] = { 1633000, 1666000, 1700000, 1733000, 1800000, 1833000, 1862400, };
constexpr size_t freqsLowSize = std::size(freqsLow);
for (size_t i = 0; i < freqsLowSize; ++i) {
if (freqsLow[i] <= C.eristaEmcMaxClock) {
newEmcList.push_back(freqsLow[i]);
} else {
break;
}
}
if (C.eristaEmcMaxClock <= freqsLow[freqsLowSize - 1]) {
return;
}
/* High range. */
constexpr u32 StepRate = 38400;
while (newEmcList.back() + StepRate < C.eristaEmcMaxClock) {
newEmcList.push_back(newEmcList.back() + StepRate);
}
if (newEmcList.back() != C.eristaEmcMaxClock) {
newEmcList.push_back(static_cast<u32>(C.eristaEmcMaxClock));
}
constexpr u32 PllmToggleFrequency = 19200;
/* A step of 19.2khz will cause hangs, crashes and other weirdness. */
/* Why? ¯\_(ツ)_/¯ */
if (C.eristaEmcMaxClock - newEmcList[newEmcList.size() - 2] <= PllmToggleFrequency) {
newEmcList.erase(newEmcList.begin() + newEmcList.size() - 2);
}
newEmcList.resize(std::min(newEmcList.size(), DvfsTableEntryLimit));
}
/* TODO: Template this */
Result VerifyMtcTable(EristaMtcTable *tableStart, u32 expectedFreq) {
R_UNLESS(tableStart->rate_khz == expectedFreq, ldr::ResultInvalidMtcTable());
R_UNLESS(tableStart->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable());
R_SUCCEED();
}
/* TODO: Template this */
Result MtcValidateAllTables(EristaMtcTable *tableStart, const u32 *validationList, u32 tableCount) {
for (u32 i = 0; i < tableCount; ++i) {
R_TRY(VerifyMtcTable(&tableStart[i], validationList[i]));
}
R_SUCCEED();
}
/* TODO: Put this into common. */
DramId GetDramId() {
u64 id64;
splGetConfig(SplConfigItem_DramId, &id64);
return static_cast<DramId>(id64);
}
MtcTableIndex GetMtcDramIndex(DramId dramId) {
for (u32 i = 0; i < std::size(mtcIndexTable); ++i) {
if (mtcIndexTable[i].dramId == dramId) {
return mtcIndexTable[i].index;
}
}
return MtcTableIndex_Invalid;
}
NORETURN void AbortInvalidMtc(const char *crashMsg) {
panic::SmcError(panic::Emc);
CRASH(crashMsg);
}
u32 GetMtcOffset(MtcTableIndex index) {
if (index < T210SdevEmcDvfsTableS6gb01) {
return index * erista::MtcFullTableSize;
}
/* Account for the weird in between mariko table. */
return index * erista::MtcFullTableSize + mariko::MtcFullTableSize;
}
void PrepareMtcMemoryRegion(u8 *firstTable, EristaMtcTable *usedTable) {
memmove(firstTable, usedTable, erista::MtcFullTableSize);
/* Clear all other tables. */
/* The used table is excluded. */
constexpr size_t RemainingRegionSize = (mariko::MtcFullTableSize) * (mariko::MtcFullTableCount) + (erista::MtcFullTableSize * (erista::MtcFullTableCount - 1));
memset(firstTable + erista::MtcFullTableSize, 0, RemainingRegionSize);
}
void MtcExtendTables(EristaMtcTable *table) {
for (u32 i = erista::MtcTableCountDefault; i < newEmcList.size(); ++i) {
std::memcpy(&table[i], &table[i - 1], sizeof(EristaMtcTable));
table[i].rate_khz = newEmcList[i];
}
} }
/* Probably more intuitive to point to 40800 rather than 1600000, but oh well. */
Result MemFreqMtcTable(u32 *ptr) { Result MemFreqMtcTable(u32 *ptr) {
if (GET_MAX_OF_ARR(maxEmcClocks) <= EmcClkOSLimit) { static const DramId dramId = [] {
DramId id = GetDramId();
return id;
}();
static const MtcTableIndex mtcIndex = [] {
MtcTableIndex idx = GetMtcDramIndex(dramId);
/* If for some reason this happens, there is no chance of recovering this. */
if (idx == MtcTableIndex_Invalid) {
AbortInvalidMtc("Invalid dramId");
}
return idx;
}();
static const u32 mtcOffset = GetMtcOffset(mtcIndex);
constexpr u32 StartAdjustment = offsetof(EristaMtcTable, rate_khz) + sizeof(EristaMtcTable) * (erista::MtcTableCountDefault - 1);
u8 *startPtr = reinterpret_cast<u8 *>(ptr) - StartAdjustment;
EristaMtcTable *table = reinterpret_cast<EristaMtcTable *>(startPtr + mtcOffset);
R_TRY(MtcValidateAllTables(table, EmcListDefault, EmcListSizeDefault));
PrepareMtcMemoryRegion(startPtr, table);
table = reinterpret_cast<EristaMtcTable *>(startPtr);
if (R_FAILED(MtcValidateAllTables(table, EmcListDefault, EmcListSizeDefault))) {
AbortInvalidMtc("Failed mtc validation");
}
if (C.eristaEmcMaxClock <= EmcClkOSLimit) {
R_SKIP(); R_SKIP();
} }
u32 khz_list[] = { 40800, 68000, 102000, 204000, 408000, 665600, 800000, 1065600, 1331200, 1600000 }; MtcExtendTables(table);
std::sort(maxEmcClocks, maxEmcClocks + std::size(maxEmcClocks));
u32 khz_list_size = std::size(khz_list);
// Generate list for mtc table pointers if (R_FAILED(MtcValidateAllTables(table, newEmcList.data(), newEmcList.size()))) {
EristaMtcTable *table_list[khz_list_size]; AbortInvalidMtc("Failed mtc validation");
for (u32 i = 0; i < khz_list_size; i++) {
u32 mtcIndex = khz_list_size - 1 - i;
u8 *table = reinterpret_cast<u8 *>(ptr) - offsetof(EristaMtcTable, rate_khz) - i * sizeof(EristaMtcTable);
table_list[mtcIndex] = reinterpret_cast<EristaMtcTable *>(table);
R_UNLESS(table_list[mtcIndex]->rate_khz == khz_list[mtcIndex], ldr::ResultInvalidMtcTable());
R_UNLESS(table_list[mtcIndex]->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable());
} }
/* If we oc ram at all, tables are always shifted by at least 1. */ for (u32 i = erista::MtcTableCountDefault; i < newEmcList.size(); ++i) {
u32 tableShifts = 1; MemMtcTableAutoAdjust(&table[i]);
for (u32 i = 0; i < std::size(maxEmcClocks) - 1; ++i) {
/* Duplicated mtc tables may cause pcv to not select frequencies properly, causing issues. */
if (maxEmcClocks[i] != maxEmcClocks[i + 1] && maxEmcClocks[i] > EmcClkOSLimit) {
++tableShifts;
} else {
maxEmcClocks[i] = 0;
}
}
/* Erista has extra, useless mtc tables, such as 40.8 Mhz, overwrite them to make room for oc freqs. */
/* More than 3 tables can be overwritten, but 3 is plenty. */
std::memmove(table_list[0], table_list[tableShifts], sizeof(EristaMtcTable) * (khz_list_size - tableShifts));
/* Since we're not scaling r/w latency properly on Erista, we first overwrite the tables with the 1600 MHz table before scaling it. */
for (u32 i = 0; i < tableShifts; ++i) {
std::memcpy(table_list[khz_list_size - i - 1], table_list[khz_list_size - tableShifts - 1], sizeof(EristaMtcTable));
}
for (u32 i = tableShifts, j = 0; i > 0 && j < std::size(maxEmcClocks); ++j) {
if (!maxEmcClocks[j]) {
continue;
}
table_list[khz_list_size - i]->rate_khz = maxEmcClocks[j];
MemMtcTableAutoAdjust(table_list[khz_list_size - i]);
--i;
} }
R_SUCCEED(); R_SUCCEED();
} }
Result MemFreqMax(u32 *ptr) { Result MemFreqMax(u32 *ptr) {
if (GET_MAX_OF_ARR(maxEmcClocks) <= EmcClkOSLimit) { if (C.eristaEmcMaxClock <= EmcClkOSLimit) {
R_SKIP(); R_SKIP();
} }
PATCH_OFFSET(ptr, GET_MAX_OF_ARR(maxEmcClocks)); PATCH_OFFSET(ptr, C.eristaEmcMaxClock);
R_SUCCEED(); R_SUCCEED();
} }
@@ -450,22 +566,77 @@ namespace ams::ldr::hoc::pcv::erista {
// R_SUCCEED(); // R_SUCCEED();
// } // }
Result MemMtcTableAsm(u32 *ptr) {
/* This is a mess but the compiler made this painful to patch so we must do it this way */
constexpr s32 GoodAdrpOffset = -1;
constexpr s32 GoodMovOffset = -7;
constexpr s32 GoodBlOffset = 1;
constexpr u32 MtcGoodBlOpcode = 0x97fe6cfc;
constexpr u32 MtcBadBlOpcode0 = 0x97ffae64; // bl nn::pcv::GetHardwareType
constexpr u32 MtcBadBlOpcode1 = 0x940036d5; // bl nn::pcv::GetHardwareType
constexpr u32 MtcBadAdrpAsm = 0xd00000a1; // adrp x1, s_ModuleResetStatus_
constexpr s32 MtcBadBlOffset0 = 2;
constexpr s32 MtcBadBlOffset1 = -1;
constexpr s32 MtcBadAdrpOffset = 1;
/* Ensure we don't dereference memory before nso start. */
R_UNLESS(ptr + GoodMovOffset >= nsoStart, ldr::ResultInvalidMtcTablePattern());
/* Check for GetHardwareType asm and skip if it is found */
/* The pattern will match on the first time, but the location is bad, so it must be skipped */
if(AsmCompareAdrpNoImm(*(ptr + MtcBadAdrpOffset), MtcBadAdrpAsm) && AsmBlCompareOpcodeOnly(*(ptr + MtcBadBlOffset0), MtcBadBlOpcode0) && AsmBlCompareOpcodeOnly(*(ptr + MtcBadBlOffset1), MtcBadBlOpcode1)) {
R_SKIP();
}
/* We don't check for matching register because both registers must be x0 in order to pass the previous checks. */
/* The correct instructions will always be x0 since the mtcTable pointer is returned. */
u32 adrp = *(ptr + GoodAdrpOffset);
R_UNLESS(AsmCompareAdrpNoImm(adrp, MtcAdrpAsm), ldr::ResultInvalidMtcTablePattern());
/* Check for the branch instruction above the cbz to ensure we are patching the right location*/
u32 bl = *(ptr + GoodBlOffset);
R_UNLESS(AsmBlCompareOpcodeOnly(bl, MtcGoodBlOpcode), ldr::ResultInvalidMtcTablePattern());
/* Check for the mov that actually sets the mtc table count. */
u32 mov = *(ptr + GoodMovOffset);
R_UNLESS(asm_compare_no_rd(mov, MtcMovAsm), ldr::ResultInvalidMtcTablePattern());
/* Patch out the count of the mov to our custom mtc table amount*/
u32 movCountPatch = asm_set_rd(asm_set_imm16(MtcMovAsm, newEmcList.size()), asm_get_rd(mov));
PATCH_OFFSET(ptr + GoodMovOffset, movCountPatch);
R_SUCCEED();
}
void Patch(uintptr_t mapped_nso, size_t nso_size) { void Patch(uintptr_t mapped_nso, size_t nso_size) {
nsoStart = reinterpret_cast<u32 *>(mapped_nso);
MtcGenerateFreqTables();
u32 CpuCvbDefaultMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(CpuCvbTableDefault)->freq);
u32 GpuCvbDefaultMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(GpuCvbTableDefault)->freq);
PatcherEntry<u32> patches[] = { PatcherEntry<u32> patches[] = {
{"CPU Freq Table", CpuFreqCvbTable<false>, 1, nullptr, static_cast<u32>(GetDvfsTableLastEntry(CpuCvbTableDefault)->freq)}, {"CPU Freq Table", CpuFreqCvbTable<false>, 1, nullptr, CpuCvbDefaultMaxFreq },
{"CPU Volt DVFS", &CpuVoltDvfs, 1, nullptr, CpuVminOfficial}, {"CPU Volt DVFS", &CpuVoltDvfs, 1, nullptr, CpuVminOfficial },
{"CPU Volt Thermals", &CpuVoltThermals, 1, nullptr, CpuVminOfficial}, {"CPU Volt Thermals", &CpuVoltThermals, 1, nullptr, CpuVminOfficial },
{"CPU Volt Dfll", &CpuVoltDfll, 1, nullptr, 0xFFEAD0FF}, {"CPU Volt Dfll", &CpuVoltDfll, 1, nullptr, CpuTune0Low },
{"GPU Volt DVFS", &GpuVoltDVFS, 1, nullptr, GpuVminOfficial}, {"GPU Volt DVFS", &GpuVoltDVFS, 1, nullptr, GpuVminOfficial },
{"GPU Volt Thermals", &GpuVoltThermals, 1, nullptr, GpuVminOfficial}, {"GPU Volt Thermals", &GpuVoltThermals, 1, nullptr, GpuVminOfficial },
{"GPU Freq Table", GpuFreqCvbTable<false>, 1, nullptr, static_cast<u32>(GetDvfsTableLastEntry(GpuCvbTableDefault)->freq)}, {"GPU Freq Table", GpuFreqCvbTable<false>, 1, nullptr, GpuCvbDefaultMaxFreq },
{"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn}, {"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn },
{"GPU PLL Max", &GpuFreqPllMax, 1, nullptr, GpuClkPllMax}, {"GPU PLL Max", & GpuFreqPllMax, 1, nullptr, GpuClkPllMax },
// {"GPU PLL Limit", &GpuFreqPllLimit, 4, nullptr, GpuClkPllLimit}, // {"GPU PLL Limit", &GpuFreqPllLimit, 4, nullptr, GpuClkPllLimit },
{"MEM Freq Mtc", &MemFreqMtcTable, 0, nullptr, EmcClkOSLimit}, {"MEM Freq Mtc", &MemFreqMtcTable, 1, nullptr, EmcClkOSLimit },
{"MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit}, {"MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit },
{"MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit}, {"MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit },
{"MEM Volt", &MemVoltHandler, 2, nullptr, MemVoltHOS}, {"MEM Volt", &MemVoltHandler, 2, nullptr, MemVoltHOS },
{"MEM Table Asm", &MemMtcTableAsm, 4, &MemMtcGetGetTablePatternFn },
}; };
for (uintptr_t ptr = mapped_nso; ptr <= mapped_nso + nso_size - sizeof(EristaMtcTable); ptr += sizeof(u32)) { for (uintptr_t ptr = mapped_nso; ptr <= mapped_nso + nso_size - sizeof(EristaMtcTable); ptr += sizeof(u32)) {
@@ -477,12 +648,13 @@ namespace ams::ldr::hoc::pcv::erista {
} }
} }
// ViewLog();
for (auto &entry : patches) { for (auto &entry : patches) {
LOGGING("%s Count: %zu", entry.description, entry.patched_count); LOGGING("%s Count: %zu\n", entry.description, entry.patched_count);
if (R_FAILED(entry.CheckResult())) { if (R_FAILED(entry.CheckResult())) {
#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) // ViewLog();
panic::SmcError(panic::Patch); panic::SmcError(panic::Patch);
#endif
CRASH(entry.description); CRASH(entry.description);
} }

View File

@@ -26,9 +26,6 @@
namespace ams::ldr::hoc::pcv::erista { namespace ams::ldr::hoc::pcv::erista {
static u32 maxEmcClocks[] = { C.eristaEmcMaxClock2, C.eristaEmcMaxClock1, C.eristaEmcMaxClock, };
#define GET_MAX_OF_ARR(ARR) (*std::max_element(ARR, ARR + std::size(ARR)))
constexpr cvb_entry_t CpuCvbTableDefault[] = { constexpr cvb_entry_t CpuCvbTableDefault[] = {
// CPU_PLL_CVB_TABLE_ODN // CPU_PLL_CVB_TABLE_ODN
{ 204000, {721094}, { } }, { 204000, {721094}, { } },
@@ -51,16 +48,16 @@ namespace ams::ldr::hoc::pcv::erista {
}; };
constexpr u32 CpuVoltOfficial = 1227; constexpr u32 CpuVoltOfficial = 1227;
constexpr u32 CpuVminOfficial = 825; constexpr u32 CpuVminOfficial = 825;
constexpr u32 CpuTune0Low = 0xFFEAD0FF;
constexpr u32 CpuVoltL4T = 1257'000; constexpr u32 CpuVoltL4T = 1257'000;
static const u32 cpuVoltDvfsPattern[] = { 1227, 1000, 100, 1000, 0 }; static const u32 cpuVoltDvfsPattern[] = { 1227, 1000, 100, 1000, 0 };
static_assert(sizeof(cpuVoltDvfsPattern) == 0x14, "invalid cpuVoltDvfsPattern size"); static_assert(sizeof(cpuVoltDvfsPattern) == 0x14, "Invalid cpuVoltDvfsPattern size");
static const u32 cpuVoltageThermalPattern[] = { 950, 1132, 0, 950, 1227, 0, 825, 1227, 15000, 825, 1170, 60000, 825, 1132, 80000 }; static const u32 cpuVoltageThermalPattern[] = { 950, 1132, 0, 950, 1227, 0, 825, 1227, 15000, 825, 1170, 60000, 825, 1132, 80000 };
static_assert(sizeof(cpuVoltageThermalPattern) == 0x3c, "invalid cpuVoltageThermalPattern size"); static_assert(sizeof(cpuVoltageThermalPattern) == 0x3c, "Invalid cpuVoltageThermalPattern size");
constexpr u32 GpuClkPllLimit = 2'600'000; constexpr u32 GpuClkPllLimit = 2'600'000;
constexpr u32 GpuClkPllMax = 921'600'000; constexpr u32 GpuClkPllMax = 921'600'000;
@@ -72,7 +69,7 @@ namespace ams::ldr::hoc::pcv::erista {
static_assert(sizeof(gpuVoltDvfsPattern) == (sizeof(u32) * 6), "Invalid gpuVoltDvfsPattern"); static_assert(sizeof(gpuVoltDvfsPattern) == (sizeof(u32) * 6), "Invalid gpuVoltDvfsPattern");
static const u32 gpuVoltThermalPattern[] = { 950, 1132, 0, 810, 1132, 15000, 810, 1132, 30000, 810, 1132, 50000, 810, 1132, 70000, 810, 1132, 105000 }; static const u32 gpuVoltThermalPattern[] = { 950, 1132, 0, 810, 1132, 15000, 810, 1132, 30000, 810, 1132, 50000, 810, 1132, 70000, 810, 1132, 105000 };
static_assert(sizeof(gpuVoltThermalPattern) == 0x48, "invalid gpuVoltageThermalPattern size"); static_assert(sizeof(gpuVoltThermalPattern) == 0x48, "Invalid gpuVoltageThermalPattern size");
/* GPU Max Clock asm Pattern: /* GPU Max Clock asm Pattern:
* *
@@ -109,8 +106,11 @@ namespace ams::ldr::hoc::pcv::erista {
{ }, { },
}; };
constexpr u32 MemVoltHOS = 1125'000; constexpr u32 EmcListDefault[] = { 40800, 68000, 102000, 204000, 408000, 665600, 800000, 1065600, 1331200, 1600000, };
constexpr u32 EmcClkMinFreq = 40800; /* 40.8 MHz table only exists on erista. */ constexpr u32 EmcListSizeDefault = std::size(EmcListDefault);
constexpr u32 EmcListEndDefault = EmcListSizeDefault - 1;
constexpr u32 MemVoltHOS = 1125'000;
constexpr u32 EmcClkPllmLimit = 1866'000'000; constexpr u32 EmcClkPllmLimit = 1866'000'000;
constexpr u32 MTC_TABLE_REV = 7; constexpr u32 MTC_TABLE_REV = 7;
@@ -123,13 +123,13 @@ namespace ams::ldr::hoc::pcv::erista {
enum DramId { enum DramId {
ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0, ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0,
ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1, ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1,
ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC = 2, /* This doesn't have a table in pcv? Wtf? */ ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC = 2,
ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4, ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4,
ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7, /* No table, but expected */ ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7,
}; };
enum MtcTableIndex { enum MtcTableIndex {
T210SdevEmcDvfsTableS4gb01 = 0, /* HB-MGCH */ T210SdevEmcDvfsTableS4gb01 = 0, /* HB-MGCH, WT:C */
T210SdevEmcDvfsTableS6gb01 = 1, /* HM-MGCH */ T210SdevEmcDvfsTableS6gb01 = 1, /* HM-MGCH */
T210SdevEmcDvfsTableH4gb01 = 2, /* HR-NLE */ T210SdevEmcDvfsTableH4gb01 = 2, /* HR-NLE */
MtcTableIndex_Invalid = 3, MtcTableIndex_Invalid = 3,
@@ -140,12 +140,24 @@ namespace ams::ldr::hoc::pcv::erista {
MtcTableIndex index; MtcTableIndex index;
}; };
constexpr MtcDramIndex mtcIndexTable[] = { const inline MtcDramIndex mtcIndexTable[] = {
{ ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH, T210SdevEmcDvfsTableS4gb01, }, { ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH, T210SdevEmcDvfsTableS4gb01, },
{ ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH, T210SdevEmcDvfsTableS6gb01, }, { ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC, T210SdevEmcDvfsTableS4gb01, },
{ ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE, T210SdevEmcDvfsTableH4gb01, }, { ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH, T210SdevEmcDvfsTableS6gb01, },
{ ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE, T210SdevEmcDvfsTableH4gb01, },
}; };
constexpr u32 MtcBrAsm = 0xD61F0140;
constexpr u32 MtcMovAsm = 0x52800148;
constexpr u32 MtcAdrpAsm = 0xD0000081;
constexpr u32 MtcBlIns = 0x97ffae64;
constexpr u32 MtcAddAsm = 0x91131821;
ALWAYS_INLINE bool MemMtcGetGetTablePatternFn(u32 *ptr) {
/* This builds an address that gets returned, so the register must be x0 by convention. */
return AsmCompareAddNoImm12(*ptr, MtcAddAsm);
}
void Patch(uintptr_t mapped_nso, size_t nso_size); void Patch(uintptr_t mapped_nso, size_t nso_size);
} }

View File

@@ -3,6 +3,8 @@
* *
* Copyright (c) 2023 hanai3Bi * Copyright (c) 2023 hanai3Bi
* *
* Copyright (c) B3711
*
* Copyright (c) Souldbminer and Horizon OC Contributors * Copyright (c) Souldbminer and Horizon OC Contributors
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@@ -50,15 +52,17 @@ namespace ams::ldr::hoc::pcv::mariko {
R_THROW(ldr::ResultInvalidGpuDvfs()); R_THROW(ldr::ResultInvalidGpuDvfs());
} }
if (!C.marikoGpuVmin) { if (C.marikoGpuBootVolt) {
R_SKIP(); PATCH_OFFSET(ptr - 3, C.marikoGpuBootVolt);
} }
PATCH_OFFSET(ptr, C.marikoGpuVmin); if (C.marikoGpuVmin) {
PATCH_OFFSET(ptr + 3, C.marikoGpuVmin); PATCH_OFFSET(ptr, C.marikoGpuVmin);
PATCH_OFFSET(ptr + 6, C.marikoGpuVmin); PATCH_OFFSET(ptr + 3, C.marikoGpuVmin);
PATCH_OFFSET(ptr + 9, C.marikoGpuVmin); PATCH_OFFSET(ptr + 6, C.marikoGpuVmin);
PATCH_OFFSET(ptr + 12, C.marikoGpuVmin); PATCH_OFFSET(ptr + 9, C.marikoGpuVmin);
PATCH_OFFSET(ptr + 12, C.marikoGpuVmin);
}
R_SUCCEED(); R_SUCCEED();
} }
@@ -79,37 +83,44 @@ namespace ams::ldr::hoc::pcv::mariko {
Result CpuFreqVdd(u32 *ptr) { Result CpuFreqVdd(u32 *ptr) {
dvfs_rail *entry = reinterpret_cast<dvfs_rail *>(reinterpret_cast<u8 *>(ptr) - offsetof(dvfs_rail, freq)); dvfs_rail *entry = reinterpret_cast<dvfs_rail *>(reinterpret_cast<u8 *>(ptr) - offsetof(dvfs_rail, freq));
R_UNLESS(entry->id == 1, ldr::ResultInvalidCpuFreqVddEntry()); R_UNLESS(entry->id == 1, ldr::ResultInvalidCpuFreqVddEntry());
R_UNLESS(entry->min_mv == 250'000, ldr::ResultInvalidCpuFreqVddEntry()); R_UNLESS(entry->min_mv == 250'000, ldr::ResultInvalidCpuFreqVddEntry());
R_UNLESS(entry->step_mv == 5000, ldr::ResultInvalidCpuFreqVddEntry()); R_UNLESS(entry->step_mv == 5000, ldr::ResultInvalidCpuFreqVddEntry());
R_UNLESS(entry->max_mv == 1525'000, ldr::ResultInvalidCpuFreqVddEntry()); R_UNLESS(entry->max_mv == 1525'000, ldr::ResultInvalidCpuFreqVddEntry());
if (C.marikoCpuUVHigh) { if (C.marikoCpuUVHigh) {
PATCH_OFFSET(ptr, CapCpuClock()); PATCH_OFFSET(ptr, CapCpuClock());
} else { } else {
PATCH_OFFSET(ptr, GetDvfsTableLastEntry(C.marikoCpuDvfsTable)->freq); PATCH_OFFSET(ptr, GetDvfsTableLastEntry(C.marikoCpuDvfsTable)->freq);
} }
R_SUCCEED(); R_SUCCEED();
} }
Result CpuVoltDVFS(u32 *ptr) { Result CpuVoltDVFS(u32 *ptr) {
if (MatchesPattern(ptr, cpuVoltagePatchOffsets, cpuVoltagePatchValues)) { CvbMeta *cpuCvbMeta = reinterpret_cast<CvbMeta *>(reinterpret_cast<u8 *>(ptr) - offsetof(CvbMeta, vmin));
if (C.marikoCpuLowVmin) {
PATCH_OFFSET(ptr, C.marikoCpuLowVmin);
}
if (C.marikoCpuHighVmin) { R_UNLESS(cpuCvbMeta->highVmin == CpuHighVminOfficial, ldr::ResultInvalidCpuMinVolt());
PATCH_OFFSET(ptr - 2, C.marikoCpuHighVmin); R_UNLESS(cpuCvbMeta->unkStepMaybe == 38, ldr::ResultInvalidCpuMinVolt());
} R_UNLESS(cpuCvbMeta->vmax == CpuVoltOfficial, ldr::ResultInvalidCpuMinVolt());
R_UNLESS(cpuCvbMeta->unkScale2 == 1000, ldr::ResultInvalidCpuMinVolt());
R_UNLESS(cpuCvbMeta->speedoScale == 100, ldr::ResultInvalidCpuMinVolt());
R_UNLESS(cpuCvbMeta->voltageScale == 1000, ldr::ResultInvalidCpuMinVolt());
R_UNLESS(cpuCvbMeta->unkZero5 == 0, ldr::ResultInvalidCpuMinVolt());
if (C.marikoCpuMaxVolt) { if (C.marikoCpuLowVmin) {
PATCH_OFFSET(ptr + 5, C.marikoCpuMaxVolt); PATCH_OFFSET(&(cpuCvbMeta->vmin), C.marikoCpuLowVmin);
}
R_SUCCEED();
} }
R_THROW(ldr::ResultInvalidCpuMinVolt()); if (C.marikoCpuHighVmin) {
PATCH_OFFSET(&(cpuCvbMeta->highVmin), C.marikoCpuHighVmin);
}
if (C.marikoCpuMaxVolt) {
PATCH_OFFSET(&(cpuCvbMeta->vmax), C.marikoCpuMaxVolt);
}
R_SUCCEED();
} }
Result CpuVoltThermals(u32 *ptr) { Result CpuVoltThermals(u32 *ptr) {
@@ -133,80 +144,80 @@ namespace ams::ldr::hoc::pcv::mariko {
} }
Result CpuVoltDfll(u32 *ptr) { Result CpuVoltDfll(u32 *ptr) {
cvb_cpu_dfll_data *entry = reinterpret_cast<cvb_cpu_dfll_data *>(ptr); CvbCpuDfllData *entry = reinterpret_cast<CvbCpuDfllData *>(ptr);
R_UNLESS(entry->tune0_low == 0xFFCF, ldr::ResultInvalidCpuVoltDfllEntry()); R_UNLESS(entry->tune0_low == 0xFFCF, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune0_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); R_UNLESS(entry->tune0_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune1_low == 0x12207FF, ldr::ResultInvalidCpuVoltDfllEntry()); R_UNLESS(entry->tune1_low == 0x12207FF, ldr::ResultInvalidCpuVoltDfllEntry());
R_UNLESS(entry->tune1_high == 0x3FFF7FF, ldr::ResultInvalidCpuVoltDfllEntry()); R_UNLESS(entry->tune1_high == 0x3FFF7FF, ldr::ResultInvalidCpuVoltDfllEntry());
switch (C.marikoCpuUVLow) { switch (C.marikoCpuUVLow) {
case 1: case 1:
PATCH_OFFSET(&(entry->tune0_low), 0xffa0); PATCH_OFFSET(&(entry->tune0_low), 0xffa0);
PATCH_OFFSET(&(entry->tune0_high), 0xffff); PATCH_OFFSET(&(entry->tune0_high), 0xffff);
PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); PATCH_OFFSET(&(entry->tune1_low), 0x21107ff);
PATCH_OFFSET(&(entry->tune1_high), 0); PATCH_OFFSET(&(entry->tune1_high), 0x0);
break; break;
case 2: case 2:
PATCH_OFFSET(&(entry->tune0_high), 0xffdf); PATCH_OFFSET(&(entry->tune0_high), 0xffdf);
PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); PATCH_OFFSET(&(entry->tune1_low), 0x21107ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27207ff); PATCH_OFFSET(&(entry->tune1_high), 0x27207ff);
break; break;
case 3: case 3:
PATCH_OFFSET(&(entry->tune0_low), 0xffdf); PATCH_OFFSET(&(entry->tune0_low), 0xffdf);
PATCH_OFFSET(&(entry->tune0_high), 0xffdf); PATCH_OFFSET(&(entry->tune0_high), 0xffdf);
PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); PATCH_OFFSET(&(entry->tune1_low), 0x21107ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27307ff); PATCH_OFFSET(&(entry->tune1_high), 0x27307ff);
break; break;
case 4: case 4:
PATCH_OFFSET(&(entry->tune0_low), 0xffff); PATCH_OFFSET(&(entry->tune0_low), 0xffff);
PATCH_OFFSET(&(entry->tune0_high), 0xffdf); PATCH_OFFSET(&(entry->tune0_high), 0xffdf);
PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); PATCH_OFFSET(&(entry->tune1_low), 0x21107ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27407ff); PATCH_OFFSET(&(entry->tune1_high), 0x27407ff);
break; break;
case 5: case 5:
PATCH_OFFSET(&(entry->tune0_high), 0xffdf); PATCH_OFFSET(&(entry->tune0_high), 0xffdf);
PATCH_OFFSET(&(entry->tune1_low), 0x21607ff); PATCH_OFFSET(&(entry->tune1_low), 0x21607ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27707ff); PATCH_OFFSET(&(entry->tune1_high), 0x27707ff);
break; break;
case 6: case 6:
PATCH_OFFSET(&(entry->tune0_high), 0xffdf); PATCH_OFFSET(&(entry->tune0_high), 0xffdf);
PATCH_OFFSET(&(entry->tune1_low), 0x21607ff); PATCH_OFFSET(&(entry->tune1_low), 0x21607ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27807ff); PATCH_OFFSET(&(entry->tune1_high), 0x27807ff);
break; break;
case 7: case 7:
PATCH_OFFSET(&(entry->tune0_high), 0xdfff); PATCH_OFFSET(&(entry->tune0_high), 0xdfff);
PATCH_OFFSET(&(entry->tune1_low), 0x21607ff); PATCH_OFFSET(&(entry->tune1_low), 0x21607ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27b07ff); PATCH_OFFSET(&(entry->tune1_high), 0x27b07ff);
break; break;
case 8: case 8:
PATCH_OFFSET(&(entry->tune0_low), 0xdfff); PATCH_OFFSET(&(entry->tune0_low), 0xdfff);
PATCH_OFFSET(&(entry->tune0_high), 0xdfff); PATCH_OFFSET(&(entry->tune0_high), 0xdfff);
PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); PATCH_OFFSET(&(entry->tune1_low), 0x21707ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27b07ff); PATCH_OFFSET(&(entry->tune1_high), 0x27b07ff);
break; break;
case 9: case 9:
PATCH_OFFSET(&(entry->tune0_low), 0xdfff); PATCH_OFFSET(&(entry->tune0_low), 0xdfff);
PATCH_OFFSET(&(entry->tune0_high), 0xdfff); PATCH_OFFSET(&(entry->tune0_high), 0xdfff);
PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); PATCH_OFFSET(&(entry->tune1_low), 0x21707ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27c07ff); PATCH_OFFSET(&(entry->tune1_high), 0x27c07ff);
break; break;
case 10: case 10:
PATCH_OFFSET(&(entry->tune0_low), 0xdfff); PATCH_OFFSET(&(entry->tune0_low), 0xdfff);
PATCH_OFFSET(&(entry->tune0_high), 0xdfff); PATCH_OFFSET(&(entry->tune0_high), 0xdfff);
PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); PATCH_OFFSET(&(entry->tune1_low), 0x21707ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27d07ff); PATCH_OFFSET(&(entry->tune1_high), 0x27d07ff);
break; break;
case 11: case 11:
PATCH_OFFSET(&(entry->tune0_low), 0xdfff); PATCH_OFFSET(&(entry->tune0_low), 0xdfff);
PATCH_OFFSET(&(entry->tune0_high), 0xdfff); PATCH_OFFSET(&(entry->tune0_high), 0xdfff);
PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); PATCH_OFFSET(&(entry->tune1_low), 0x21707ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27e07ff); PATCH_OFFSET(&(entry->tune1_high), 0x27e07ff);
break; break;
case 12: case 12:
PATCH_OFFSET(&(entry->tune0_low), 0xdfff); PATCH_OFFSET(&(entry->tune0_low), 0xdfff);
PATCH_OFFSET(&(entry->tune0_high), 0xdfff); PATCH_OFFSET(&(entry->tune0_high), 0xdfff);
PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); PATCH_OFFSET(&(entry->tune1_low), 0x21707ff);
PATCH_OFFSET(&(entry->tune1_high), 0x27f07ff); PATCH_OFFSET(&(entry->tune1_high), 0x27f07ff);
break; break;
default: default:
@@ -215,7 +226,7 @@ namespace ams::ldr::hoc::pcv::mariko {
switch (C.marikoCpuUVHigh) { switch (C.marikoCpuUVHigh) {
case 1: case 1:
PATCH_OFFSET(&(entry->tune1_high), 0); PATCH_OFFSET(&(entry->tune1_high), 0x0);
PATCH_OFFSET(&(entry->tune0_high), 0xffff); PATCH_OFFSET(&(entry->tune0_high), 0xffff);
break; break;
case 2: case 2:
@@ -279,12 +290,6 @@ namespace ams::ldr::hoc::pcv::mariko {
R_THROW(ldr::ResultInvalidGpuFreqMaxPattern()); R_THROW(ldr::ResultInvalidGpuFreqMaxPattern());
} }
/* Verify the limit. */
/* TODO: Make this a little bit cleaner at some point. */
if (AsmGetImm16(ins1) != (GpuClkOsLimit & 0xFFFF) || AsmGetImm16(ins2) != (GpuClkOsLimit >> 16)) {
R_THROW(ldr::ResultInvalidGpuFreqMaxPattern());
}
u32 max_clock; u32 max_clock;
switch (C.marikoGpuUV) { switch (C.marikoGpuUV) {
case 0: case 0:
@@ -296,8 +301,14 @@ namespace ams::ldr::hoc::pcv::mariko {
case 2: case 2:
max_clock = GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT)->freq; max_clock = GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT)->freq;
break; break;
case 3:
max_clock = GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT15)->freq;
break;
case 4:
max_clock = GetDvfsTableLastEntry(C.marikoGpuDvfsTableHighUV)->freq;
break;
default: default:
max_clock = GetDvfsTableLastEntry(C.marikoGpuDvfsTable)->freq; max_clock = GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT)->freq;
break; break;
} }
@@ -306,7 +317,7 @@ namespace ams::ldr::hoc::pcv::mariko {
asm_set_rd(asm_set_imm16(GpuAsmPattern[1], max_clock >> 16), rd) asm_set_rd(asm_set_imm16(GpuAsmPattern[1], max_clock >> 16), rd)
}; };
PATCH_OFFSET(ptr32, asm_patch[0]); PATCH_OFFSET(ptr32, asm_patch[0]);
PATCH_OFFSET(ptr32 + 1, asm_patch[1]); PATCH_OFFSET(ptr32 + 1, asm_patch[1]);
R_SUCCEED(); R_SUCCEED();
@@ -371,7 +382,7 @@ namespace ams::ldr::hoc::pcv::mariko {
} }
u32 trefbw = refresh_raw + 0x40; u32 trefbw = refresh_raw + 0x40;
trefbw = MIN(trefbw, static_cast<u32>(0x3FFF)); trefbw = MIN(trefbw, static_cast<u32>(0x3FFF));
const u32 dyn_self_ref_control = (static_cast<u32>(7605.0 / tCK_avg) + 260) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000); const u32 dyn_self_ref_control = (static_cast<u32>(7605.0 / tCK_avg) + 260) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000);
@@ -379,7 +390,7 @@ namespace ams::ldr::hoc::pcv::mariko {
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD)); WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast<u32>(0xB8))); WRITE_PARAM_ALL_REG(table, emc_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast<u32>(0xB9)));
WRITE_PARAM_ALL_REG(table, emc_ras, MIN(GET_CYCLE_CEIL(tRAS), static_cast<u32>(0x7F))); WRITE_PARAM_ALL_REG(table, emc_ras, MIN(GET_CYCLE_CEIL(tRAS), static_cast<u32>(0x7F)));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD)); WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb)); WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb));
@@ -438,22 +449,21 @@ namespace ams::ldr::hoc::pcv::mariko {
WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, rdv); WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, rdv);
WRITE_PARAM_ALL_REG(table, emc_rdv_mask, rdv + 2); WRITE_PARAM_ALL_REG(table, emc_rdv_mask, rdv + 2);
WRITE_PARAM_ALL_REG(table, emc_tr_rdv, rdv); WRITE_PARAM_ALL_REG(table, emc_tr_rdv, rdv);
/* TODO: Check this out again at some point. */
WRITE_PARAM_ALL_REG(table, emc_cmd_brlshft_2, 0x24); WRITE_PARAM_ALL_REG(table, emc_cmd_brlshft_2, 0x24);
WRITE_PARAM_ALL_REG(table, emc_cmd_brlshft_3, 0x24); WRITE_PARAM_ALL_REG(table, emc_cmd_brlshft_3, 0x24);
/* This needs some clean up. */ /* This needs some clean up. */
constexpr double MC_ARB_DIV = 4.0; constexpr double MC_ARB_DIV = 4.0;
constexpr u32 MC_ARB_SFA = 2; constexpr u32 MC_ARB_SFA = 2;
table->burst_mc_regs.mc_emem_arb_cfg = table->rate_khz / (33.3 * 1000) / MC_ARB_DIV; table->burst_mc_regs.mc_emem_arb_cfg = table->rate_khz / (33.3 * 1000) / MC_ARB_DIV;
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2; table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2; table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(tR2P / MC_ARB_DIV); table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(tR2P / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(tW2P / MC_ARB_DIV) + MC_ARB_SFA; table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(tW2P / MC_ARB_DIV) + MC_ARB_SFA;
@@ -526,12 +536,12 @@ namespace ams::ldr::hoc::pcv::mariko {
table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & Mask2) | allowance1; table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & Mask2) | allowance1;
table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & Mask2) | allowance1; table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & Mask2) | allowance1;
table->dram_timings.t_rp = tRFCpb; table->dram_timings.t_rp = tRFCpb;
table->dram_timings.t_rfc = tRFCab; table->dram_timings.t_rfc = tRFCab;
table->dram_timings.rl = RL; table->dram_timings.rl = RL;
table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast<u32>(mrw2); table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast<u32>(mrw2);
table->emc_cfg_2 = 0x11083D; table->emc_cfg_2 = 0x11083D;
} }
void MemMtcPllmbDivisor(MarikoMtcTable *table) { void MemMtcPllmbDivisor(MarikoMtcTable *table) {
@@ -544,11 +554,11 @@ namespace ams::ldr::hoc::pcv::mariko {
bool remainder_check = (table->rate_khz - PllOscInKHz * (table->rate_khz / PllOscInKHz)) > (table->rate_khz - PllOscHalfKHz * divm_candidate_half) && static_cast<int>(((target_freq_d / PllOscHalfKHz - divm_candidate_half - 0.5) * 8192.0)) != 0; bool remainder_check = (table->rate_khz - PllOscInKHz * (table->rate_khz / PllOscInKHz)) > (table->rate_khz - PllOscHalfKHz * divm_candidate_half) && static_cast<int>(((target_freq_d / PllOscHalfKHz - divm_candidate_half - 0.5) * 8192.0)) != 0;
u32 divm_final = remainder_check + 1; u32 divm_final = remainder_check + 1;
table->pllmb_divm = divm_final; table->pllmb_divm = divm_final;
double div_step_d = static_cast<double>(PllOscInKHz) / divm_final; double div_step_d = static_cast<double>(PllOscInKHz) / divm_final;
s32 divn_integer = static_cast<u8>(table->rate_khz / div_step_d); s32 divn_integer = static_cast<u8>(table->rate_khz / div_step_d);
table->pllmb_divn = divn_integer; table->pllmb_divn = divn_integer;
u32 divn_fraction = static_cast<s32>((target_freq_d / div_step_d - divn_integer - 0.5) * 8192.0); u32 divn_fraction = static_cast<s32>((target_freq_d / div_step_d - divn_integer - 0.5) * 8192.0);
@@ -559,34 +569,34 @@ namespace ams::ldr::hoc::pcv::mariko {
s32 divn_fraction_ssc = static_cast<s32>((actual_freq_khz * 0.997 / div_step_d - divn_integer - 0.5) * 8192.0); s32 divn_fraction_ssc = static_cast<s32>((actual_freq_khz * 0.997 / div_step_d - divn_integer - 0.5) * 8192.0);
double delta_scaled = (0.3 / div_step_d + 0.3 / div_step_d) * (divn_fraction - divn_fraction_ssc); double delta_scaled = (0.3 / div_step_d + 0.3 / div_step_d) * (divn_fraction - divn_fraction_ssc);
s32 delta_int = static_cast<s32>(delta_scaled); s32 delta_int = static_cast<s32>(delta_scaled);
double delta_frac = delta_scaled - delta_int; double delta_frac = delta_scaled - delta_int;
u32 setup_value = 0; u32 setup_value = 0;
if (delta_frac <= 0.5) { if (delta_frac <= 0.5) {
double round_val = (delta_int + ROUND(delta_frac + delta_frac)) ? 0.5 : 0.0; double round_val = (delta_int + ROUND(delta_frac + delta_frac)) ? 0.5 : 0.0;
setup_value = ROUND(delta_frac + delta_frac) ? static_cast<u32>(round_val + round_val) | 0x1000 : static_cast<u32>(round_val); setup_value = ROUND(delta_frac + delta_frac) ? static_cast<u32>(round_val + round_val) | 0x1000 : static_cast<u32>(round_val);
} else { } else {
s32 frac_doubled = ROUND(delta_frac - 0.5 + delta_frac - 0.5); s32 frac_doubled = ROUND(delta_frac - 0.5 + delta_frac - 0.5);
double round_val = 1.0; double round_val = 1.0;
setup_value = frac_doubled ? static_cast<u32>(round_val) : static_cast<u32>(round_val + round_val) | 0x1000; setup_value = frac_doubled ? static_cast<u32>(round_val) : static_cast<u32>(round_val + round_val) | 0x1000;
} }
u32 ctrl1 = static_cast<u16>(divn_fraction_ssc) | (static_cast<u16>(divn_fraction) << 16); u32 ctrl1 = static_cast<u16>(divn_fraction_ssc) | (static_cast<u16>(divn_fraction) << 16);
u32 ctrl2 = static_cast<u16>(divn_fraction) | (static_cast<u16>(setup_value) << 16); u32 ctrl2 = static_cast<u16>(divn_fraction) | (static_cast<u16>(setup_value) << 16);
table->pllm_ss_ctrl1 = ctrl1; table->pllm_ss_ctrl1 = ctrl1;
table->pllm_ss_ctrl2 = ctrl2; table->pllm_ss_ctrl2 = ctrl2;
table->pllmb_ss_ctrl1 = ctrl1; table->pllmb_ss_ctrl1 = ctrl1;
table->pllmb_ss_ctrl2 = ctrl2; table->pllmb_ss_ctrl2 = ctrl2;
} else { } else {
table->pllm_ss_cfg &= 0xBFFFFFFF; table->pllm_ss_cfg &= 0xBFFFFFFF;
table->pllmb_ss_cfg &= 0xBFFFFFFF; table->pllmb_ss_cfg &= 0xBFFFFFFF;
u64 pair = (static_cast<u64>(divn_fraction) << 32) | static_cast<u64>(table->rate_khz); u64 pair = (static_cast<u64>(divn_fraction) << 32) | static_cast<u64>(table->rate_khz);
u32 pll_misc = (table->pllm_ss_ctrl2 & 0xFFFF0000) | static_cast<u32>((pair - actual_freq_khz) >> 32); u32 pll_misc = (table->pllm_ss_ctrl2 & 0xFFFF0000) | static_cast<u32>((pair - actual_freq_khz) >> 32);
table->pllm_ss_ctrl2 = pll_misc; table->pllm_ss_ctrl2 = pll_misc;
table->pllmb_ss_ctrl2 = pll_misc; table->pllmb_ss_ctrl2 = pll_misc;
} }
} }
@@ -615,15 +625,34 @@ namespace ams::ldr::hoc::pcv::mariko {
newEmcList.resize(std::min(newEmcList.size(), DvfsTableEntryLimit)); newEmcList.resize(std::min(newEmcList.size(), DvfsTableEntryLimit));
} }
void MtcGenerateFreqTables() { void MtcGenerate133StepTable() {
if (C.marikoEmcMaxClock <= EmcClkOSLimit) { const u32 stepFreqs133[] = { 1733000, 1866000, 2000000, 2133000, 2266000, 2400000, 2533000, 2666000, 2800000, 2933000, 3066000, 3200000, 3333000, 3466000, }; // Avoid rounding issues
return; constexpr u32 StepFreqs133Size = std::size(stepFreqs133);
for (u32 i = 0; i < StepFreqs133Size; ++i) {
if (stepFreqs133[i] <= C.marikoEmcMaxClock) {
newEmcList.push_back(stepFreqs133[i]);
} else {
break;
}
} }
if (newEmcList.back() != C.marikoEmcMaxClock) {
newEmcList.push_back(static_cast<u32>(C.marikoEmcMaxClock));
}
newEmcList.resize(std::min(newEmcList.size(), DvfsTableEntryLimit));
}
void MtcGenerateFreqTables() {
newEmcList.clear(); newEmcList.clear();
newEmcList.reserve(DvfsTableEntryCount); newEmcList.reserve(DvfsTableEntryCount);
newEmcList.insert(newEmcList.end(), std::begin(EmcListDefault), std::end(EmcListDefault)); newEmcList.insert(newEmcList.end(), std::begin(EmcListDefault), std::end(EmcListDefault));
if (C.marikoEmcMaxClock <= EmcClkOSLimit) {
return;
}
u32 stepRate = 0; u32 stepRate = 0;
switch (C.stepMode) { switch (C.stepMode) {
case StepMode_66MHz: case StepMode_66MHz:
@@ -635,6 +664,9 @@ namespace ams::ldr::hoc::pcv::mariko {
case StepMode_Jedec: case StepMode_Jedec:
MtcGenerateJedecTable(); MtcGenerateJedecTable();
return; return;
case StepMode_133MHz:
MtcGenerate133StepTable();
return;
default: default:
stepRate = 66667; stepRate = 66667;
break; break;
@@ -665,7 +697,7 @@ namespace ams::ldr::hoc::pcv::mariko {
Result MtcValidateAllTables(MarikoMtcTable *tableStart, const u32 *validationList, u32 tableCount) { Result MtcValidateAllTables(MarikoMtcTable *tableStart, const u32 *validationList, u32 tableCount) {
for (u32 i = 0; i < tableCount; ++i) { for (u32 i = 0; i < tableCount; ++i) {
R_UNLESS(R_SUCCEEDED(VerifyMtcTable(&tableStart[i], validationList[i])), ldr::ResultInvalidMtcTable()); R_TRY(VerifyMtcTable(&tableStart[i], validationList[i]));
} }
R_SUCCEED(); R_SUCCEED();
@@ -687,9 +719,9 @@ namespace ams::ldr::hoc::pcv::mariko {
return MtcTableIndex_Invalid; return MtcTableIndex_Invalid;
} }
NORETURN void AbortInvalidDramId() { NORETURN void AbortInvalidMtc(const char *crashMsg) {
panic::SmcError(panic::Emc); panic::SmcError(panic::Emc);
CRASH("Invalid dram id\n"); CRASH(crashMsg);
} }
u32 GetMtcOffset(MtcTableIndex index) { u32 GetMtcOffset(MtcTableIndex index) {
@@ -718,12 +750,7 @@ namespace ams::ldr::hoc::pcv::mariko {
} }
} }
bool patchedMtc = false;
Result MemFreqMtcTable(u32 *ptr) { Result MemFreqMtcTable(u32 *ptr) {
if (C.marikoEmcMaxClock <= EmcClkOSLimit || patchedMtc) {
R_SKIP();
}
static const DramId dramId = [] { static const DramId dramId = [] {
DramId id = GetDramId(); DramId id = GetDramId();
return id; return id;
@@ -733,7 +760,7 @@ namespace ams::ldr::hoc::pcv::mariko {
MtcTableIndex idx = GetMtcDramIndex(dramId); MtcTableIndex idx = GetMtcDramIndex(dramId);
/* If for some reason this happens, there is no chance of recovering this. */ /* If for some reason this happens, there is no chance of recovering this. */
if (idx == MtcTableIndex_Invalid) { if (idx == MtcTableIndex_Invalid) {
AbortInvalidDramId(); AbortInvalidMtc("Invalid dramId");
} }
return idx; return idx;
}(); }();
@@ -742,22 +769,26 @@ namespace ams::ldr::hoc::pcv::mariko {
static const u32 mtcOffset = GetMtcOffset(mtcIndex); static const u32 mtcOffset = GetMtcOffset(mtcIndex);
/* Offset from 1600MHz pointer to 204Mhz table start. */ /* Offset from 1600MHz pointer to 204Mhz table start. */
constexpr u32 StartAdjustment = offsetof(MarikoMtcTable, rate_khz) + sizeof(MarikoMtcTable) * 2; constexpr u32 StartAdjustment = offsetof(MarikoMtcTable, rate_khz) + sizeof(MarikoMtcTable) * (mariko::MtcTableCountDefault - 1);
u8 *startPtr = reinterpret_cast<u8 *>(ptr) - StartAdjustment; u8 *startPtr = reinterpret_cast<u8 *>(ptr) - StartAdjustment;
MarikoMtcTable *table = reinterpret_cast<MarikoMtcTable *>(startPtr + mtcOffset); MarikoMtcTable *table = reinterpret_cast<MarikoMtcTable *>(startPtr + mtcOffset);
R_UNLESS(R_SUCCEEDED(MtcValidateAllTables(table, EmcListDefault, EmcListSizeDefault)), ldr::ResultInvalidMtcTable()); R_TRY(MtcValidateAllTables(table, EmcListDefault, EmcListSizeDefault));
PrepareMtcMemoryRegion(startPtr, table); PrepareMtcMemoryRegion(startPtr, table);
table = reinterpret_cast<MarikoMtcTable *>(startPtr); table = reinterpret_cast<MarikoMtcTable *>(startPtr);
if (R_FAILED(MtcValidateAllTables(table, EmcListDefault, EmcListSizeDefault))) { if (R_FAILED(MtcValidateAllTables(table, EmcListDefault, EmcListSizeDefault))) {
panic::SmcError(panic::Emc); AbortInvalidMtc("Failed mtc validation");
}
if (C.marikoEmcMaxClock <= EmcClkOSLimit) {
R_SKIP();
} }
MtcExtendTables(table); MtcExtendTables(table);
if (R_FAILED(MtcValidateAllTables(table, newEmcList.data(), newEmcList.size()))) { if (R_FAILED(MtcValidateAllTables(table, newEmcList.data(), newEmcList.size()))) {
panic::SmcError(panic::Emc); AbortInvalidMtc("Failed mtc validation");
} }
for (u32 i = mariko::MtcTableCountDefault; i < newEmcList.size(); ++i) { for (u32 i = mariko::MtcTableCountDefault; i < newEmcList.size(); ++i) {
@@ -765,7 +796,6 @@ namespace ams::ldr::hoc::pcv::mariko {
MemMtcPllmbDivisor(&table[i]); MemMtcPllmbDivisor(&table[i]);
} }
patchedMtc = true;
R_SUCCEED(); R_SUCCEED();
} }
@@ -782,33 +812,82 @@ namespace ams::ldr::hoc::pcv::mariko {
R_SKIP(); R_SKIP();
} }
s32 max0 = 1050;
s32 max1 = 1025;
s32 max2 = 1000;
s32 voltAdd = 25 * C.emcDvbShift; s32 voltAdd = 25 * C.emcDvbShift;
#define DVB_VOLT(zero, one, two) std::min(zero + voltAdd, 1050), std::min(one + voltAdd, 1025), std::min(two + voltAdd, 1000),
DvbEntry emcDvbTableNew[] = { if (C.marikoSocVmax && C.marikoSocVmax > 1000) {
{ 204000, { 637, 637, 637, } }, max0 = C.marikoSocVmax;
{ 1331200, { 650, 637, 637, } }, max1 = C.marikoSocVmax;
{ 1600000, { 675, 650, 637, } }, max2 = C.marikoSocVmax;
{ 1866000, { DVB_VOLT(700, 675, 650) } }, }
{ 2133000, { DVB_VOLT(725, 700, 675) } },
{ 2400000, { DVB_VOLT(750, 725, 700) } }, constexpr s32 MinVolt = 637;
{ 2666000, { DVB_VOLT(775, 750, 725) } },
{ 2933000, { DVB_VOLT(800, 775, 750) } }, auto ClampVolt = [&](s32 value, s32 max) {
{ 3200000, { DVB_VOLT(800, 800, 775) } }, return std::clamp(value + voltAdd, MinVolt, max);
{ 0xFFFFFFFF, { } },
}; };
u32 j = MtcTableCountDefault; auto DvbVolt = [&](s32 zero, s32 one, s32 two) {
for (u32 i = MtcTableCountDefault; i < newEmcList.size(); ++i) { return std::array<s32, 3>{
if (newEmcList[i] >= emcDvbTableNew[j].freq && newEmcList[i] < emcDvbTableNew[j + 1].freq) { ClampVolt(zero, max0),
emcDvbTableNew[j].freq = newEmcList[i]; ClampVolt(one, max1),
++j; ClampVolt(two, max2)
} else { };
break; };
#define DVB(v) \
static_cast<u32>((v)[0]), \
static_cast<u32>((v)[1]), \
static_cast<u32>((v)[2])
DvbEntry emcDvbOcTableBrackets[] = {
{ 204000, { 637, 637, 637, }, },
{ 1331200, { 650, 637, 637, }, },
{ 1600000, { 675, 650, 637, }, },
{ 1866000, { DVB(DvbVolt( 700, 675, 650)) }, },
{ 2000000, { DVB(DvbVolt( 712, 687, 662)) }, },
{ 2133000, { DVB(DvbVolt( 725, 700, 675)) }, },
{ 2200000, { DVB(DvbVolt( 737, 712, 687)) }, },
{ 2266000, { DVB(DvbVolt( 750, 725, 700)) }, },
{ 2333000, { DVB(DvbVolt( 762, 737, 712)) }, },
{ 2400000, { DVB(DvbVolt( 775, 750, 725)) }, },
{ 2433000, { DVB(DvbVolt( 787, 762, 737)) }, },
{ 2466000, { DVB(DvbVolt( 800, 775, 750)) }, },
{ 2533000, { DVB(DvbVolt( 812, 787, 762)) }, },
{ 2566000, { DVB(DvbVolt( 825, 800, 775)) }, },
{ 2600000, { DVB(DvbVolt( 837, 812, 787)) }, },
{ 2666000, { DVB(DvbVolt( 850, 825, 800)) }, },
{ 2700000, { DVB(DvbVolt( 875, 850, 825)) }, },
{ 2733000, { DVB(DvbVolt( 887, 862, 837)) }, },
{ 2766000, { DVB(DvbVolt( 912, 887, 862)) }, },
{ 2800000, { DVB(DvbVolt( 925, 900, 875)) }, },
{ 2833000, { DVB(DvbVolt( 937, 912, 887)) }, },
{ 2900000, { DVB(DvbVolt( 950, 925, 900)) }, },
{ 2933000, { DVB(DvbVolt( 962, 937, 912)) }, },
{ 3000000, { DVB(DvbVolt( 975, 950, 925)) }, },
{ 3033000, { DVB(DvbVolt( 987, 962, 937)) }, },
{ 3100000, { DVB(DvbVolt(1000, 975, 950)) }, },
{ 3133000, { DVB(DvbVolt(1025, 1000, 975)) }, },
{ 3166000, { DVB(DvbVolt(1037, 1012, 987)) }, },
{ 3200000, { DVB(DvbVolt(1050, 1025, 1000)) }, },
{ ~0u, { }, },
};
#undef DVB
DvbEntry emcDvbTableOc[newEmcList.size()];
u32 bracketIndex = 0;
for (u32 i = 0; i < newEmcList.size(); ++i) {
while (newEmcList[i] >= emcDvbOcTableBrackets[bracketIndex + 1].freq) {
++bracketIndex;
} }
emcDvbTableOc[i].freq = newEmcList[i];
std::memcpy(emcDvbTableOc[i].volt, emcDvbOcTableBrackets[bracketIndex].volt, sizeof(emcDvbTableOc[i].volt));
} }
std::memset(mem_dvb_table_head, 0, sizeof(EmcDvbTableDefault)); std::memset(mem_dvb_table_head, 0, sizeof(EmcDvbTableDefault));
std::memcpy(mem_dvb_table_head, &emcDvbTableNew, sizeof(emcDvbTableNew)); std::memcpy(mem_dvb_table_head, &emcDvbTableOc, sizeof(emcDvbTableOc));
/* Max dvfs entry is 32, but HOS doesn't seem to boot if exact freq doesn't exist in dvb table, /* Max dvfs entry is 32, but HOS doesn't seem to boot if exact freq doesn't exist in dvb table,
reason why it's like this reason why it's like this
@@ -849,7 +928,7 @@ namespace ams::ldr::hoc::pcv::mariko {
regulator *entry = reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_2_3.default_uv)); regulator *entry = reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_2_3.default_uv));
constexpr u32 uv_step = 5'000; constexpr u32 uv_step = 5'000;
constexpr u32 uv_min = 250'000; constexpr u32 uv_min = 250'000;
auto validator = [entry]() { auto validator = [entry]() {
R_UNLESS(entry->id == 2, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->id == 2, ldr::ResultInvalidRegulatorEntry());
@@ -909,8 +988,127 @@ namespace ams::ldr::hoc::pcv::mariko {
u8 movRd = asm_get_rd(mov); u8 movRd = asm_get_rd(mov);
u32 movCountPatch = asm_set_rd(asm_set_imm16(MtcMovAsm, newEmcList.size()), movRd); u32 movCountPatch = asm_set_rd(asm_set_imm16(MtcMovAsm, newEmcList.size()), movRd);
PATCH_OFFSET(ptr - BrOffset, NopIns); PATCH_OFFSET(ptr - BrOffset, NopIns);
PATCH_OFFSET(ptr - MovOffset, movCountPatch); PATCH_OFFSET(ptr - MovOffset, movCountPatch);
R_SUCCEED();
}
Result GetSocSpeedo(u32 &socSpeedo) {
constexpr u64 FusePhysicalAddress = 0x7000F000;
u64 virtualAddress = 0;
constexpr u64 Size = 0x1000;
u64 outSize;
/* TODO: use svc::QueryMemoryMapping instead. */
R_TRY(svcQueryMemoryMapping(&virtualAddress, &outSize, FusePhysicalAddress, Size));
constexpr u32 FuseOffset = 2048;
constexpr u32 SocSpeedoOffset = 308;
socSpeedo = *reinterpret_cast<u32 *>(virtualAddress + FuseOffset + SocSpeedoOffset);
R_SUCCEED();
}
u32 GetSocProcessId(u32 socSpeedo) {
if (socSpeedo <= 1597) {
return 0;
}
if (socSpeedo <= 1708) {
return 1;
}
/* >= 1709. */
return 2;
}
Result SocVoltAsm(u32 *compareSpeedos) {
constexpr u32 VoltageScanLimit = 10;
/* Might actually be speedo id. */
u32 *writeProcessId = ScanAssembly(compareSpeedos, VoltageScanLimit, SocVoltWriteProcessIdAsm, asm_compare_no_rd);
R_UNLESS(writeProcessId != nullptr, ldr::ResultInvalidSocVoltPattern());
u8 writeProcessIdRd = asm_get_rd(*writeProcessId);
/* This writes 1050mV. */
u32 *writeVoltage = ScanAssembly(writeProcessId, VoltageScanLimit, SocVoltWriteVoltageAsm, asm_compare_no_rd);
R_UNLESS(writeVoltage != nullptr, ldr::ResultInvalidSocVoltPattern());
u8 writeVoltageRd = asm_get_rd(*writeVoltage);
/* A csel instruction is used to select the soc voltage limit register. */
/* We care about its destination register since that is used for verification. */
constexpr u32 VoltageSelectScanLimit = 24;
u32 *selectVoltage = ScanAssembly(writeVoltage, VoltageSelectScanLimit, SocVoltSelectRegisterAsm, AsmCompareCselNoReg);
R_UNLESS(selectVoltage != nullptr, ldr::ResultInvalidSocVoltPattern());
/* Todo: check rm and rn? */
u8 selectVoltageRd = asm_get_rd(*selectVoltage);
/* rdCsel is then multiplied by 1000 to convert to uV. */
/* This is pretty far down the function. */
constexpr u32 MultiplierScanLimit = 200;
u32 *multiplier = ScanAssembly(selectVoltage, MultiplierScanLimit, SocVoltMultiplyVoltsAsm, AsmCompareMullNoReg);
R_UNLESS(multiplier != nullptr, ldr::ResultInvalidSocVoltPattern());
u8 multiplierRn = AsmGetMullRn(*multiplier);
u8 multiplierRm = AsmGetMullRm(*multiplier);
/* One of the two registers has to be rdCsel. */
R_UNLESS((multiplierRn == selectVoltageRd) || (multiplierRm == selectVoltageRd), ldr::ResultInvalidSocVoltPattern());
u8 multiplierRd = asm_get_rd(*multiplier);
/* Subs instruction is then used to verify against absolute limit. */
u32 limitValidationPattern = AsmSubsSetRn(SocVoltValidateLimitAsm, multiplierRd);
u32 *limitValidation = ScanAssembly(multiplier, VoltageScanLimit, limitValidationPattern, AsmSubsCompareNoReg);
R_UNLESS(limitValidation != nullptr, ldr::ResultInvalidSocVoltPattern());
/* There is a b.gt instruction right after (checks for socVoltageCap < socVoltageMax). */
u32 *branchToAbort = limitValidation + 1;
R_UNLESS(AsmCompareBrConNoImm19(*branchToAbort, SocVoltBranchToAbortAsm), ldr::ResultInvalidSocVoltPattern());
if (!C.marikoSocVmax || C.marikoSocVmax <= 1000) {
R_SKIP();
}
/* Adjust 1598 speedo minimum to ensure it always goes down process id 0 branch. */
/* 2200 should be high enough :D */
u32 compareSpeedosPatch = AsmSubsSetImm12(*compareSpeedos, 2200);
PATCH_OFFSET(compareSpeedos, compareSpeedosPatch);
u32 socSpeedo = 0;
R_TRY(GetSocSpeedo(socSpeedo));
/* Adjust processId from 0 to [process id of switch booting this]. */
/* We're overwriting the orr instruction entirly. */
u32 processId = GetSocProcessId(socSpeedo);
u32 writeProcessIdPatch = asm_set_rd(asm_set_imm16(SocVoltWriteVoltageAsm, processId), writeProcessIdRd);
PATCH_OFFSET(writeProcessId, writeProcessIdPatch);
/* Adjust voltage limit. */
u32 voltageLimitPatch = asm_set_rd(asm_set_imm16(SocVoltWriteVoltageAsm, C.marikoSocVmax), writeVoltageRd);
PATCH_OFFSET(writeVoltage, voltageLimitPatch);
/* Branches to an abort if limits are invalid -- we patch the branch instruction with NOP. */
PATCH_OFFSET(branchToAbort, NopIns);
R_SUCCEED();
}
Result SocVoltLimit(u32 *ptr) {
R_UNLESS(!std::memcmp(ptr - SocVoltLimitMaxDefaultIndex, socVoltLimitArray, sizeof(socVoltLimitArray)), ldr::ResultInvalidSocVoltLimit());
if (!C.marikoSocVmax || C.marikoSocVmax <= SocVoltLimitOfficial) {
R_SKIP();
}
constexpr u32 Step = 25;
u32 maxVolt = C.marikoSocVmax;
if (maxVolt % Step) {
maxVolt = maxVolt / Step * Step; /* Round. */
}
u32 volt = SocVoltLimitOfficial;
for (u32 i = 1; i < DvfsTableEntryCount - SocVoltLimitMaxDefaultIndex && volt < maxVolt; ++i) {
volt += Step;
PATCH_OFFSET(ptr + i, volt);
}
R_SUCCEED(); R_SUCCEED();
} }
@@ -932,13 +1130,15 @@ namespace ams::ldr::hoc::pcv::mariko {
{ "GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn }, { "GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn },
{ "GPU PLL Max", &GpuFreqPllMax, 1, nullptr, GpuClkPllMax }, { "GPU PLL Max", &GpuFreqPllMax, 1, nullptr, GpuClkPllMax },
{ "GPU PLL Limit", &GpuFreqPllLimit, 4, nullptr, GpuClkPllLimit }, { "GPU PLL Limit", &GpuFreqPllLimit, 4, nullptr, GpuClkPllLimit },
{ "MEM Freq Mtc", &MemFreqMtcTable, 0, nullptr, EmcClkOSLimit }, { "MEM Freq Mtc", &MemFreqMtcTable, 1, nullptr, EmcClkOSLimit },
{ "MEM Freq Dvb", &MemFreqDvbTable, 1, nullptr, EmcClkOSLimit }, { "MEM Freq Dvb", &MemFreqDvbTable, 1, nullptr, EmcClkOSLimit },
{ "MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit }, { "MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit },
{ "MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit }, { "MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit },
{ "MEM Vddq", &EmcVddqVolt, 2, nullptr, EmcVddqDefault }, { "MEM Vddq", &EmcVddqVolt, 2, nullptr, EmcVddqDefault },
{ "MEM Vdd2", &MemVoltHandler, 2, nullptr, MemVdd2Default }, { "MEM Vdd2", &MemVoltHandler, 2, nullptr, MemVdd2Default },
{ "Mem Table Asm", &MemMtcTableAsm, 0, &MemMtcGetGetTablePatternFn }, { "MEM Table Asm", &MemMtcTableAsm, 1, &MemMtcGetGetTablePatternFn },
{ "SOC Volt Asm", &SocVoltAsm, 1, &SocVoltPatternFn },
{ "SOC Volt Limit", &SocVoltLimit, 1, nullptr, SocVoltLimitOfficial },
}; };
for (uintptr_t ptr = mapped_nso; ptr <= mapped_nso + nso_size - sizeof(MarikoMtcTable); ptr += sizeof(u32)) { for (uintptr_t ptr = mapped_nso; ptr <= mapped_nso + nso_size - sizeof(MarikoMtcTable); ptr += sizeof(u32)) {
@@ -953,9 +1153,7 @@ namespace ams::ldr::hoc::pcv::mariko {
for (auto &entry : patches) { for (auto &entry : patches) {
LOGGING("%s Count: %zu", entry.description, entry.patched_count); LOGGING("%s Count: %zu", entry.description, entry.patched_count);
if (R_FAILED(entry.CheckResult())) { if (R_FAILED(entry.CheckResult())) {
#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) panic::SmcError(panic::Patch);
panic::SmcError(panic::Patch);
#endif
CRASH(entry.description); CRASH(entry.description);
} }

View File

@@ -48,11 +48,11 @@ namespace ams::ldr::hoc::pcv::mariko {
{ }, { },
}; };
constexpr u32 CpuClkOfficial = 1963'500; constexpr u32 CpuClkOfficial = 1963'500;
constexpr u32 CpuVoltOfficial = 1120; constexpr u32 CpuVoltOfficial = 1120;
constexpr u32 CpuVminOfficial = 620; constexpr u32 CpuHighVminOfficial = 850;
constexpr u32 CpuVminOfficial = 620;
constexpr u32 CpuTune0Low = 0xFFCF; constexpr u32 CpuTune0Low = 0xFFCF;
static const u32 cpuVoltagePatchValues[] = { 850, 38, 1120, 1000, 100, 1000, 0 }; static const u32 cpuVoltagePatchValues[] = { 850, 38, 1120, 1000, 100, 1000, 0 };
static const s32 cpuVoltagePatchOffsets[] = { -2, -1, 5, 6, 7, 8, 9 }; static const s32 cpuVoltagePatchOffsets[] = { -2, -1, 5, 6, 7, 8, 9 };
@@ -112,7 +112,7 @@ namespace ams::ldr::hoc::pcv::mariko {
struct DvbEntry { struct DvbEntry {
u64 freq; u64 freq;
s32 volt[4] = {}; u32 volt[4] = {};
}; };
constexpr DvbEntry EmcDvbTableDefault[] = { constexpr DvbEntry EmcDvbTableDefault[] = {
@@ -124,16 +124,35 @@ namespace ams::ldr::hoc::pcv::mariko {
{ 1600000, { 675, 650, 637, } }, { 1600000, { 675, 650, 637, } },
}; };
/* Movz */
/*
SF | OPC | HW | Imm16 | RD
31 | 30 29 28 27 26 25 24 23 | 22 21 | 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 | 4 3 2 1 0
*/
constexpr u32 SocVoltCompareSpeedoAsm = 0x7118FAFF; /* subs imm, compares to >=1598 max speedo and then goes down process id 1 route. */
constexpr u32 SocVoltWriteProcessIdAsm = 0x2A1F03F4; /* orr, writes id 0. */
constexpr u32 SocVoltWriteVoltageAsm = 0x52808358; /* Movz imm, writes 1050mV. */
constexpr u32 SocVoltSelectRegisterAsm = 0x1A9A3118; /* Csel, selects the voltage -- we need the register of this. */
constexpr u32 SocVoltMultiplyVoltsAsm = 0x1B1A7F0B; /* Mul, converts from mV -> uV */
constexpr u32 SocVoltValidateLimitAsm = 0x6B0A017F; /* Subs, checks limits */
constexpr u32 SocVoltBranchToAbortAsm = 0x540020AC; /* B.ge Branches to abort if limits are invalid. */
ALWAYS_INLINE bool SocVoltPatternFn(u32 *ptr) {
return asm_compare_no_rd(*ptr, SocVoltCompareSpeedoAsm);
}
constexpr u32 SocVoltLimitOfficial = 1050;
constexpr u32 SocVoltLimitMaxDefaultIndex = 17;
static const u32 socVoltLimitArray[DvfsTableEntryCount] = { 637, 650, 675, 700, 725, 750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, };
constexpr u32 EmcListDefault[] = { 204000, 1331200, 1600000, }; constexpr u32 EmcListDefault[] = { 204000, 1331200, 1600000, };
constexpr u32 EmcListSizeDefault = std::size(EmcListDefault); constexpr u32 EmcListSizeDefault = std::size(EmcListDefault);
constexpr u32 EmcListEndDefault = EmcListSizeDefault - 1; constexpr u32 EmcListEndDefault = EmcListSizeDefault - 1;
constexpr u32 EmcRateStep = 33'000;
constexpr u32 EmcRateStepScale = 33'200;
constexpr u32 EmcClkOSAlt = 1331'200; constexpr u32 EmcClkOSAlt = 1331'200;
constexpr u32 EmcClkPllmLimit = 2133'000'000; constexpr u32 EmcClkPllmLimit = 2133'000'000;
constexpr u32 EmcVddqDefault = 600'000; constexpr u32 EmcVddqDefault = 600'000;
constexpr u32 MemVdd2Default = 1100'000; constexpr u32 MemVdd2Default = 1100'000;
constexpr u32 MTC_TABLE_REV = 3; constexpr u32 MTC_TABLE_REV = 3;
constexpr u32 MtcTableCountDefault = 3; constexpr u32 MtcTableCountDefault = 3;
@@ -209,7 +228,7 @@ namespace ams::ldr::hoc::pcv::mariko {
MtcTableIndex index; MtcTableIndex index;
}; };
constexpr MtcDramIndex mtcIndexTable[] = { const inline MtcDramIndex mtcIndexTable[] = {
{ HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, }, { HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, },
{ AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, }, { AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, },
{ IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, }, { IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, },
@@ -260,8 +279,8 @@ namespace ams::ldr::hoc::pcv::mariko {
/* Adrp */ /* Adrp */
/* /*
OP | ImmLow | ImmHigh | RD OP | ImmLow | | ImmHigh | RD
31 | 30 29 28 27 26 25 24 | 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 | 4 3 2 1 0 31 | 30 29 | 28 27 26 25 24 | 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 | 4 3 2 1 0
*/ */
/* ADD (immediate) */ /* ADD (immediate) */

View File

@@ -21,11 +21,7 @@
namespace ams::ldr::hoc::ptm { namespace ams::ldr::hoc::ptm {
Result CpuPtmBoost(perf_conf_entry* entry) { Result CpuPtmBoost(perf_conf_entry* entry) {
#ifdef ATMOSPHERE_IS_STRATOSPHERE
bool isMariko = (spl::GetSocType() == spl::SocType_Mariko); bool isMariko = (spl::GetSocType() == spl::SocType_Mariko);
#else
bool isMariko = true;
#endif
if (!C.eristaCpuBoostClock || !C.marikoCpuBoostClock) { if (!C.eristaCpuBoostClock || !C.marikoCpuBoostClock) {
R_SUCCEED(); R_SUCCEED();
@@ -76,11 +72,7 @@ namespace ams::ldr::hoc::ptm {
PatcherEntry<perf_conf_entry> cpuPtmBoostPatch = { "CPU Ptm Boost", &CpuPtmBoost, 2, }; PatcherEntry<perf_conf_entry> cpuPtmBoostPatch = { "CPU Ptm Boost", &CpuPtmBoost, 2, };
PatcherEntry<perf_conf_entry> memPtmPatch = { "MEM Ptm", &MemPtm, 16, }; PatcherEntry<perf_conf_entry> memPtmPatch = { "MEM Ptm", &MemPtm, 16, };
#ifdef ATMOSPHERE_IS_STRATOSPHERE
bool isMariko = (spl::GetSocType() == spl::SocType_Mariko); bool isMariko = (spl::GetSocType() == spl::SocType_Mariko);
#else
bool isMariko = true;
#endif
for (u32 i = 0; i < entryCnt; i++) { for (u32 i = 0; i < entryCnt; i++) {
perf_conf_entry *entry = confTable + i; perf_conf_entry *entry = confTable + i;
@@ -92,7 +84,7 @@ namespace ams::ldr::hoc::ptm {
switch (entry->cpu_freq_1) { switch (entry->cpu_freq_1) {
case cpuPtmBoost: case cpuPtmBoost:
cpuPtmBoostPatch.Apply(entry); R_DISCARD(cpuPtmBoostPatch.Apply(entry));
break; break;
case cpuPtmDefault: case cpuPtmDefault:
case cpuPtmDevOC: case cpuPtmDevOC:
@@ -107,7 +99,7 @@ namespace ams::ldr::hoc::ptm {
case memPtmAlt: case memPtmAlt:
case memPtmClamp: case memPtmClamp:
if (isMariko) { if (isMariko) {
memPtmPatch.Apply(entry); R_DISCARD(memPtmPatch.Apply(entry));
} }
break; break;
default: default:
@@ -117,13 +109,15 @@ namespace ams::ldr::hoc::ptm {
} }
LOGGING("%s Count: %zu", cpuPtmBoostPatch.description, cpuPtmBoostPatch.patched_count); LOGGING("%s Count: %zu", cpuPtmBoostPatch.description, cpuPtmBoostPatch.patched_count);
if (R_FAILED(cpuPtmBoostPatch.CheckResult())) if (R_FAILED(cpuPtmBoostPatch.CheckResult())) {
CRASH(cpuPtmBoostPatch.description); CRASH(cpuPtmBoostPatch.description);
}
if (isMariko) { if (isMariko) {
LOGGING("%s Count: %zu", memPtmPatch.description, memPtmPatch.patched_count); LOGGING("%s Count: %zu", memPtmPatch.description, memPtmPatch.patched_count);
if (R_FAILED(memPtmPatch.CheckResult())) if (R_FAILED(memPtmPatch.CheckResult())) {
CRASH(memPtmPatch.description); CRASH(memPtmPatch.description);
}
} }
} }

View File

@@ -69,9 +69,7 @@ MmuRequest nvencRequest;
MmuRequest nvjpgRequest; MmuRequest nvjpgRequest;
//Checks //Checks
Result clkrstCheck = 1;
Result nvCheck = 1; Result nvCheck = 1;
Result pcvCheck = 1;
Result i2cCheck = 1; Result i2cCheck = 1;
Result pwmCheck = 1; Result pwmCheck = 1;
Result tcCheck = 1; Result tcCheck = 1;
@@ -554,28 +552,6 @@ void Misc(void*) {
do { do {
mutexLock(&mutex_Misc); mutexLock(&mutex_Misc);
// CPU, GPU and RAM Frequency
if (R_SUCCEEDED(clkrstCheck)) {
ClkrstSession clkSession;
if (R_SUCCEEDED(clkrstOpenSession(&clkSession, PcvModuleId_CpuBus, 3))) {
clkrstGetClockRate(&clkSession, &CPU_Hz);
clkrstCloseSession(&clkSession);
}
if (R_SUCCEEDED(clkrstOpenSession(&clkSession, PcvModuleId_GPU, 3))) {
clkrstGetClockRate(&clkSession, &GPU_Hz);
clkrstCloseSession(&clkSession);
}
if (R_SUCCEEDED(clkrstOpenSession(&clkSession, PcvModuleId_EMC, 3))) {
clkrstGetClockRate(&clkSession, &RAM_Hz);
clkrstCloseSession(&clkSession);
}
}
else if (R_SUCCEEDED(pcvCheck)) {
pcvGetClockRate(PcvModule_CpuBus, &CPU_Hz);
pcvGetClockRate(PcvModule_GPU, &GPU_Hz);
pcvGetClockRate(PcvModule_EMC, &RAM_Hz);
}
// Get sys-clk data // Get sys-clk data
if (R_SUCCEEDED(hocclkCheck)) { if (R_SUCCEEDED(hocclkCheck)) {
HocClkContext hocclkCTX; HocClkContext hocclkCTX;
@@ -599,6 +575,9 @@ void Misc(void*) {
realSOC_mV = hocclkCTX.voltages[HocClkVoltage_SOC]; realSOC_mV = hocclkCTX.voltages[HocClkVoltage_SOC];
realVDD2_mV = hocclkCTX.voltages[HocClkVoltage_EMCVDD2]; realVDD2_mV = hocclkCTX.voltages[HocClkVoltage_EMCVDD2];
realVDDQ_mV = hocclkCTX.voltages[HocClkVoltage_EMCVDDQ]; realVDDQ_mV = hocclkCTX.voltages[HocClkVoltage_EMCVDDQ];
CPU_Hz = hocclkCTX.freqs[HocClkModule_CPU];
GPU_Hz = hocclkCTX.freqs[HocClkModule_GPU];
RAM_Hz = hocclkCTX.freqs[HocClkModule_MEM];
} }
} }

View File

@@ -419,8 +419,6 @@ public:
tsl::hlp::doWithSmSession([this]{ tsl::hlp::doWithSmSession([this]{
apmInitialize(); apmInitialize();
if (hosversionAtLeast(8,0,0)) clkrstCheck = clkrstInitialize();
else pcvCheck = pcvInitialize();
if (hosversionAtLeast(5,0,0)) tcCheck = tcInitialize(); if (hosversionAtLeast(5,0,0)) tcCheck = tcInitialize();
@@ -473,8 +471,6 @@ public:
} }
shmemClose(&_sharedmemory); shmemClose(&_sharedmemory);
//Exit services //Exit services
clkrstExit();
pcvExit();
tsExit(); tsExit();
tcExit(); tcExit();
pwmChannelSessionClose(&g_ICon); pwmChannelSessionClose(&g_ICon);
@@ -502,8 +498,6 @@ public:
//Initialize services //Initialize services
tsl::hlp::doWithSmSession([this]{ tsl::hlp::doWithSmSession([this]{
apmInitialize(); apmInitialize();
if (hosversionAtLeast(8,0,0)) clkrstCheck = clkrstInitialize();
else pcvCheck = pcvInitialize();
if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
@@ -556,8 +550,6 @@ public:
hocclkIpcExit(); hocclkIpcExit();
} }
//Exit services //Exit services
clkrstExit();
pcvExit();
tsExit(); tsExit();
tcExit(); tcExit();
pwmChannelSessionClose(&g_ICon); pwmChannelSessionClose(&g_ICon);
@@ -589,8 +581,6 @@ public:
// Same serviceinit as before // Same serviceinit as before
tsl::hlp::doWithSmSession([this]{ tsl::hlp::doWithSmSession([this]{
apmInitialize(); apmInitialize();
if (hosversionAtLeast(8,0,0)) clkrstCheck = clkrstInitialize();
else pcvCheck = pcvInitialize();
if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
@@ -644,8 +634,6 @@ public:
hocclkIpcExit(); hocclkIpcExit();
} }
// Exit services // Exit services
clkrstExit();
pcvExit();
tsExit(); tsExit();
tcExit(); tcExit();
pwmChannelSessionClose(&g_ICon); pwmChannelSessionClose(&g_ICon);
@@ -679,8 +667,6 @@ public:
virtual void initServices() override { virtual void initServices() override {
tsl::hlp::doWithSmSession([this]{ tsl::hlp::doWithSmSession([this]{
apmInitialize(); apmInitialize();
if (hosversionAtLeast(8,0,0)) clkrstCheck = clkrstInitialize();
else pcvCheck = pcvInitialize();
if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
@@ -732,8 +718,6 @@ public:
if (R_SUCCEEDED(hocclkCheck)) { if (R_SUCCEEDED(hocclkCheck)) {
hocclkIpcExit(); hocclkIpcExit();
} }
clkrstExit();
pcvExit();
tsExit(); tsExit();
tcExit(); tcExit();
pwmChannelSessionClose(&g_ICon); pwmChannelSessionClose(&g_ICon);
@@ -762,8 +746,6 @@ public:
virtual void initServices() override { virtual void initServices() override {
tsl::hlp::doWithSmSession([this]{ tsl::hlp::doWithSmSession([this]{
apmInitialize(); apmInitialize();
if (hosversionAtLeast(8,0,0)) clkrstCheck = clkrstInitialize();
else pcvCheck = pcvInitialize();
if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
@@ -815,8 +797,6 @@ public:
if (R_SUCCEEDED(hocclkCheck)) { if (R_SUCCEEDED(hocclkCheck)) {
hocclkIpcExit(); hocclkIpcExit();
} }
clkrstExit();
pcvExit();
tsExit(); tsExit();
tcExit(); tcExit();
pwmChannelSessionClose(&g_ICon); pwmChannelSessionClose(&g_ICon);
@@ -845,8 +825,6 @@ public:
virtual void initServices() override { virtual void initServices() override {
tsl::hlp::doWithSmSession([this]{ tsl::hlp::doWithSmSession([this]{
apmInitialize(); apmInitialize();
if (hosversionAtLeast(8,0,0)) clkrstCheck = clkrstInitialize();
else pcvCheck = pcvInitialize();
if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
@@ -898,8 +876,6 @@ public:
if (R_SUCCEEDED(hocclkCheck)) { if (R_SUCCEEDED(hocclkCheck)) {
hocclkIpcExit(); hocclkIpcExit();
} }
clkrstExit();
pcvExit();
tsExit(); tsExit();
tcExit(); tcExit();
pwmChannelSessionClose(&g_ICon); pwmChannelSessionClose(&g_ICon);

View File

@@ -142,7 +142,7 @@ public:
}); });
// tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); // tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release);
tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Status Monitor Pro", APP_VERSION, true); tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION, true);
rootFrame->setContent(Status); rootFrame->setContent(Status);
return rootFrame; return rootFrame;

View File

@@ -125,7 +125,7 @@ public:
//Print strings //Print strings
///CPU ///CPU
if (R_SUCCEEDED(clkrstCheck) || R_SUCCEEDED(pcvCheck)) { if (1) {
uint32_t height_offset = 155; uint32_t height_offset = 155;
if (realCPU_Hz && settings.showRealFreqs) { if (realCPU_Hz && settings.showRealFreqs) {
@@ -173,7 +173,7 @@ public:
} }
///GPU ///GPU
if (R_SUCCEEDED(clkrstCheck) || R_SUCCEEDED(pcvCheck) || R_SUCCEEDED(nvCheck)) { if (R_SUCCEEDED(nvCheck)) {
uint32_t height_offset = 320-8; uint32_t height_offset = 320-8;
if (realGPU_Hz && settings.showRealFreqs) { if (realGPU_Hz && settings.showRealFreqs) {
@@ -181,7 +181,7 @@ public:
} }
renderer->drawString("GPU Usage", false, COMMON_MARGIN, 285-8, 20, (settings.catColor1)); renderer->drawString("GPU Usage", false, COMMON_MARGIN, 285-8, 20, (settings.catColor1));
if (R_SUCCEEDED(clkrstCheck) || R_SUCCEEDED(pcvCheck)) { if (1) {
if (settings.showTargetFreqs) { if (settings.showTargetFreqs) {
//static auto targetFreqWidth = renderer->getTextDimensions("Target Frequency: ", false, 15).first; //static auto targetFreqWidth = renderer->getTextDimensions("Target Frequency: ", false, 15).first;
renderer->drawString("Target Frequency", false, COMMON_MARGIN, height_offset, 15, (settings.catColor2)); renderer->drawString("Target Frequency", false, COMMON_MARGIN, height_offset, 15, (settings.catColor2));
@@ -213,7 +213,7 @@ public:
static std::vector<std::string> specialChars = {""}; static std::vector<std::string> specialChars = {""};
///RAM ///RAM
if (R_SUCCEEDED(clkrstCheck) || R_SUCCEEDED(pcvCheck) || R_SUCCEEDED(Hinted)) { if (R_SUCCEEDED(Hinted)) {
uint32_t height_offset = 410; uint32_t height_offset = 410;
if (realRAM_Hz && settings.showRealFreqs) { if (realRAM_Hz && settings.showRealFreqs) {
@@ -221,7 +221,7 @@ public:
} }
renderer->drawString("RAM Usage", false, COMMON_MARGIN, 375, 20, (settings.catColor1)); renderer->drawString("RAM Usage", false, COMMON_MARGIN, 375, 20, (settings.catColor1));
if (R_SUCCEEDED(clkrstCheck) || R_SUCCEEDED(pcvCheck)) { if (1) {
if (settings.showTargetFreqs) { if (settings.showTargetFreqs) {
//static auto targetFreqWidth = renderer->getTextDimensions("Target Frequency: ", false, 15).first; //static auto targetFreqWidth = renderer->getTextDimensions("Target Frequency: ", false, 15).first;
renderer->drawString("Target Frequency", false, COMMON_MARGIN, height_offset, 15, (settings.catColor2)); renderer->drawString("Target Frequency", false, COMMON_MARGIN, height_offset, 15, (settings.catColor2));

View File

@@ -122,7 +122,7 @@ public:
}); });
// tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); // tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release);
tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Status Monitor Pro", APP_VERSION, true); tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION, true);
rootFrame->setContent(Status); rootFrame->setContent(Status);
return rootFrame; return rootFrame;

View File

@@ -1,6 +1,5 @@
# hoc-clk # hoc-clk
Switch sysmodule allowing you to set cpu/gpu/mem clocks according to the running application and docked state. Overclocking suite for Nintendo Switch.
Modified for Horizon OC
Support is only provided for FW 16.0.0+. This MAY work on older firmwares but support is NOT guaranteed Support is only provided for FW 17.0.0+. This MAY work on older firmwares but support is NOT guaranteed

Binary file not shown.

23
Source/hoc-clk/build.sh Normal file → Executable file
View File

@@ -9,11 +9,9 @@ if [[ -n "$1" ]]; then
DIST_DIR="$1" DIST_DIR="$1"
fi fi
echo "DIST_DIR: $DIST_DIR" echo
echo "CORES: $CORES" echo "*** Compiling hoc-clk ***"
TITLE_ID="$(sed -n 's/.*"title_id"[[:space:]]*:[[:space:]]*"0x\([^"]*\)".*/\1/p' "$ROOT_DIR/sysmodule/perms.json")"
echo "*** sysmodule ***"
TITLE_ID="$(grep -oP '"title_id":\s*"0x\K(\w+)' "$ROOT_DIR/sysmodule/perms.json")"
pushd "$ROOT_DIR/sysmodule" pushd "$ROOT_DIR/sysmodule"
make -j$CORES make -j$CORES
@@ -24,18 +22,23 @@ cp -vf "$ROOT_DIR/sysmodule/out/hoc-clk.nsp" "$DIST_DIR/atmosphere/contents/$TIT
>"$DIST_DIR/atmosphere/contents/$TITLE_ID/flags/boot2.flag" >"$DIST_DIR/atmosphere/contents/$TITLE_ID/flags/boot2.flag"
cp -vf "$ROOT_DIR/sysmodule/toolbox.json" "$DIST_DIR/atmosphere/contents/$TITLE_ID/toolbox.json" cp -vf "$ROOT_DIR/sysmodule/toolbox.json" "$DIST_DIR/atmosphere/contents/$TITLE_ID/toolbox.json"
echo "*** overlay ***" echo
echo "*** Compiling hoc-clk-overlay ***"
pushd "$ROOT_DIR/overlay" pushd "$ROOT_DIR/overlay"
make -j$CORES make -j$CORES
popd > /dev/null popd > /dev/null
mkdir -p "$DIST_DIR/switch/.overlays" mkdir -p "$DIST_DIR/switch/.overlays"
cp -vf "$ROOT_DIR/overlay/out/horizon-oc-overlay.ovl" "$DIST_DIR/switch/.overlays/horizon-oc-overlay.ovl" cp -vf "$ROOT_DIR/overlay/out/horizon-oc-overlay.ovl" "$DIST_DIR/switch/.overlays/horizon-oc-overlay.ovl"
echo
echo "*** assets ***" echo "*** Copying assets ***"
mkdir -p "$DIST_DIR/config/horizon-oc" mkdir -p "$DIST_DIR/config/horizon-oc"
cp -vf "$ROOT_DIR/config.ini.template" "$DIST_DIR/config/horizon-oc/config.ini.template" cp -vf "$ROOT_DIR/config.ini.template" "$DIST_DIR/config/horizon-oc/config.ini.template"
cp -vf "$ROOT_DIR/../../README.md" "$DIST_DIR/README.md" mkdir -p "$DIST_DIR/config/ultrahand/assets/notifications"
cp -vf "$ROOT_DIR/assets/hoc.rgba" "$DIST_DIR/config/ultrahand/assets/notifications/hoc.rgba"
echo "*** lang ***" echo
cp -r "$ROOT_DIR/overlay/lang/" "$DIST_DIR/config/horizon-oc/lang/" echo "*** Copying lang ***"
cp -vr "$ROOT_DIR/overlay/lang/" "$DIST_DIR/config/horizon-oc/lang/"
echo

View File

@@ -1,314 +0,0 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 shuffle2
* Copyright (c) 2018 balika011
* Copyright (c) 2019-2025 CTCaer
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef _FUSE_H_
#define _FUSE_H_
#ifndef BIT
#define BIT(n) (1U<<(n))
#endif
/*! Fuse registers. */
#define FUSE_CTRL 0x0
#define FUSE_ADDR 0x4
#define FUSE_RDATA 0x8
#define FUSE_WDATA 0xC
#define FUSE_TIME_RD1 0x10
#define FUSE_TIME_RD2 0x14
#define FUSE_TIME_PGM1 0x18
#define FUSE_TIME_PGM2 0x1C
#define FUSE_PRIV2INTFC 0x20
#define FUSE_PRIV2INTFC_START_DATA BIT(0)
#define FUSE_PRIV2INTFC_SKIP_RECORDS BIT(1)
#define FUSE_FUSEBYPASS 0x24
#define FUSE_PRIVATEKEYDISABLE 0x28
#define FUSE_PRIVKEY_DISABLE BIT(0)
#define FUSE_PRIVKEY_TZ_STICKY_BIT BIT(4)
#define FUSE_DISABLEREGPROGRAM 0x2C
#define FUSE_WRITE_ACCESS_SW 0x30
#define FUSE_PWR_GOOD_SW 0x34
#define FUSE_PRIV2RESHIFT 0x3C
#define FUSE_FUSETIME_RD0 0x40
#define FUSE_FUSETIME_RD1 0x44
#define FUSE_FUSETIME_RD2 0x48
#define FUSE_FUSETIME_RD3 0x4C
#define FUSE_PRIVATE_KEY0_NONZERO 0x80
#define FUSE_PRIVATE_KEY1_NONZERO 0x84
#define FUSE_PRIVATE_KEY2_NONZERO 0x88
#define FUSE_PRIVATE_KEY3_NONZERO 0x8C
#define FUSE_PRIVATE_KEY4_NONZERO 0x90
/*! Fuse Cached registers */
#define FUSE_RESERVED_ODM8_B01 0x98 // FUSE_READ_TZ Group 0.
#define FUSE_RESERVED_ODM9_B01 0x9C // FUSE_READ_TZ Group 0.
#define FUSE_RESERVED_ODM10_B01 0xA0 // FUSE_READ_TZ Group 0.
#define FUSE_RESERVED_ODM11_B01 0xA4 // FUSE_READ_TZ Group 0.
#define FUSE_RESERVED_ODM12_B01 0xA8 // FUSE_READ_TZ Group 1? Is value -1?
#define FUSE_RESERVED_ODM13_B01 0xAC // FUSE_READ_TZ Group 1? Is value -1?
#define FUSE_RESERVED_ODM14_B01 0xB0 // FUSE_READ_TZ Group 1? Is value -1?
#define FUSE_RESERVED_ODM15_B01 0xB4 // FUSE_READ_TZ Group 1? Is value -1?
#define FUSE_RESERVED_ODM16_B01 0xB8 // FUSE_READ_TZ Group 2? Is value -1?
#define FUSE_RESERVED_ODM17_B01 0xBC // FUSE_READ_TZ Group 2? Is value -1?
#define FUSE_RESERVED_ODM18_B01 0xC0 // FUSE_READ_TZ Group 2.
#define FUSE_RESERVED_ODM19_B01 0xC4 // FUSE_READ_TZ Group 2.
#define FUSE_RESERVED_ODM20_B01 0xC8 // FUSE_READ_TZ Group 3.
#define FUSE_RESERVED_ODM21_B01 0xCC // FUSE_READ_TZ Group 3.
#define FUSE_KEK00_B01 0xD0
#define FUSE_KEK01_B01 0xD4
#define FUSE_KEK02_B01 0xD8
#define FUSE_KEK03_B01 0xDC
#define FUSE_BEK00_B01 0xE0
#define FUSE_BEK01_B01 0xE4
#define FUSE_BEK02_B01 0xE8
#define FUSE_BEK03_B01 0xEC
#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4SVT_B01 0xF0
#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4SVT_B01 0xF4
#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4SVT_B01 0xF8
#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4SVT_B01 0xFC
#define FUSE_PRODUCTION_MODE 0x100
#define FUSE_JTAG_SECUREID_VALID 0x104
#define FUSE_ODM_LOCK 0x108
#define FUSE_OPT_OPENGL_EN 0x10C
#define FUSE_SKU_INFO 0x110
#define FUSE_CPU_SPEEDO_0_CALIB 0x114
#define FUSE_CPU_IDDQ_CALIB 0x118
#define FUSE_RESERVED_ODM22_B01 0x11C // FUSE_READ_TZ Group 3.
#define FUSE_RESERVED_ODM23_B01 0x120 // FUSE_READ_TZ Group 3.
#define FUSE_RESERVED_ODM24_B01 0x124 // FUSE_READ_TZ Group 4.
#define FUSE_OPT_FT_REV 0x128
#define FUSE_CPU_SPEEDO_1_CALIB 0x12C
#define FUSE_CPU_SPEEDO_2_CALIB 0x130
#define FUSE_SOC_SPEEDO_0_CALIB 0x134
#define FUSE_SOC_SPEEDO_1_CALIB 0x138
#define FUSE_SOC_SPEEDO_2_CALIB 0x13C
#define FUSE_SOC_IDDQ_CALIB 0x140
#define FUSE_RESERVED_ODM25_B01 0x144 // FUSE_READ_TZ Group 4.
#define FUSE_FA 0x148
#define FUSE_RESERVED_PRODUCTION 0x14C
#define FUSE_HDMI_LANE0_CALIB 0x150
#define FUSE_HDMI_LANE1_CALIB 0x154
#define FUSE_HDMI_LANE2_CALIB 0x158
#define FUSE_HDMI_LANE3_CALIB 0x15C
#define FUSE_ENCRYPTION_RATE 0x160
#define FUSE_PUBLIC_KEY0 0x164
#define FUSE_PUBLIC_KEY1 0x168
#define FUSE_PUBLIC_KEY2 0x16C
#define FUSE_PUBLIC_KEY3 0x170
#define FUSE_PUBLIC_KEY4 0x174
#define FUSE_PUBLIC_KEY5 0x178
#define FUSE_PUBLIC_KEY6 0x17C
#define FUSE_PUBLIC_KEY7 0x180
#define FUSE_TSENSOR1_CALIB 0x184 // CPU1.
#define FUSE_TSENSOR2_CALIB 0x188 // CPU2.
#define FUSE_OPT_SECURE_SCC_DIS_B01 0x18C
#define FUSE_OPT_CP_REV 0x190 // FUSE style revision - ATE. 0x101 0x100
#define FUSE_OPT_PFG 0x194
#define FUSE_TSENSOR0_CALIB 0x198 // CPU0.
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19C
#define FUSE_SECURITY_MODE 0x1A0
#define FUSE_PRIVATE_KEY0 0x1A4
#define FUSE_PRIVATE_KEY1 0x1A8
#define FUSE_PRIVATE_KEY2 0x1AC
#define FUSE_PRIVATE_KEY3 0x1B0
#define FUSE_PRIVATE_KEY4 0x1B4
#define FUSE_ARM_JTAG_DIS 0x1B8
#define FUSE_BOOT_DEVICE_INFO 0x1BC
#define FUSE_RESERVED_SW 0x1C0
#define FUSE_OPT_VP9_DISABLE 0x1C4
#define FUSE_RESERVED_ODM0 0x1C8
#define FUSE_RESERVED_ODM1 0x1CC
#define FUSE_RESERVED_ODM2 0x1D0
#define FUSE_RESERVED_ODM3 0x1D4
#define FUSE_RESERVED_ODM4 0x1D8
#define FUSE_RESERVED_ODM5 0x1DC
#define FUSE_RESERVED_ODM6 0x1E0
#define FUSE_RESERVED_ODM7 0x1E4
#define FUSE_OBS_DIS 0x1E8
#define FUSE_OPT_NVJTAG_PROTECTION_ENABLE_B01 0x1EC
#define FUSE_USB_CALIB 0x1F0
#define FUSE_SKU_DIRECT_CONFIG 0x1F4
#define FUSE_KFUSE_PRIVKEY_CTRL 0x1F8
#define FUSE_PACKAGE_INFO 0x1FC // 1: MID, 2: DSC.
#define FUSE_OPT_VENDOR_CODE 0x200
#define FUSE_OPT_FAB_CODE 0x204
#define FUSE_OPT_LOT_CODE_0 0x208
#define FUSE_OPT_LOT_CODE_1 0x20C
#define FUSE_OPT_WAFER_ID 0x210
#define FUSE_OPT_X_COORDINATE 0x214
#define FUSE_OPT_Y_COORDINATE 0x218
#define FUSE_OPT_SEC_DEBUG_EN 0x21C
#define FUSE_OPT_OPS_RESERVED 0x220
#define FUSE_SATA_CALIB 0x224
#define FUSE_SPARE_REGISTER_ODM_B01 0x224
#define FUSE_GPU_IDDQ_CALIB 0x228
#define FUSE_TSENSOR3_CALIB 0x22C // CPU3.
#define FUSE_CLOCK_BONDOUT0 0x230
#define FUSE_CLOCK_BONDOUT1 0x234
#define FUSE_RESERVED_ODM26_B01 0x238 // FUSE_READ_TZ Group 4.
#define FUSE_RESERVED_ODM27_B01 0x23C // FUSE_READ_TZ Group 4.
#define FUSE_RESERVED_ODM28_B01 0x240 // MAX77812 phase configuration. FUSE_READ_TZ Group 5.
#define FUSE_OPT_SAMPLE_TYPE 0x244
#define FUSE_OPT_SUBREVISION 0x248 // "", "p", "q", "r". e.g: A01p.
#define FUSE_OPT_SW_RESERVED_0 0x24C
#define FUSE_OPT_SW_RESERVED_1 0x250
#define FUSE_TSENSOR4_CALIB 0x254 // GPU.
#define FUSE_TSENSOR5_CALIB 0x258 // MEM0.
#define FUSE_TSENSOR6_CALIB 0x25C // MEM1.
#define FUSE_TSENSOR7_CALIB 0x260 // PLLX.
#define FUSE_OPT_PRIV_SEC_DIS 0x264
#define FUSE_PKC_DISABLE 0x268
#define FUSE_BOOT_SECURITY_INFO_B01 0x268
#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4HVT_B01 0x26C
#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4HVT_B01 0x270
#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4HVT_B01 0x274
#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4HVT_B01 0x278
#define FUSE_FUSE2TSEC_DEBUG_DISABLE 0x27C
#define FUSE_TSENSOR_COMMON 0x280
#define FUSE_OPT_CP_BIN 0x284
#define FUSE_OPT_GPU_DISABLE 0x288
#define FUSE_OPT_FT_BIN 0x28C
#define FUSE_OPT_DONE_MAP 0x290
#define FUSE_RESERVED_ODM29_B01 0x294 // FUSE_READ_TZ Group 5? Is value -1?
#define FUSE_APB2JTAG_DISABLE 0x298
#define FUSE_ODM_INFO 0x29C // Debug features disable.
#define FUSE_ARM_CRYPT_DE_FEATURE 0x2A8
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4SVT_B01 0x2B0
#define FUSE_OPT_RAM_RCT_TSMCDP_PO4SVT_B01 0x2B4
#define FUSE_OPT_RAM_WCT_TSMCDP_PO4SVT_B01 0x2B8
#define FUSE_OPT_RAM_KP_TSMCDP_PO4SVT_B01 0x2BC
#define FUSE_WOA_SKU_FLAG 0x2C0
#define FUSE_ECO_RESERVE_1 0x2C4
#define FUSE_GCPLEX_CONFIG_FUSE 0x2C8
#define FUSE_GPU_VPR_AUTO_FETCH_DIS BIT(0)
#define FUSE_GPU_VPR_ENABLED BIT(1)
#define FUSE_GPU_WPR_ENABLED BIT(2)
#define FUSE_PRODUCTION_MONTH 0x2CC
#define FUSE_RAM_REPAIR_INDICATOR 0x2D0
#define FUSE_TSENSOR9_CALIB 0x2D4 // AOTAG.
#define FUSE_VMIN_CALIBRATION 0x2DC
#define FUSE_AGING_SENSOR_CALIBRATION 0x2E0
#define FUSE_DEBUG_AUTHENTICATION 0x2E4
#define FUSE_SECURE_PROVISION_INDEX 0x2E8
#define FUSE_SECURE_PROVISION_INFO 0x2EC
#define FUSE_OPT_GPU_DISABLE_CP1 0x2F0
#define FUSE_SPARE_ENDIS 0x2F4
#define FUSE_ECO_RESERVE_0 0x2F8 // AID.
#define FUSE_RESERVED_CALIB0 0x304 // GPCPLL ADC Calibration.
#define FUSE_RESERVED_CALIB1 0x308
#define FUSE_OPT_GPU_TPC0_DISABLE 0x30C
#define FUSE_OPT_GPU_TPC0_DISABLE_CP1 0x310
#define FUSE_OPT_CPU_DISABLE 0x314
#define FUSE_OPT_CPU_DISABLE_CP1 0x318
#define FUSE_TSENSOR10_CALIB 0x31C
#define FUSE_TSENSOR10_CALIB_AUX 0x320
#define FUSE_OPT_RAM_SVOP_DP 0x324
#define FUSE_OPT_RAM_SVOP_PDP 0x328
#define FUSE_OPT_RAM_SVOP_REG 0x32C
#define FUSE_OPT_RAM_SVOP_SP 0x330
#define FUSE_OPT_RAM_SVOP_SMPDP 0x334
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4HVT_B01 0x324
#define FUSE_OPT_RAM_RCT_TSMCDP_PO4HVT_B01 0x328
#define FUSE_OPT_RAM_WCT_TSMCDP_PO4HVT_B01 0x32c
#define FUSE_OPT_RAM_KP_TSMCDP_PO4HVT_B01 0x330
#define FUSE_OPT_RAM_SVOP_SP_B01 0x334
#define FUSE_OPT_GPU_TPC0_DISABLE_CP2 0x338
#define FUSE_OPT_GPU_TPC1_DISABLE 0x33C
#define FUSE_OPT_GPU_TPC1_DISABLE_CP1 0x340
#define FUSE_OPT_GPU_TPC1_DISABLE_CP2 0x344
#define FUSE_OPT_CPU_DISABLE_CP2 0x348
#define FUSE_OPT_GPU_DISABLE_CP2 0x34C
#define FUSE_USB_CALIB_EXT 0x350
#define FUSE_RESERVED_FIELD 0x354 // RMA.
#define FUSE_SPARE_REALIGNMENT_REG 0x37C
#define FUSE_SPARE_BIT_0 0x380
//...
#define FUSE_SPARE_BIT_31 0x3FC
/*! Fuse commands. */
#define FUSE_IDLE 0x0
#define FUSE_READ 0x1
#define FUSE_WRITE 0x2
#define FUSE_SENSE 0x3
#define FUSE_CMD_MASK 0x3
/*! Fuse status. */
#define FUSE_STATUS_RESET 0
#define FUSE_STATUS_POST_RESET 1
#define FUSE_STATUS_LOAD_ROW0 2
#define FUSE_STATUS_LOAD_ROW1 3
#define FUSE_STATUS_IDLE 4
#define FUSE_STATUS_READ_SETUP 5
#define FUSE_STATUS_READ_STROBE 6
#define FUSE_STATUS_SAMPLE_FUSES 7
#define FUSE_STATUS_READ_HOLD 8
#define FUSE_STATUS_FUSE_SRC_SETUP 9
#define FUSE_STATUS_WRITE_SETUP 10
#define FUSE_STATUS_WRITE_ADDR_SETUP 11
#define FUSE_STATUS_WRITE_PROGRAM 12
#define FUSE_STATUS_WRITE_ADDR_HOLD 13
#define FUSE_STATUS_FUSE_SRC_HOLD 14
#define FUSE_STATUS_LOAD_RIR 15
#define FUSE_STATUS_READ_BEFORE_WRITE_SETUP 16
#define FUSE_STATUS_READ_DEASSERT_PD 17
/*! Fuse cache registers. */
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
#define FUSE_ARRAY_WORDS_NUM 192
#define FUSE_ARRAY_WORDS_NUM_B01 256
enum
{
FUSE_NX_HW_TYPE_ICOSA,
FUSE_NX_HW_TYPE_IOWA,
FUSE_NX_HW_TYPE_HOAG,
FUSE_NX_HW_TYPE_AULA
};
enum
{
FUSE_NX_HW_STATE_PROD,
FUSE_NX_HW_STATE_DEV
};
#endif

View File

@@ -48,7 +48,7 @@ extern "C" {
#include "hocclk/apm.h" #include "hocclk/apm.h"
#include "hocclk/config.h" #include "hocclk/config.h"
#include "hocclk/errors.h" #include "hocclk/errors.h"
#include "hocclk/psm_ext.h" #include "hocclk/result.hpp"
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -42,22 +42,20 @@ typedef enum
typedef enum typedef enum
{ {
HocClkConsoleType_Icosa = 0, // V1 HocClkConsoleType_Icosa = 0, // V1
HocClkConsoleType_Copper, // Unreleased Erista
HocClkConsoleType_Hoag, // Lite
HocClkConsoleType_Iowa, // V2 HocClkConsoleType_Iowa, // V2
HocClkConsoleType_Calcio, // Unreleased Mariko HocClkConsoleType_Hoag, // Lite
HocClkConsoleType_Aula, // OLED HocClkConsoleType_Aula, // OLED
HocClkConsoleType_EnumMax, HocClkConsoleType_EnumMax,
} HocClkConsoleType; } HocClkConsoleType;
typedef enum { typedef enum {
HocClkVoltage_SOC = 0, HocClkVoltage_SOC = 0, // VDD_SOC rail.
HocClkVoltage_EMCVDD2, HocClkVoltage_EMCVDD2, // DRAM VDD2 rail
HocClkVoltage_CPU, HocClkVoltage_CPU, // CPU rail
HocClkVoltage_GPU, HocClkVoltage_GPU, // GPU rail
HocClkVoltage_EMCVDDQ, // Returns VDD2 on Erista HocClkVoltage_EMCVDDQ, // DRAM VDDQ rail
HocClkVoltage_Display, HocClkVoltage_Display, // Display rail
HocClkVoltage_Battery, HocClkVoltage_Battery, // Battery voltage
HocClkVoltage_EnumMax, HocClkVoltage_EnumMax,
} HocClkVoltage; } HocClkVoltage;
@@ -73,7 +71,7 @@ typedef enum
typedef enum typedef enum
{ {
HocClkModule_CPU = 0, HocClkModule_CPU = 0,
HocClkModule_GPU, HocClkModule_GPU,
HocClkModule_MEM, HocClkModule_MEM,
HocClkModule_Governor, HocClkModule_Governor,
@@ -83,15 +81,17 @@ typedef enum
typedef enum typedef enum
{ {
HocClkThermalSensor_SOC = 0, HocClkThermalSensor_SOC = 0, // SoC temperature in millicelcius
HocClkThermalSensor_PCB, HocClkThermalSensor_PCB, // PCB temperature in millicelcius
HocClkThermalSensor_Skin, HocClkThermalSensor_Skin, // "Skin" temperature in millicelcius
HocClkThermalSensor_Battery, HocClkThermalSensor_Battery, // Battery temperature in millicelcius
HocClkThermalSensor_PMIC, // Always return 50.0C, as thats the only reasonable value the PMIC sensor can generate HocClkThermalSensor_PMIC, // Always return 50.0C, as thats the only reasonable value the PMIC sensor can generate
HocClkThermalSensor_CPU, HocClkThermalSensor_CPU, // CPU temperature in millicelcius
HocClkThermalSensor_GPU, HocClkThermalSensor_GPU, // GPU temperature in millicelcius
HocClkThermalSensor_MEM, // Returns the PLLX sensor value on Mariko HocClkThermalSensor_MEM, // MEM temperature in millicelcius. Returns the PLLX sensor value on Mariko
HocClkThermalSensor_PLLX, HocClkThermalSensor_PLLX, // PLLX temperature in millicelcius
HocClkThermalSensor_AO, // AOTAG
HocClkThermalSensor_BQ24193, // BQ24193 temperature. Refer to BQ24193Temp for returned values
HocClkThermalSensor_EnumMax HocClkThermalSensor_EnumMax
} HocClkThermalSensor; } HocClkThermalSensor;
@@ -113,7 +113,7 @@ typedef enum
HocClkPartLoad_RamBWAll, HocClkPartLoad_RamBWAll,
HocClkPartLoad_RamBWCpu, HocClkPartLoad_RamBWCpu,
HocClkPartLoad_RamBWGpu, HocClkPartLoad_RamBWGpu,
HocClkPartLoad_RamBWPeak, HocClkPartLoad_RamBWPeak, // Maximum possible RAM bandwidth
HocClkPartLoad_EnumMax HocClkPartLoad_EnumMax
} HocClkPartLoad; } HocClkPartLoad;
@@ -128,12 +128,14 @@ typedef enum {
GPUUVLevel_NoUV = 0, GPUUVLevel_NoUV = 0,
GPUUVLevel_SLT, GPUUVLevel_SLT,
GPUUVLevel_HiOPT, GPUUVLevel_HiOPT,
GPUUVLevel_HiOPT15,
GPUUVLevel_HighUV,
GPUUVLevel_EnumMax, GPUUVLevel_EnumMax,
} GPUUndervoltLevel; } GPUUndervoltLevel;
enum { enum {
DVFSMode_Disabled = 0, DVFSMode_Disabled = 0,
DVFSMode_Hijack, DVFSMode_Hijack, // PCV hijack dvfs
// DVFSMode_OfficialService, // DVFSMode_OfficialService,
// DVFSMode_Hack, // DVFSMode_Hack,
DVFSMode_EnumMax, DVFSMode_EnumMax,
@@ -164,8 +166,8 @@ typedef enum {
} RamDisplayMode; } RamDisplayMode;
typedef enum { typedef enum {
MemoryFrequencyMeasurementMode_Actmon = 0, MemoryFrequencyMeasurementMode_PLL = 0,
MemoryFrequencyMeasurementMode_PLL, MemoryFrequencyMeasurementMode_Actmon,
MemoryFrequencyMeasurementMode_EnumMax, MemoryFrequencyMeasurementMode_EnumMax,
} MemoryFrequencyMeasurementMode; } MemoryFrequencyMeasurementMode;
@@ -175,6 +177,51 @@ typedef enum {
RamDisplayUnit_MHzMTs, RamDisplayUnit_MHzMTs,
RamDisplayUnit_EnumMax, RamDisplayUnit_EnumMax,
} RamDisplayUnit; } RamDisplayUnit;
typedef enum {
BQ24193Temp_Normal = 0,
BQ24193Temp_Warm,
BQ24193Temp_Hot,
BQ24193Temp_Overheat,
BQ24193Temp_EnumMax
} BQ24193Temp;
typedef enum AulaColorMode {
AulaDisplayColorMode_DoNotOverride = 0xFF,
AulaDisplayColorMode_Saturated = 0x0,
AulaDisplayColorMode_Washed = 0x45,
AulaDisplayColorMode_Basic = 0x03, // Default
AulaDisplayColorMode_PowerReset = 0x20, // Reset to on power on
AulaDisplayColorMode_Natural = 0x23,
AulaDisplayColorMode_Vivid = 0x65,
AulaDisplayColorMode_Night0 = 0x43,
AulaDisplayColorMode_Night1 = 0x15,
AulaDisplayColorMode_Night2 = 0x35,
AulaDisplayColorMode_Night3 = 0x75,
} AulaColorMode;
// typedef enum {
// PANEL_JDI_XXX062M = 0x10,
// PANEL_JDI_LAM062M109A = 0x0910, // SI.
// PANEL_JDI_LPM062M326A = 0x2610, // LTPS.
// PANEL_INL_P062CCA_AZ1 = 0x0F20,
// PANEL_AUO_A062TAN01 = 0x0F30,
// PANEL_INL_2J055IA_27A = 0x1020,
// PANEL_AUO_A055TAN01 = 0x1030,
// PANEL_SHP_LQ055T1SW10 = 0x1040,
// PANEL_SAM_AMS699VC01 = 0x2050,
// PANEL_RR_SUPER5_OLED_V1 = 0x10E0,
// PANEL_RR_SUPER5_OLED_HD_V1 = 0x10E1,
// PANEL_RR_SUPER7_IPS_V1 = 0x0FE0,
// PANEL_RR_SUPER7_IPS_HD_V1 = 0x0FE1
// // Found on 6/2" clones. Unknown markings. Clone of AUO A062TAN01.
// // Quality seems JDI like. Has bad low backlight scaling. ID: [83] 94 [0F]. Sometimes reports [30] 94 [0F]. Both IDs have correct CRC16.
// PANEL_OEM_CLONE_6_2 = 0x0F83,
// // Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
// PANEL_OEM_CLONE_5_5 = 0x00B3,
// // Found on 5.5" clones with AUO A055TAN02 (59.05A30.001) fake markings.
// PANEL_OEM_CLONE = 0x0000
// //0x0F40 [40] 94 [0F], 5.5" clone
// } HocClkDisplayPanel;
#define HOCCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax) #define HOCCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax)
@@ -237,6 +284,10 @@ static inline const char* hocclkFormatThermalSensor(HocClkThermalSensor thermSen
return pretty ? "MEM" : "mem"; return pretty ? "MEM" : "mem";
case HocClkThermalSensor_PLLX: case HocClkThermalSensor_PLLX:
return pretty ? "PLLX" : "pllx"; return pretty ? "PLLX" : "pllx";
case HocClkThermalSensor_AO:
return pretty ? "AO" : "ao";
case HocClkThermalSensor_BQ24193:
return pretty ? "BQ24193" : "bq24193";
default: default:
return "unknown"; return "unknown";
} }
@@ -284,7 +335,7 @@ static inline const char* hocClkFormatVoltage(HocClkVoltage voltage, bool pretty
case HocClkVoltage_GPU: case HocClkVoltage_GPU:
return pretty ? "GPU" : "gpu"; return pretty ? "GPU" : "gpu";
case HocClkVoltage_EMCVDD2: case HocClkVoltage_EMCVDD2:
return pretty ? "VDD2" : "emcvdd2"; return pretty ? "VDD2" : "vdd2";
case HocClkVoltage_EMCVDDQ: case HocClkVoltage_EMCVDDQ:
return pretty ? "VDDQ" : "vddq"; return pretty ? "VDDQ" : "vddq";
case HocClkVoltage_SOC: case HocClkVoltage_SOC:
@@ -295,3 +346,61 @@ static inline const char* hocClkFormatVoltage(HocClkVoltage voltage, bool pretty
return "unknown"; return "unknown";
} }
} }
static inline const char* hocClkFormatConsoleType(HocClkConsoleType consoleType, bool pretty)
{
switch(consoleType)
{
case HocClkConsoleType_Icosa:
return pretty ? "Icosa (V1)" : "icosa";
case HocClkConsoleType_Iowa:
return pretty ? "Iowa (V2)" : "iowa";
case HocClkConsoleType_Hoag:
return pretty ? "Hoag (Lite)" : "hoag";
case HocClkConsoleType_Aula:
return pretty ? "Aula (OLED)" : "aula";
default:
return "unknown";
}
}
// static inline const char* hocClkFormatPanel(HocClkDisplayPanel panel, bool pretty)
// {
// switch(panel)
// {
// case PANEL_JDI_XXX062M:
// return pretty ? "JDI XXX062M" : "jdi_xxx062m";
// case PANEL_JDI_LAM062M109A:
// return pretty ? "JDI LAM062M109A" : "jdi_lam062m109a";
// case PANEL_JDI_LPM062M326A:
// return pretty ? "JDI LPM062M326A" : "jdi_lpm062m326a";
// case PANEL_INL_P062CCA_AZ1:
// return pretty ? "INL P062CCA-AZ1" : "inl_p062cca_az1";
// case PANEL_AUO_A062TAN01:
// return pretty ? "AUO A062TAN01" : "auo_a062tan01";
// case PANEL_INL_2J055IA_27A:
// return pretty ? "INL 2J055IA-27A" : "inl_2j055ia_27a";
// case PANEL_AUO_A055TAN01:
// return pretty ? "AUO A055TAN01" : "auo_a055tan01";
// case PANEL_SHP_LQ055T1SW10:
// return pretty ? "SHP LQ055T1SW10" : "shp_lq055t1sw10";
// case PANEL_SAM_AMS699VC01:
// return pretty ? "SAM AMS699VC01" : "sam_ams699vc01";
// case PANEL_RR_SUPER5_OLED_V1:
// return pretty ? "SUPER5 OLED" : "rr_super5_oled_v1";
// case PANEL_RR_SUPER5_OLED_HD_V1:
// return pretty ? "SUPER5 OLED HD" : "rr_super5_oled_hd_v1";
// case PANEL_RR_SUPER7_IPS_V1:
// return pretty ? "SUPER7 IPS" : "rr_super7_ips_v1";
// case PANEL_RR_SUPER7_IPS_HD_V1:
// return pretty ? "RR Super7 IPS HD V1" : "rr_super7_ips_hd_v1";
// case PANEL_OEM_CLONE_6_2:
// return pretty ? "OEM Clone 6.2" : "oem_clone_6_2";
// case PANEL_OEM_CLONE_5_5:
// return pretty ? "OEM Clone 5.5" : "oem_clone_5_5";
// case PANEL_OEM_CLONE:
// return pretty ? "OEM Clone" : "oem_clone";
// default:
// return "unknown";
// }
// }

View File

@@ -30,21 +30,41 @@
#include <stdint.h> #include <stdint.h>
#include "board.h" #include "board.h"
typedef struct typedef struct {
{
/*
* This "stable struct" must never be modified. It provides a fixed memory layout so external clients can safely read the expected fields even
* if HocClkContext changes in newer versions and the client is not recompiled.
*/
struct {
#define HocClkModuleStable_EnumMax 5
#define HocClkThermalSensorStable_EnumMax 11
#define HocClkPowerSensorStable_EnumMax 2
#define HocClkPartLoadStable_EnumMax 10
#define HocClkVoltageStable_EnumMax 7
u32 freqs[HocClkModuleStable_EnumMax];
u32 realFreqs[HocClkModuleStable_EnumMax];
u32 overrideFreqs[HocClkModuleStable_EnumMax];
s32 temps[HocClkThermalSensorStable_EnumMax];
s32 power[HocClkPowerSensorStable_EnumMax];
u32 partLoad[HocClkPartLoadStable_EnumMax];
u32 voltages[HocClkVoltageStable_EnumMax];
} stable;
uint64_t applicationId; uint64_t applicationId;
HocClkProfile profile; HocClkProfile profile;
uint32_t freqs[HocClkModule_EnumMax]; uint32_t freqs[HocClkModule_EnumMax];
uint32_t realFreqs[HocClkModule_EnumMax]; uint32_t realFreqs[HocClkModule_EnumMax];
uint32_t overrideFreqs[HocClkModule_EnumMax]; uint32_t overrideFreqs[HocClkModule_EnumMax];
uint32_t temps[HocClkThermalSensor_EnumMax]; int32_t temps[HocClkThermalSensor_EnumMax];
int32_t power[HocClkPowerSensor_EnumMax]; int32_t power[HocClkPowerSensor_EnumMax];
uint32_t partLoad[HocClkPartLoad_EnumMax]; uint32_t partLoad[HocClkPartLoad_EnumMax];
uint32_t voltages[HocClkVoltage_EnumMax]; uint32_t voltages[HocClkVoltage_EnumMax];
u16 speedos[HocClkSpeedo_EnumMax]; u16 speedos[HocClkSpeedo_EnumMax];
u16 iddq[HocClkSpeedo_EnumMax]; u16 iddq[HocClkSpeedo_EnumMax];
u16 waferX; s16 waferX;
u16 waferY; s16 waferY;
// Misc stuff // Misc stuff
GpuSchedulingMode gpuSchedulingMode; GpuSchedulingMode gpuSchedulingMode;
@@ -54,13 +74,16 @@ typedef struct
u8 maxDisplayFreq; u8 maxDisplayFreq;
u8 dramID; u8 dramID;
bool isDram8GB; bool isDram8GB;
HocClkConsoleType consoleType;
// FPS / Resolution // FPS / Resolution
u8 fps; u8 fps;
u16 resolutionHeight; u16 resolutionHeight;
u8 custRev;
u16 kipVersion;
// Reserved for future use // Reserved for future use
u8 reserved[0x428]; u8 reserved[0x35B];
} HocClkContext; } HocClkContext;
typedef struct typedef struct
@@ -71,8 +94,8 @@ typedef struct
}; };
} HocClkTitleProfileList; } HocClkTitleProfileList;
#define HOCCLK_FREQ_LIST_MAX 32 #define HOCCLK_FREQ_LIST_MAX 48
#define GLOBAL_PROFILE_ID 0xA111111111111111 #define HOCCLK_GLOBAL_PROFILE_TID 0xA111111111111111
static_assert(sizeof(HocClkContext) == 0x500); static_assert(sizeof(HocClkContext) == 0x500);

View File

@@ -46,12 +46,8 @@ typedef enum {
HocClkConfigValue_ThermalThrottle, HocClkConfigValue_ThermalThrottle,
HocClkConfigValue_ThermalThrottleThreshold, HocClkConfigValue_ThermalThrottleThreshold,
HocClkConfigValue_HandheldTDP,
HocClkConfigValue_HandheldTDPLimit,
HocClkConfigValue_LiteTDPLimit,
HocClkConfigValue_BatteryChargeCurrent, HocClkConfigValue_BatteryChargeCurrent,
HocClkConfigValue_InputCurrentLimit,
HocClkConfigValue_OverwriteRefreshRate, HocClkConfigValue_OverwriteRefreshRate,
HocClkConfigValue_MaxDisplayClockH, HocClkConfigValue_MaxDisplayClockH,
@@ -72,19 +68,26 @@ typedef enum {
HocClkConfigValue_RamDisplayUnit, HocClkConfigValue_RamDisplayUnit,
HocClkConfigValue_IsFirstLoad, HocClkConfigValue_IsFirstLoad,
HocClkConfigValue_AulaDisplayColorPreset,
HocClkConfigValue_MarikoMiddleFreqs,
HocClkConfigValue_AutoRAMCPUOverclock,
HocClkConfigValue_AutoRamCpuCpuOCFreq,
HocClkConfigValue_AutoRamCpuRamOCThreshold,
KipConfigValue_custRev, KipConfigValue_custRev,
KipConfigValue_KipVersion,
// KipConfigValue_mtcConf, // KipConfigValue_mtcConf,
KipConfigValue_hpMode, KipConfigValue_hpMode,
KipConfigValue_commonEmcMemVolt, KipConfigValue_commonEmcMemVolt,
KipConfigValue_eristaEmcMaxClock, KipConfigValue_eristaEmcMaxClock,
KipConfigValue_eristaEmcMaxClock1,
KipConfigValue_eristaEmcMaxClock2,
KipConfigValue_stepMode, KipConfigValue_stepMode,
KipConfigValue_marikoEmcMaxClock, KipConfigValue_marikoEmcMaxClock,
KipConfigValue_marikoEmcVddqVolt, KipConfigValue_marikoEmcVddqVolt,
KipConfigValue_emcDvbShift, KipConfigValue_emcDvbShift,
KipConfigValue_marikoSocVmax,
KipConfigValue_t1_tRCD, KipConfigValue_t1_tRCD,
KipConfigValue_t2_tRP, KipConfigValue_t2_tRP,
@@ -111,9 +114,6 @@ typedef enum {
KipConfigValue_write_latency_1866, KipConfigValue_write_latency_1866,
KipConfigValue_write_latency_2133, KipConfigValue_write_latency_2133,
KipConfigValue_mem_burst_read_latency,
KipConfigValue_mem_burst_write_latency,
KipConfigValue_eristaCpuUV, KipConfigValue_eristaCpuUV,
KipConfigValue_eristaCpuVmin, KipConfigValue_eristaCpuVmin,
KipConfigValue_eristaCpuMaxVolt, KipConfigValue_eristaCpuMaxVolt,
@@ -134,10 +134,10 @@ typedef enum {
KipConfigValue_marikoGpuUV, KipConfigValue_marikoGpuUV,
KipConfigValue_marikoGpuVmin, KipConfigValue_marikoGpuVmin,
KipConfigValue_marikoGpuBootVolt,
KipConfigValue_marikoGpuVmax, KipConfigValue_marikoGpuVmax,
KipConfigValue_commonGpuVoltOffset, KipConfigValue_commonGpuVoltOffset,
KipConfigValue_gpuSpeedo,
KipConfigValue_g_volt_76800, KipConfigValue_g_volt_76800,
KipConfigValue_g_volt_153600, KipConfigValue_g_volt_153600,
@@ -235,17 +235,11 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
case HocClkConfigValue_ThermalThrottleThreshold: case HocClkConfigValue_ThermalThrottleThreshold:
return pretty ? "Thermal Throttle Threshold" : "thermal_throttle_threshold"; return pretty ? "Thermal Throttle Threshold" : "thermal_throttle_threshold";
case HocClkConfigValue_HandheldTDP:
return pretty ? "Handheld TDP" : "handheld_tdp";
case HocClkConfigValue_HandheldTDPLimit:
return pretty ? "Handheld TDP Limit" : "tdp_limit";
case HocClkConfigValue_LiteTDPLimit:
return pretty ? "Handheld TDP Limit" : "tdp_limit_l";
case HocClkConfigValue_BatteryChargeCurrent: case HocClkConfigValue_BatteryChargeCurrent:
return pretty ? "Battery Charge Current" : "bat_charge_current"; return pretty ? "Battery Charge Current" : "bat_charge_current";
case HocClkConfigValue_InputCurrentLimit:
return pretty ? "Input Current Limit" : "in_curr_limit";
case HocClkConfigValue_OverwriteRefreshRate: case HocClkConfigValue_OverwriteRefreshRate:
return pretty ? "Display Refresh Rate Changing" : "drr_changing"; return pretty ? "Display Refresh Rate Changing" : "drr_changing";
@@ -284,10 +278,23 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
case HocClkConfigValue_RamDisplayUnit: case HocClkConfigValue_RamDisplayUnit:
return pretty ? "RAM Frequency Display Unit" : "RAM_display_unit"; return pretty ? "RAM Frequency Display Unit" : "RAM_display_unit";
case HocClkConfigValue_AulaDisplayColorPreset:
return pretty ? "Aula Display Color Preset" : "aula_color_preset";
case HocClkConfigValue_MarikoMiddleFreqs:
return pretty ? "Mariko Middle Clocks" : "mariko_middle_freqs";
case HocClkConfigValue_AutoRAMCPUOverclock:
return pretty ? "Auto High RAM CPU OC" : "auto_high_ram_cpu_oc";
case HocClkConfigValue_AutoRamCpuCpuOCFreq:
return pretty ? "Auto High RAM CPU OC Freq" : "auto_ram_cpu_cpu_oc_freq";
case HocClkConfigValue_AutoRamCpuRamOCThreshold:
return pretty ? "Auto High RAM CPU OC RAM Threshold" : "auto_ram_cpu_ram_oc_threshold";
// KIP config values // KIP config values
case KipConfigValue_custRev: case KipConfigValue_custRev:
return pretty ? "Custom Revision" : "kip_cust_rev"; return pretty ? "Custom Revision" : "kip_cust_rev";
case KipConfigValue_KipVersion:
return pretty ? "KIP Version" : "kip_version";
// case KipConfigValue_mtcConf: // case KipConfigValue_mtcConf:
// return pretty ? "MTC Config" : "kip_mtc_conf"; // return pretty ? "MTC Config" : "kip_mtc_conf";
case KipConfigValue_hpMode: case KipConfigValue_hpMode:
@@ -297,11 +304,7 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
case KipConfigValue_commonEmcMemVolt: case KipConfigValue_commonEmcMemVolt:
return pretty ? "Common EMC/MEM Voltage" : "common_emc_mem_volt"; return pretty ? "Common EMC/MEM Voltage" : "common_emc_mem_volt";
case KipConfigValue_eristaEmcMaxClock: case KipConfigValue_eristaEmcMaxClock:
return pretty ? "Erista EMC Max Clock 1" : "erista_emc_max_clock"; return pretty ? "Erista EMC Max Clock" : "erista_emc_max_clock2";
case KipConfigValue_eristaEmcMaxClock1:
return pretty ? "Erista EMC Max Clock 2" : "erista_emc_max_clock1";
case KipConfigValue_eristaEmcMaxClock2:
return pretty ? "Erista EMC Max Clock 3" : "erista_emc_max_clock2";
case KipConfigValue_stepMode: case KipConfigValue_stepMode:
return pretty ? "Step Mode:" : "step_mode"; return pretty ? "Step Mode:" : "step_mode";
case KipConfigValue_marikoEmcMaxClock: case KipConfigValue_marikoEmcMaxClock:
@@ -310,7 +313,8 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
return pretty ? "Mariko EMC VDDQ Voltage" : "mariko_emc_vddq_volt"; return pretty ? "Mariko EMC VDDQ Voltage" : "mariko_emc_vddq_volt";
case KipConfigValue_emcDvbShift: case KipConfigValue_emcDvbShift:
return pretty ? "EMC DVB Shift" : "emc_dvb_shift"; return pretty ? "EMC DVB Shift" : "emc_dvb_shift";
case KipConfigValue_marikoSocVmax:
return pretty ? "SOC Vmax" : "soc_vmax";
// Memory timings // Memory timings
case KipConfigValue_t1_tRCD: case KipConfigValue_t1_tRCD:
return pretty ? "t1 - tRCD" : "t1_trcd"; return pretty ? "t1 - tRCD" : "t1_trcd";
@@ -357,11 +361,6 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
case KipConfigValue_write_latency_2133: case KipConfigValue_write_latency_2133:
return pretty ? "2133 Write Latency" : "write_latency_2133"; return pretty ? "2133 Write Latency" : "write_latency_2133";
case KipConfigValue_mem_burst_read_latency:
return pretty ? "Memory Burst Read Latency" : "mem_burst_read_latency";
case KipConfigValue_mem_burst_write_latency:
return pretty ? "Memory Burst Write Latency" : "mem_burst_write_latency";
// CPU Erista // CPU Erista
case KipConfigValue_eristaCpuUV: case KipConfigValue_eristaCpuUV:
return pretty ? "Erista CPU Undervolt" : "erista_cpu_uv"; return pretty ? "Erista CPU Undervolt" : "erista_cpu_uv";
@@ -405,13 +404,13 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
return pretty ? "Mariko GPU Undervolt" : "mariko_gpu_uv"; return pretty ? "Mariko GPU Undervolt" : "mariko_gpu_uv";
case KipConfigValue_marikoGpuVmin: case KipConfigValue_marikoGpuVmin:
return pretty ? "Mariko GPU Vmin" : "mariko_gpu_vmin"; return pretty ? "Mariko GPU Vmin" : "mariko_gpu_vmin";
case KipConfigValue_marikoGpuBootVolt:
return pretty ? "Mariko GPU Boot Voltage" : "mariko_gpu_boot_volt";
case KipConfigValue_marikoGpuVmax: case KipConfigValue_marikoGpuVmax:
return pretty ? "Mariko GPU Vmax" : "mariko_gpu_vmax"; return pretty ? "Mariko GPU Vmax" : "mariko_gpu_vmax";
case KipConfigValue_commonGpuVoltOffset: case KipConfigValue_commonGpuVoltOffset:
return pretty ? "Common GPU Voltage Offset" : "common_gpu_volt_offset"; return pretty ? "Common GPU Voltage Offset" : "common_gpu_volt_offset";
case KipConfigValue_gpuSpeedo:
return pretty ? "GPU Speedo" : "gpu_speedo";
// Mariko GPU voltages (24) // Mariko GPU voltages (24)
case KipConfigValue_g_volt_76800: return pretty ? "Mariko GPU Volt 76 MHz" : "g_volt_76800"; case KipConfigValue_g_volt_76800: return pretty ? "Mariko GPU Volt 76 MHz" : "g_volt_76800";
@@ -491,11 +490,13 @@ static inline uint64_t hocclkDefaultConfigValue(HocClkConfigValue val)
case HocClkConfigValue_UncappedClocks: case HocClkConfigValue_UncappedClocks:
case HocClkConfigValue_OverwriteBoostMode: case HocClkConfigValue_OverwriteBoostMode:
case HocClkConfigValue_BatteryChargeCurrent: case HocClkConfigValue_BatteryChargeCurrent:
case HocClkConfigValue_InputCurrentLimit:
case HocClkConfigValue_OverwriteRefreshRate: case HocClkConfigValue_OverwriteRefreshRate:
case HocClkConfigValue_GPUScheduling: case HocClkConfigValue_GPUScheduling:
case HocClkConfigValue_LiveCpuUv: case HocClkConfigValue_LiveCpuUv:
case HocClkConfigValue_GPUSchedulingMethod: case HocClkConfigValue_GPUSchedulingMethod:
case HocClkConfigValue_MemoryFrequencyMeasurementMode: case HocClkConfigValue_MemoryFrequencyMeasurementMode:
case HocClkConfigValue_MarikoMiddleFreqs:
return 0ULL; return 0ULL;
case HocClkConfigValue_RamDisplayUnit: case HocClkConfigValue_RamDisplayUnit:
return (uint64_t)RamDisplayUnit_MHz; return (uint64_t)RamDisplayUnit_MHz;
@@ -506,22 +507,24 @@ static inline uint64_t hocclkDefaultConfigValue(HocClkConfigValue val)
return 1963ULL; return 1963ULL;
case HocClkConfigValue_ThermalThrottle: case HocClkConfigValue_ThermalThrottle:
case HocClkConfigValue_HandheldTDP:
case HocClkConfigValue_IsFirstLoad: case HocClkConfigValue_IsFirstLoad:
case HocClkConfigValue_DVFSMode: case HocClkConfigValue_DVFSMode:
case HocClkConfigValue_AutoRAMCPUOverclock:
return 1ULL; return 1ULL;
case HocClkConfigValue_AutoRamCpuCpuOCFreq:
return 1683000ULL;
case HocClkConfigValue_AutoRamCpuRamOCThreshold:
return 2666000ULL;
case HocClkConfigValue_ThermalThrottleThreshold: case HocClkConfigValue_ThermalThrottleThreshold:
return 70ULL; return 70ULL;
case HocClkConfigValue_HandheldTDPLimit:
return 9600ULL; // 8600mW will trigger on erista stock, so raise it a bit
case HocClkConfigValue_LiteTDPLimit:
return 6400ULL; // 0.5C
case HocClkConfigValue_CpuGovernorMinimumFreq: case HocClkConfigValue_CpuGovernorMinimumFreq:
return 612000000ULL; // 612MHz return 612000000ULL; // 612MHz
case HocClkConfigValue_MaxDisplayClockH: case HocClkConfigValue_MaxDisplayClockH:
return 60ULL; return 60ULL;
case HocClkConfigValue_DisplayVoltage: case HocClkConfigValue_DisplayVoltage:
return 1200ULL; // Auto return 1200ULL; // Auto
case HocClkConfigValue_AulaDisplayColorPreset:
return AulaDisplayColorMode_DoNotOverride;
default: default:
return 0ULL; return 0ULL;
} }
@@ -534,8 +537,6 @@ static inline uint64_t hocclkValidConfigValue(HocClkConfigValue val, uint64_t in
case HocClkConfigValue_EristaMaxCpuClock: case HocClkConfigValue_EristaMaxCpuClock:
case HocClkConfigValue_MarikoMaxCpuClock: case HocClkConfigValue_MarikoMaxCpuClock:
case HocClkConfigValue_ThermalThrottleThreshold: case HocClkConfigValue_ThermalThrottleThreshold:
case HocClkConfigValue_HandheldTDPLimit:
case HocClkConfigValue_LiteTDPLimit:
case HocClkConfigValue_PollingIntervalMs: case HocClkConfigValue_PollingIntervalMs:
case HocClkConfigValue_MaxDisplayClockH: case HocClkConfigValue_MaxDisplayClockH:
return input > 0; return input > 0;
@@ -547,25 +548,26 @@ static inline uint64_t hocclkValidConfigValue(HocClkConfigValue val, uint64_t in
case HocClkConfigValue_UncappedClocks: case HocClkConfigValue_UncappedClocks:
case HocClkConfigValue_OverwriteBoostMode: case HocClkConfigValue_OverwriteBoostMode:
case HocClkConfigValue_ThermalThrottle: case HocClkConfigValue_ThermalThrottle:
case HocClkConfigValue_HandheldTDP:
case HocClkConfigValue_OverwriteRefreshRate: case HocClkConfigValue_OverwriteRefreshRate:
case HocClkConfigValue_IsFirstLoad: case HocClkConfigValue_IsFirstLoad:
case HocClkConfigValue_EnableExperimentalSettings: case HocClkConfigValue_EnableExperimentalSettings:
case HocClkConfigValue_LiveCpuUv: case HocClkConfigValue_LiveCpuUv:
case HocClkConfigValue_GPUSchedulingMethod: case HocClkConfigValue_GPUSchedulingMethod:
case HocClkConfigValue_MarikoMiddleFreqs:
case HocClkConfigValue_AutoRAMCPUOverclock:
return (input & 0x1) == input; return (input & 0x1) == input;
case KipConfigValue_KipVersion:
case KipConfigValue_custRev: case KipConfigValue_custRev:
// case KipConfigValue_mtcConf: // case KipConfigValue_mtcConf:
case KipConfigValue_hpMode: case KipConfigValue_hpMode:
case KipConfigValue_commonEmcMemVolt: case KipConfigValue_commonEmcMemVolt:
case KipConfigValue_eristaEmcMaxClock: case KipConfigValue_eristaEmcMaxClock:
case KipConfigValue_eristaEmcMaxClock1:
case KipConfigValue_eristaEmcMaxClock2:
case KipConfigValue_stepMode: case KipConfigValue_stepMode:
case KipConfigValue_marikoEmcMaxClock: case KipConfigValue_marikoEmcMaxClock:
case KipConfigValue_marikoEmcVddqVolt: case KipConfigValue_marikoEmcVddqVolt:
case KipConfigValue_emcDvbShift: case KipConfigValue_emcDvbShift:
case KipConfigValue_marikoSocVmax:
case KipConfigValue_t1_tRCD: case KipConfigValue_t1_tRCD:
case KipConfigValue_t2_tRP: case KipConfigValue_t2_tRP:
case KipConfigValue_t3_tRAS: case KipConfigValue_t3_tRAS:
@@ -586,8 +588,6 @@ static inline uint64_t hocclkValidConfigValue(HocClkConfigValue val, uint64_t in
case KipConfigValue_write_latency_1600: case KipConfigValue_write_latency_1600:
case KipConfigValue_write_latency_1866: case KipConfigValue_write_latency_1866:
case KipConfigValue_write_latency_2133: case KipConfigValue_write_latency_2133:
case KipConfigValue_mem_burst_read_latency:
case KipConfigValue_mem_burst_write_latency:
case KipConfigValue_eristaCpuUV: case KipConfigValue_eristaCpuUV:
case KipConfigValue_eristaCpuMaxVolt: case KipConfigValue_eristaCpuMaxVolt:
case KipConfigValue_marikoCpuUVLow: case KipConfigValue_marikoCpuUVLow:
@@ -603,9 +603,9 @@ static inline uint64_t hocclkValidConfigValue(HocClkConfigValue val, uint64_t in
case KipConfigValue_eristaGpuVmin: case KipConfigValue_eristaGpuVmin:
case KipConfigValue_marikoGpuUV: case KipConfigValue_marikoGpuUV:
case KipConfigValue_marikoGpuVmin: case KipConfigValue_marikoGpuVmin:
case KipConfigValue_marikoGpuBootVolt:
case KipConfigValue_marikoGpuVmax: case KipConfigValue_marikoGpuVmax:
case KipConfigValue_commonGpuVoltOffset: case KipConfigValue_commonGpuVoltOffset:
case KipConfigValue_gpuSpeedo:
case KipConfigValue_g_volt_76800: case KipConfigValue_g_volt_76800:
case KipConfigValue_g_volt_153600: case KipConfigValue_g_volt_153600:
case KipConfigValue_g_volt_230400: case KipConfigValue_g_volt_230400:
@@ -669,13 +669,20 @@ static inline uint64_t hocclkValidConfigValue(HocClkConfigValue val, uint64_t in
case HocClkConfigValue_CpuGovernorMinimumFreq: case HocClkConfigValue_CpuGovernorMinimumFreq:
case HocClkConfigValue_MemoryFrequencyMeasurementMode: case HocClkConfigValue_MemoryFrequencyMeasurementMode:
case HocClkConfigValue_RamDisplayUnit: case HocClkConfigValue_RamDisplayUnit:
case HocClkConfigValue_AulaDisplayColorPreset:
case HocClkConfigValue_AutoRamCpuCpuOCFreq:
case HocClkConfigValue_AutoRamCpuRamOCThreshold:
return true; return true;
case HocClkConfigValue_BatteryChargeCurrent: case HocClkConfigValue_BatteryChargeCurrent:
return ((input >= 1024) && (input <= 3072)) || !input; return ((input >= 1024) && (input <= 3072)) || !input;
case HocClkConfigValue_InputCurrentLimit:
return ((input >= 100) && (input <= 3000)) || !input;
case HocClkConfigValue_DisplayVoltage: case HocClkConfigValue_DisplayVoltage:
return ((input >= 800) && (input <= 1325)); return ((input >= 800) && (input <= 1325));
default: default:
return false; return true;
} }
} }

View File

@@ -1,94 +0,0 @@
/*
* Copyright (c) KazushiMe
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <switch.h>
typedef enum {
PsmPDC_NewPDO = 1, //Received new Power Data Object
PsmPDC_NoPD = 2, //No Power Delivery source is detected
PsmPDC_AcceptedRDO = 3 //Received and accepted Request Data Object
} PsmChargeInfoPDC; //BM92T series
typedef enum {
PsmPowerRole_Sink = 1,
PsmPowerRole_Source = 2
} PsmPowerRole;
const char* PsmPowerRoleToStr(PsmPowerRole role);
typedef enum {
PsmInfoChargerType_None = 0,
PsmInfoChargerType_PD = 1,
PsmInfoChargerType_TypeC_1500mA = 2,
PsmInfoChargerType_TypeC_3000mA = 3,
PsmInfoChargerType_DCP = 4,
PsmInfoChargerType_CDP = 5,
PsmInfoChargerType_SDP = 6,
PsmInfoChargerType_Apple_500mA = 7,
PsmInfoChargerType_Apple_1000mA = 8,
PsmInfoChargerType_Apple_2000mA = 9
} PsmInfoChargerType;
const char* PsmInfoChargerTypeToStr(PsmInfoChargerType type);
typedef enum {
PsmFlags_NoHub = BIT(0), //If hub is disconnected
PsmFlags_Rail = BIT(8), //At least one Joy-con is charging from rail
PsmFlags_SPDSRC = BIT(12), //OTG
PsmFlags_ACC = BIT(16) //Accessory
} PsmChargeInfoFlags;
typedef struct {
int32_t InputCurrentLimit; //Input (Sink) current limit in mA
int32_t VBUSCurrentLimit; //Output (Source/VBUS/OTG) current limit in mA
int32_t ChargeCurrentLimit; //Battery charging current limit in mA (512mA when Docked, 768mA when BatteryTemperature < 17.0 C)
int32_t ChargeVoltageLimit; //Battery charging voltage limit in mV (3952mV when BatteryTemperature >= 51.0 C)
int32_t unk_x10; //Possibly an emum, getting the same value as PowerRole in all tested cases
int32_t unk_x14; //Possibly flags
PsmChargeInfoPDC PDCState; //Power Delivery Controller State
int32_t BatteryTemperature; //Battery temperature in milli C
int32_t RawBatteryCharge; //Raw battery charged capacity per cent-mille (i.e. 100% = 100000 pcm)
int32_t VoltageAvg; //Voltage avg in mV (more in Notes)
int32_t BatteryAge; //Battery age (capacity full / capacity design) per cent-mille (i.e. 100% = 100000 pcm)
PsmPowerRole PowerRole;
PsmInfoChargerType ChargerType;
int32_t ChargerVoltageLimit; //Charger and external device voltage limit in mV
int32_t ChargerCurrentLimit; //Charger and external device current limit in mA
PsmChargeInfoFlags Flags; //Unknown flags
} PsmChargeInfo;
typedef enum {
Psm_EnableBatteryCharging = 2,
Psm_DisableBatteryCharging = 3,
Psm_EnableFastBatteryCharging = 10,
Psm_DisableFastBatteryCharging = 11,
Psm_GetBatteryChargeInfoFields = 17,
} IPsmServerCmd;
bool PsmIsChargerConnected(const PsmChargeInfo* info);
bool PsmIsCharging(const PsmChargeInfo* info);
typedef enum {
PsmBatteryState_Discharging,
PsmBatteryState_ChargingPaused,
PsmBatteryState_FastCharging
} PsmBatteryState;
PsmBatteryState PsmGetBatteryState(const PsmChargeInfo* info);
const char* PsmGetBatteryStateIcon(const PsmChargeInfo* info);

View File

@@ -0,0 +1,11 @@
#pragma once
#include <switch.h>
#define R_UNLESS(rc) \
do { \
if (R_FAILED(rc)) { \
return; \
} \
} while (0)
/* TODO: Add more Result macros. */

View File

@@ -1,64 +0,0 @@
/*
* Copyright (c) 2023 KazushiMe
* Licensed under the GPLv2
*/
#pragma once
#include <switch.h>
// To use i2c service, sm and i2c should be intialized via smInitialize() and i2cInitialize().
Result I2cSet_U8(I2cDevice dev, u8 reg, u8 val);
Result I2cRead_OutU8(I2cDevice dev, u8 reg, u8 *out);
Result I2cRead_OutU16(I2cDevice dev, u8 reg, u16 *out);
// Max17050 fuel gauge
float I2c_Max17050_GetBatteryCurrent();
const u8 MAX17050_CURRENT_REG = 0x0A;
// Buck Converter
typedef enum I2c_BuckConverter_Reg {
I2c_Max77620_SD1VOLT_REG = 0x17, // Used for Erista DDR VDDQ+VDD2 / Mariko VDD2
I2c_Max77620_LDO0VOLT_REG = 0x23, // Used for Erista DDR VDDQ+VDD2 / Mariko VDD2
I2c_Max77621_VOLT_REG = 0x00,
I2c_Max77812_CPUVOLT_REG = 0x26,
I2c_Max77812_GPUVOLT_REG = 0x23,
I2c_Max77812_MEMVOLT_REG = 0x25, // Master 3 (GPU 1 + 2, DRAM 3, CPU 4), used for Mariko VDDQ
} I2c_BuckConverter_Reg;
typedef struct I2c_BuckConverter_Domain {
I2cDevice device;
I2c_BuckConverter_Reg reg;
u8 volt_mask;
u32 uv_step;
u32 uv_min;
u32 uv_max;
u8 por_val;
} I2c_BuckConverter_Domain;
const I2c_BuckConverter_Domain I2c_Erista_CPU = { I2cDevice_Max77621Cpu, I2c_Max77621_VOLT_REG, 0x7F, 6250, 606250, 1400000, };
const I2c_BuckConverter_Domain I2c_Erista_GPU = { I2cDevice_Max77621Gpu, I2c_Max77621_VOLT_REG, 0x7F, 6250, 606250, 1400000, };
const I2c_BuckConverter_Domain I2c_Erista_DRAM = { I2cDevice_Max77620Pmic, I2c_Max77620_SD1VOLT_REG, 0x3F, 12500, 600000, 1250000, };
const I2c_BuckConverter_Domain I2c_Display = { I2cDevice_Max77620Pmic, I2c_Max77620_LDO0VOLT_REG, 0x7F, 25000, 800000, 1325000, };
const I2c_BuckConverter_Domain I2c_Mariko_CPU = { I2cDevice_Max77812_2, I2c_Max77812_CPUVOLT_REG, 0xFF, 5000, 250000, 1525000, 0x78 };
const I2c_BuckConverter_Domain I2c_Mariko_GPU = { I2cDevice_Max77812_2, I2c_Max77812_GPUVOLT_REG, 0xFF, 5000, 250000, 1525000, 0x78 };
const I2c_BuckConverter_Domain I2c_Mariko_DRAM_VDDQ = { I2cDevice_Max77812_2, I2c_Max77812_MEMVOLT_REG, 0xFF, 5000, 250000, 700000, 0x78 };
const I2c_BuckConverter_Domain I2c_Mariko_DRAM_VDD2 = { I2cDevice_Max77620Pmic, I2c_Max77620_SD1VOLT_REG, 0x7F, 12500, 600000, 1250000, };
u32 I2c_BuckConverter_GetMvOut(const I2c_BuckConverter_Domain* domain);
Result I2c_BuckConverter_SetMvOut(const I2c_BuckConverter_Domain* domain, u32 mvolt);
// Bq24193 Battery management
u32 I2c_Bq24193_Convert_Raw_mA(u8 raw);
u8 I2c_Bq24193_Convert_mA_Raw(u32 ma);
Result I2c_Bq24193_GetFastChargeCurrentLimit(u32 *ma);
Result I2c_Bq24193_SetFastChargeCurrentLimit(u32 ma);
const u32 MA_RANGE_MIN = 512;
const u32 MA_RANGE_MAX = 4544;
const u8 BQ24193_CHARGE_CURRENT_CONTROL_REG = 0x2;

View File

@@ -1,67 +0,0 @@
/*
* Copyright (c) KazushiMe
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include <hocclk/psm_ext.h>
const char* PsmPowerRoleToStr(PsmPowerRole role) {
switch (role) {
case PsmPowerRole_Sink: return "Sink";
case PsmPowerRole_Source: return "Source";
default: return "Unknown";
}
}
const char* PsmInfoChargerTypeToStr(PsmInfoChargerType type) {
switch (type) {
case PsmInfoChargerType_None: return "None";
case PsmInfoChargerType_PD: return "USB-C PD";
case PsmInfoChargerType_TypeC_1500mA:
case PsmInfoChargerType_TypeC_3000mA: return "USB-C";
case PsmInfoChargerType_DCP: return "USB DCP";
case PsmInfoChargerType_CDP: return "USB CDP";
case PsmInfoChargerType_SDP: return "USB SDP";
case PsmInfoChargerType_Apple_500mA:
case PsmInfoChargerType_Apple_1000mA:
case PsmInfoChargerType_Apple_2000mA: return "Apple";
default: return "Unknown";
}
}
bool PsmIsChargerConnected(const PsmChargeInfo* info) {
return info->ChargerType != PsmInfoChargerType_None;
}
bool PsmIsCharging(const PsmChargeInfo* info) {
return PsmIsChargerConnected(info) && ((info->unk_x14 >> 8) & 1);
}
PsmBatteryState PsmGetBatteryState(const PsmChargeInfo* info) {
if (!PsmIsChargerConnected(info))
return PsmBatteryState_Discharging;
if (!PsmIsCharging(info))
return PsmBatteryState_ChargingPaused;
return PsmBatteryState_FastCharging;
}
const char* PsmGetBatteryStateIcon(const PsmChargeInfo* info) {
switch (PsmGetBatteryState(info)) {
case PsmBatteryState_Discharging: return "\u25c0"; // ◀
case PsmBatteryState_ChargingPaused:return "| |";
case PsmBatteryState_FastCharging: return "\u25b6"; // ▶
default: return "?";
}
}

View File

@@ -22,12 +22,12 @@ BUILD := build
OUTDIR := out OUTDIR := out
RESOURCES := res RESOURCES := res
SOURCES := src src/ui/gui src/ui/elements ../common/src ../common/src/client SOURCES := src src/ui/gui src/ui/elements ../common/src ../common/src/client
DATA := data DATA := data ../assets
INCLUDES := ../common/include INCLUDES := ../common/include
EXEFS_SRC := exefs_src EXEFS_SRC := exefs_src
IS_MINIMAL := 0 IS_MINIMAL := 0
APP_TITLE := Horizon OC Gaea APP_TITLE := Horizon OC
NO_ICON := 1 NO_ICON := 1
@@ -39,7 +39,7 @@ include ${TOPDIR}/lib/libultrahand/ultrahand.mk
# version control constants # version control constants
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
#TARGET_VERSION := $(shell git describe --dirty --always --tags) #TARGET_VERSION := $(shell git describe --dirty --always --tags)
APP_VERSION := 2.0.2 APP_VERSION := 2.4.0 # ensure to set KIP_VERSION and CUST_REV in sysmodule Makefile when updating this
TARGET_VERSION := $(APP_VERSION) TARGET_VERSION := $(APP_VERSION)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@@ -166,6 +166,11 @@ $(OUTPUT).elf: $(OFILES)
@echo $(notdir $<) @echo $(notdir $<)
@$(bin2o) @$(bin2o)
%.rgba.o : %.rgba
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS) -include $(DEPENDS)
#--------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------

View File

@@ -1,37 +1,33 @@
{ {
"Information": "Informationen", "Information": "Informationen",
"IDDQ:": "IDDQ:",
"Module: ": "Modul:",
"sys-dock status:": "Sys-Dock-Status:",
"SaltyNX status:": "SaltyNX-Status:",
"RR Display status:": "RR Anzeigestatus:",
"Wafer Position:": "Waferposition:",
"Credits": "Credits",
"Developers": "Entwickler",
"Contributors": "Mitwirkende",
"Testers": "Tester",
"Special Thanks": "Besonderer Dank",
"Unknown": "Unbekannt", "Unknown": "Unbekannt",
"Installed": "Installiert", "Installed": "Installiert",
"Not Installed": "Nicht installiert", "Not Installed": "Nicht installiert",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "DIE BIERWAREN-LIZENZ",
"Default": "Standard", "Default": "Standard",
"Do Not Override": "Nicht überschreiben", "Do Not Override": "Nicht überschreiben",
"Do not override": "Nicht überschreiben",
"Disabled": "Deaktiviert", "Disabled": "Deaktiviert",
"Enabled": "Aktiviert", "Enabled": "Aktiviert",
" \\ue0e3 Reset": "\\ue0e3 Zurücksetzen", "Enabled (Default)": "Aktiviert (Standard)",
"Display": "Anzeige", "Enable": "Aktivieren",
"Application changed\\n\\n": "Anwendung geändert\\n\\n", "Fatal error": "Fataler Fehler",
"The running application changed\\n\\n": "Die laufende Anwendung hat sich geändert\\n\\n",
"while editing was going on.": "während die Bearbeitung im Gange war.",
"Board": "Vorstand",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Es konnte keine Verbindung zum hoc-clk-Systemmodul hergestellt werden.\\n\\n", "Could not connect to hoc-clk sysmodule.\\n\\n": "Es konnte keine Verbindung zum hoc-clk-Systemmodul hergestellt werden.\\n\\n",
"Please make sure everything is\\n\\n": "Bitte stellen Sie sicher, dass alles in Ordnung ist\\n\\n", "Please make sure everything is\\n\\n": "Bitte stellen Sie sicher, dass alles in Ordnung ist\\n\\n",
"correctly installed and enabled.": "korrekt installiert und aktiviert.", "correctly installed and enabled.": "korrekt installiert und aktiviert.",
"Fatal error": "Fataler Fehler",
"Edit App Profile": "App-Profil bearbeiten",
"Edit Global Profile": "Globales Profil bearbeiten",
"Temporary Overrides": "Temporäre Überschreibungen",
"Temporary Overrides ": "Temporäre Überschreibungen", "Temporary Overrides ": "Temporäre Überschreibungen",
"  Reset": " Zurücksetzen",
"Settings": "Einstellungen",
"About": "Über",
"Credits": "Credits",
"Application changed\\n\\n": "Anwendung geändert\\n\\n",
"The running application changed\\n\\n": "Die laufende Anwendung hat sich geändert\\n\\n",
"while editing was going on.": "während die Bearbeitung im Gange war.",
"Sleep Mode": "Schlafmodus", "Sleep Mode": "Schlafmodus",
"Stock": "Lager", "Stock": "Lager",
"Dev OC": "Entwickler OC", "Dev OC": "Entwickler OC",
@@ -40,57 +36,74 @@
"Unsafe Max": "Unsicher max", "Unsafe Max": "Unsicher max",
"Absolute Max": "Absolutes Maximum", "Absolute Max": "Absolutes Maximum",
"Handheld Safe Max": "Handsafe max", "Handheld Safe Max": "Handsafe max",
"Enable": "Aktivieren",
"Edit App Profile": "App-Profil bearbeiten",
"Edit Global Profile": "Globales Profil bearbeiten",
"Temporary Overrides": "Temporäre Überschreibungen",
"Settings": "Einstellungen",
"About": "Über",
"Compiling with minimal features": "Kompilieren mit minimalen Funktionen",
"General Settings": "Allgemeine Einstellungen", "General Settings": "Allgemeine Einstellungen",
"Governor Settings": "Gouverneurseinstellungen", "Governor Settings": "Regler-Einstellungen",
"Safety Settings": "Sicherheitseinstellungen", "Safety Settings": "Sicherheitseinstellungen",
"Save KIP Settings": "Speichern Sie die KIP-Einstellungen", "Save KIP Settings": "KIP-Einstellungen speichern",
"RAM Settings": "RAM-Einstellungen", "RAM Settings": "RAM-Einstellungen",
"CPU Settings": "CPU-Einstellungen", "CPU Settings": "CPU-Einstellungen",
"GPU Settings": "GPU-Einstellungen", "GPU Settings": "GPU-Einstellungen",
"Display Settings": "Anzeigeeinstellungen", "Display Settings": "Anzeigeeinstellungen",
"Experimental Settings": "Experimentelle Einstellungen",
"Experimental": "Experimentell", "Experimental": "Experimentell",
" Settings marked in blue": "Blau markierte Einstellungen",
"don't require a reboot to apply!": "erfordern keinen Neustart zum Aktivieren!",
"You can also press  to show": "Drücken Sie auch  zum Anzeigen",
"information about each setting.": "von Informationen zu jeder Einstellung.",
" Experimental Settings are incomplete ": "Experimentelle Einstellungen unvollständig",
"and may not work correctly or at all!": "und funktionieren möglicherweise gar nicht!",
"Here be dragons!": "Hier gibt es Drachen!",
"RAM Voltage Display Mode": "RAM-Spannungsanzeigemodus",
"RAM Display Unit": "RAM-Anzeigeeinheit",
"Polling Interval": "Abfrageintervall",
"GPU Scheduling Override Method": "GPU-Planungsüberschreibungsmethode", "GPU Scheduling Override Method": "GPU-Planungsüberschreibungsmethode",
"GPU Scheduling Override": "GPU-Planungsüberschreibung",
"GPU Boot Volt": "GPU Boot-Spannung",
"GPU Boot Voltage": "GPU Boot-Spannung",
"Memory Frequency Measurement Mode": "RAM-Frequenz-Messmodus",
" Overriding the charge current": "Überschreiben des Ladestroms",
"can be dangerous and may cause": "kann gefährlich sein und verursachen", "can be dangerous and may cause": "kann gefährlich sein und verursachen",
"damage to your battery or charger!": "Schäden an Ihrem Akku oder Ladegerät!", "damage to your battery or charger!": "Schäden an Ihrem Akku oder Ladegerät!",
"Charge Current Override": "Ladestrom-Überbrückung", "Charge Current Override": "Ladestrom-Überbrückung",
"RAM Voltage Display Mode": "RAM-Spannungsanzeigemodus", "Display Color Preset": "Farbprofil",
"Polling Interval": "Abfrageintervall", "Basic": "Standard",
"Saturated": "Gesättigt",
"Washed": "Verblasst",
"Natural": "Natürlich",
"Vivid": "Lebendig",
"CPU Governor Minimum Frequency": "Mindestfrequenz des CPU-Reglers", "CPU Governor Minimum Frequency": "Mindestfrequenz des CPU-Reglers",
" Usage of unsafe display": "Verwendung unsicherer Bildschirmfrequenzen",
"refresh rates may cause stress": "Bildwiederholraten können Stress verursachen", "refresh rates may cause stress": "Bildwiederholraten können Stress verursachen",
"or damage to your display! ": "oder Schäden an Ihrem Display!", "or damage to your display! ": "oder Schäden an Ihrem Display!",
"Proceed at your own risk!": "Das Vorgehen erfolgt auf eigene Gefahr!", "Proceed at your own risk!": "Das Vorgehen erfolgt auf eigene Gefahr!",
"Max Handheld Display": "Max Handheld-Display", "Max Handheld Display": "Max Handheld-Display",
"Max Handheld Display Hz": "Max. Handheld-Hz",
"Display Clock": "Uhr anzeigen", "Display Clock": "Uhr anzeigen",
" Adjust the display voltage": "Display-Spannung anpassen",
"with caution to avoid damage": "mit Vorsicht, um Schäden zu vermeiden",
"to your display panel! ": "am Display-Panel!",
"Display Voltage": "Display-Spannung",
"Thermal Throttle Limit": "Thermische Drosselgrenze",
"Official Rating": "Offizielle Bewertung", "Official Rating": "Offizielle Bewertung",
"TDP Threshold": "TDP-Schwellenwert", "TDP Threshold": "TDP-Schwellenwert",
"Power": "Macht", "Power": "Macht",
"Thermal Throttle Limit": "Thermische Drosselgrenze",
"HP Mode": "HP-Modus", "HP Mode": "HP-Modus",
"Default (Mariko)": "Standard (Mariko)",
"Default (Erista)": "Standard (Erista)", "DVB Shift": "DVB-Versatz",
"Rating": "Bewertung", "SoC Max Volt": "SoC Max-Spannung",
"Safe Max (Mariko)": "Safe Max (Mariko)", "Step Mode": "Schritt-Modus",
"Safe Max (Erista)": "Safe Max (Erista)",
"RAM VDD2 Voltage": "RAM VDD2 Spannung", "RAM VDD2 Voltage": "RAM VDD2 Spannung",
"Voltage": "Spannung",
"RAM VDDQ Voltage": "RAM-VDDQ-Spannung", "RAM VDDQ Voltage": "RAM-VDDQ-Spannung",
"Voltage": "Spannung",
"RAM Frequency Editor": "RAM-Frequenzeditor", "RAM Frequency Editor": "RAM-Frequenzeditor",
"JEDEC.": "JEDEC.", "Ram Max Clock": "Ram Max Takt",
"High speedo needed!": "Hoher Tacho erforderlich!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (Benötigt extremen Tacho/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (Benötigt extremen Tacho/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (Benötigt extremen Tacho/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (Benötigt lächerlichen Tacho/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (Benötigt lächerlichen Tacho/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (Benötigt lächerlichen Tacho/PLL)",
"Ram Max Clock": "Ram Max Uhr",
"RAM Latency Editor": "RAM-Latenz-Editor", "RAM Latency Editor": "RAM-Latenz-Editor",
"RAM Timing Reductions": "Reduzierung des RAM-Timings", "RAM Timing Reductions": "Reduzierung des RAM-Timings",
"Memory Timings": "Speicherzeiten", "Memory Timings": "Speicherzeiten",
@@ -102,6 +115,15 @@
"Memory Latencies": "Speicherlatenzen", "Memory Latencies": "Speicherlatenzen",
"Read Latency": "Leselatenz", "Read Latency": "Leselatenz",
"Write Latency": "Schreiblatenz", "Write Latency": "Schreiblatenz",
"High speedo needed!": "Hoher Speedo-Wert erforderlich!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (Benötigt extremen Speedo/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (Benötigt extremen Speedo/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (Benötigt extremen Speedo/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (Benötigt lächerlichen Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (Benötigt lächerlichen Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (Benötigt lächerlichen Speedo/PLL)",
"JEDEC.": "JEDEC.",
"CPU Boost Clock": "CPU-Boost-Takt", "CPU Boost Clock": "CPU-Boost-Takt",
"CPU UV": "CPU-UV", "CPU UV": "CPU-UV",
"CPU Unlock": "CPU-Entsperrung", "CPU Unlock": "CPU-Entsperrung",
@@ -110,32 +132,84 @@
"CPU Max Clock": "Maximaler CPU-Takt", "CPU Max Clock": "Maximaler CPU-Takt",
"Extreme UV Table": "Extremer UV-Tisch", "Extreme UV Table": "Extremer UV-Tisch",
"CPU UV Table": "CPU-UV-Tisch", "CPU UV Table": "CPU-UV-Tisch",
"CPU Low UV": "CPU-niedrige UV-Strahlung", "CPU Low UV": "CPU niedrige UV",
"CPU High UV": "CPU Hohe UV-Strahlung", "CPU High UV": "CPU hohe UV",
"CPU Low VMIN": "CPU niedrig VMIN", "CPU Low VMIN": "CPU niedrig VMIN",
"CPU High VMIN": "CPU hoch VMIN", "CPU High VMIN": "CPU hoch VMIN",
"No Undervolt": "Kein Undervolt", "No Undervolt": "Kein Undervolt",
"SLT Table": "SLT-Tisch", "SLT Table": "SLT-Tabelle",
"HiOPT Table": "HiOPT-Tabelle", "HiOPT Table": "HiOPT-Tabelle",
"GPU Undervolt Table": "GPU-Unterspannungstabelle", "GPU Undervolt Table": "GPU-Unterspannungstabelle",
"GPU Minimum Voltage": "GPU-Mindestspannung", "GPU Minimum Voltage": "GPU-Mindestspannung",
"Calculate GPU Vmin": "Berechnen Sie die GPU-Vmin", "Calculate GPU Vmin": "GPU-Vmin berechnen",
"GPU VMIN": "GPU-VMIN", "GPU VMIN": "GPU-VMIN",
"GPU Maximum Voltage": "Maximale GPU-Spannung", "GPU Maximum Voltage": "Maximale GPU-Spannung",
"GPU Voltage Offset": "GPU-Spannungsoffset", "GPU Voltage Offset": "GPU-Spannungsoffset",
"Do not override": "Nicht überschreiben",
"Enabled (Default)": "Aktiviert (Standard)",
"96.6% limit": "96,6 %-Grenze",
"99.7% limit": "99,7 %-Grenze",
"GPU Scheduling Override": "GPU-Planungsüberschreibung",
"Official Service": "Offizieller Dienst",
"GPU DVFS Mode": "GPU-DVFS-Modus", "GPU DVFS Mode": "GPU-DVFS-Modus",
"GPU DVFS Offset": "GPU-DVFS-Offset", "GPU DVFS Offset": "GPU-DVFS-Offset",
"GPU Voltage Table": "GPU-Spannungstabelle", "GPU Voltage Table": "GPU-Spannungstabelle",
"GPU Custom Table (mV)": "Benutzerdefinierte GPU-Tabelle (mV)", "GPU Custom Table (mV)": "Benutzerdefinierte GPU-Tabelle (mV)",
"Official Service": "Offizieller Dienst",
"96.6% limit": "96,6 %-Grenze",
"99.7% limit": "99,7 %-Grenze",
" Setting GPU Clocks past": "GPU-Takt überschreiten",
"1228MHz without a proper undervolt": "1228 MHz ohne korrekten Undervolt",
"can cause degradation or damage": "kann Degradierung oder Schäden verursachen",
"to your console!": "an Ihrer Konsole!",
"1075MHz without UV, 1152MHz on SLT": "1075 MHz ohne UV, 1152 MHz auf SLT", "1075MHz without UV, 1152MHz on SLT": "1075 MHz ohne UV, 1152 MHz auf SLT",
"or 1228MHz on HiOPT can cause ": "oder 1228 MHz auf HiOPT kann dazu führen", "or 1228MHz on HiOPT can cause ": "oder 1228 MHz auf HiOPT kann dazu führen",
"permanent damage to your Switch!": "Dauerhafter Schaden an Ihrem Switch!", "permanent damage to your Switch!": "dauerhafter Schaden an Ihrem Switch!",
"921MHz without UV and 960MHz on": "921 MHz ohne UV und 960 MHz eingeschaltet", "921MHz without UV and 960MHz on": "921 MHz ohne UV und 960 MHz eingeschaltet",
"SLT or HiOPT can cause ": "SLT oder HiOPT können dazu führen" "SLT or HiOPT can cause ": "SLT oder HiOPT können dazu führen",
"Default (Mariko)": "Standard (Mariko)",
"Default (Erista)": "Standard (Erista)",
"Rating": "Bewertung",
"Safe Max (Mariko)": "Safe Max (Mariko)",
"Safe Max (Erista)": "Safe Max (Erista)",
"Voltages": "Spannungen",
"RAM Voltage:": "RAM-Spannung:",
"Display Voltage:": "Display-Spannung:",
"Temperatures": "Temperaturen",
"PLLX Temp:": "PLLX Temp:",
"AOTAG Temp:": "AOTAG Temp:",
"BQ24193 Temp:": "BQ24193 Temp:",
"Normal": "Normal",
"Warm": "Warm",
"Hot": "Heiß",
"Overheat": "Überhitzung",
"Not Patched": "Nicht gepatcht",
"Invalid": "Ungültig",
"RAM Bandwidth": "RAM-Bandbreite",
"RAM BW (Peak):": "RAM-BW (Max.):",
"RAM BW (All):": "RAM-BW (Ges.):",
"RAM BW (CPU):": "RAM-BW (CPU):",
"RAM BW (GPU):": "RAM-BW (GPU):",
"Hardware Info": "Hardware-Info",
"Console Type:": "Konsolentyp:",
"Speedo:": "Speedo:",
"DRAM Module: ": "DRAM-Modul: ",
"Software Info": "Software-Info",
"KIP version:": "KIP-Version:",
"sys-dock status:": "Sys-Dock-Status:",
"SaltyNX status:": "SaltyNX-Status:",
"RR Display status:": "RR Anzeigestatus:",
"Wafer Position:": "Waferposition:",
"IDDQ:": "IDDQ:",
"Module: ": "Modul:",
"Board": "Vorstand",
"Display": "Anzeige",
"Developers": "Entwickler",
"Contributors": "Mitwirkende",
"Testers": "Tester",
"Translators": "Übersetzer",
"Special Thanks": "Besonderer Dank",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%u mV",
"Compiling with minimal features": "Kompilieren mit minimalen Funktionen",
"THE BEER-WARE LICENSE": "DIE BIERWAREN-LIZENZ"
} }

View File

@@ -1,37 +1,33 @@
{ {
"Information": "Información", "Information": "Información",
"IDDQ:": "IDDQ:",
"Module: ": "Módulo:",
"sys-dock status:": "Estado de sys-dock:",
"SaltyNX status:": "Estado de SaltyNX:",
"RR Display status:": "Estado de pantalla RR:",
"Wafer Position:": "Posición del wafer:",
"Credits": "Créditos",
"Developers": "Desarrolladores",
"Contributors": "Colaboradores",
"Testers": "Testers",
"Special Thanks": "Agradecimientos especiales",
"Unknown": "Desconocido", "Unknown": "Desconocido",
"Installed": "Instalado", "Installed": "Instalado",
"Not Installed": "No instalado", "Not Installed": "No instalado",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "LICENCIA BEER-WARE",
"Default": "Predeterminado", "Default": "Predeterminado",
"Do Not Override": "No sobrescribir", "Do Not Override": "No sobrescribir",
"Do not override": "No sobrescribir",
"Disabled": "Desactivado", "Disabled": "Desactivado",
"Enabled": "Activado", "Enabled": "Activado",
" \\ue0e3 Reset": "\\ue0e3 Restablecer", "Enabled (Default)": "Activado (predeterminado)",
"Display": "Pantalla", "Enable": "Activar",
"Application changed\\n\\n": "Aplicación cambiada\\n\\n", "Fatal error": "Error fatal",
"The running application changed\\n\\n": "La aplicación en ejecución ha cambiado\\n\\n",
"while editing was going on.": "mientras se estaba editando.",
"Board": "Placa",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "No se pudo conectar al sysmodule hoc-clk.\\n\\n", "Could not connect to hoc-clk sysmodule.\\n\\n": "No se pudo conectar al sysmodule hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Asegúrate de que todo esté\\n\\n", "Please make sure everything is\\n\\n": "Asegúrate de que todo esté\\n\\n",
"correctly installed and enabled.": "correctamente instalado y activado.", "correctly installed and enabled.": "correctamente instalado y activado.",
"Fatal error": "Error fatal",
"Edit App Profile": "Editar perfil de aplicación",
"Edit Global Profile": "Editar perfil global",
"Temporary Overrides": "Ajustes temporales",
"Temporary Overrides ": "Ajustes temporales", "Temporary Overrides ": "Ajustes temporales",
"  Reset": " Restablecer",
"Settings": "Configuración",
"About": "Acerca de",
"Credits": "Créditos",
"Application changed\\n\\n": "Aplicación cambiada\\n\\n",
"The running application changed\\n\\n": "La aplicación en ejecución ha cambiado\\n\\n",
"while editing was going on.": "mientras se estaba editando.",
"Sleep Mode": "Modo reposo", "Sleep Mode": "Modo reposo",
"Stock": "Valores de fábrica", "Stock": "Valores de fábrica",
"Dev OC": "OC de desarrollo", "Dev OC": "OC de desarrollo",
@@ -40,13 +36,7 @@
"Unsafe Max": "Máximo no seguro", "Unsafe Max": "Máximo no seguro",
"Absolute Max": "Máximo absoluto", "Absolute Max": "Máximo absoluto",
"Handheld Safe Max": "Máximo seguro en portátil", "Handheld Safe Max": "Máximo seguro en portátil",
"Enable": "Activar",
"Edit App Profile": "Editar perfil de aplicación",
"Edit Global Profile": "Editar perfil global",
"Temporary Overrides": "Ajustes temporales",
"Settings": "Configuración",
"About": "Acerca de",
"Compiling with minimal features": "Compilado con funciones mínimas",
"General Settings": "Configuración general", "General Settings": "Configuración general",
"Governor Settings": "Configuración del governor", "Governor Settings": "Configuración del governor",
"Safety Settings": "Configuración de seguridad", "Safety Settings": "Configuración de seguridad",
@@ -55,41 +45,64 @@
"CPU Settings": "Configuración de CPU", "CPU Settings": "Configuración de CPU",
"GPU Settings": "Configuración de GPU", "GPU Settings": "Configuración de GPU",
"Display Settings": "Configuración de pantalla", "Display Settings": "Configuración de pantalla",
"Experimental Settings": "Configuración experimental",
"Experimental": "Experimental", "Experimental": "Experimental",
" Settings marked in blue": "La configuración en azul",
"don't require a reboot to apply!": "no requiere reinicio para aplicarse.",
"You can also press  to show": "Pulsa  para mostrar",
"information about each setting.": "información sobre cada ajuste.",
" Experimental Settings are incomplete ": "La configuración experimental está incompleta",
"and may not work correctly or at all!": "y puede que no funcione correctamente.",
"Here be dragons!": "¡Aquí hay dragones!",
"RAM Voltage Display Mode": "Modo de visualización de voltaje de RAM",
"RAM Display Unit": "Unidad de visualización RAM",
"Polling Interval": "Intervalo de sondeo",
"GPU Scheduling Override Method": "Método de sobrescritura del scheduling de GPU", "GPU Scheduling Override Method": "Método de sobrescritura del scheduling de GPU",
"GPU Scheduling Override": "Sobrescritura de scheduling de GPU",
"GPU Boot Volt": "Voltaje de arranque GPU",
"GPU Boot Voltage": "Voltaje de arranque GPU",
"Memory Frequency Measurement Mode": "Modo de medición de frecuencia de memoria",
" Overriding the charge current": "Sobrescribir la corriente de carga",
"can be dangerous and may cause": "puede ser peligroso y causar", "can be dangerous and may cause": "puede ser peligroso y causar",
"damage to your battery or charger!": "daños a la batería o al cargador.", "damage to your battery or charger!": "daños a la batería o al cargador.",
"Charge Current Override": "Sobrescritura de corriente de carga", "Charge Current Override": "Sobrescritura de corriente de carga",
"RAM Voltage Display Mode": "Modo de visualización de voltaje de RAM", "Display Color Preset": "Preajuste de color",
"Polling Interval": "Intervalo de sondeo", "Basic": "Básico",
"Saturated": "Saturado",
"Washed": "Lavado",
"Natural": "Natural",
"Vivid": "Vívido",
"CPU Governor Minimum Frequency": "Frecuencia mínima del governor de CPU", "CPU Governor Minimum Frequency": "Frecuencia mínima del governor de CPU",
" Usage of unsafe display": "El uso de frecuencias de pantalla",
"refresh rates may cause stress": "las tasas de refresco pueden causar estrés", "refresh rates may cause stress": "las tasas de refresco pueden causar estrés",
"or damage to your display! ": "o dañar la pantalla.", "or damage to your display! ": "o dañar la pantalla.",
"Proceed at your own risk!": "¡Úsalo bajo tu propio riesgo!", "Proceed at your own risk!": "¡Úsalo bajo tu propio riesgo!",
"Max Handheld Display": "Frecuencia máxima de pantalla en portátil", "Max Handheld Display": "Frecuencia máxima de pantalla en portátil",
"Max Handheld Display Hz": "Hz máximo en modo portátil",
"Display Clock": "Frecuencia de pantalla", "Display Clock": "Frecuencia de pantalla",
" Adjust the display voltage": "Ajusta el voltaje de pantalla",
"with caution to avoid damage": "con cuidado para evitar daños",
"to your display panel! ": "al panel de pantalla.",
"Display Voltage": "Voltaje de pantalla",
"Thermal Throttle Limit": "Límite de thermal throttling",
"Official Rating": "Valor oficial", "Official Rating": "Valor oficial",
"TDP Threshold": "Umbral de TDP", "TDP Threshold": "Umbral de TDP",
"Power": "Potencia", "Power": "Potencia",
"Thermal Throttle Limit": "Límite de thermal throttling",
"HP Mode": "Modo alto rendimiento", "HP Mode": "Modo alto rendimiento",
"Default (Mariko)": "Predeterminado (Mariko)",
"Default (Erista)": "Predeterminado (Erista)", "DVB Shift": "Desplazamiento DVB",
"Rating": "Valor", "SoC Max Volt": "Voltaje máximo del SoC",
"Safe Max (Mariko)": "Máximo seguro (Mariko)", "Step Mode": "Modo de paso",
"Safe Max (Erista)": "Máximo seguro (Erista)",
"RAM VDD2 Voltage": "Voltaje VDD2 de RAM", "RAM VDD2 Voltage": "Voltaje VDD2 de RAM",
"Voltage": "Voltaje",
"RAM VDDQ Voltage": "Voltaje VDDQ de RAM", "RAM VDDQ Voltage": "Voltaje VDDQ de RAM",
"Voltage": "Voltaje",
"RAM Frequency Editor": "Editor de frecuencia de RAM", "RAM Frequency Editor": "Editor de frecuencia de RAM",
"JEDEC.": "JEDEC",
"High speedo needed!": "¡Se necesita alto speedo!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (requiere Speedo/PLL extremo)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (requiere Speedo/PLL extremo)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (requiere Speedo/PLL extremo)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (requiere Speedo/PLL muy alto)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (requiere Speedo/PLL muy alto)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (requiere Speedo/PLL muy alto)",
"Ram Max Clock": "Frecuencia máxima de RAM", "Ram Max Clock": "Frecuencia máxima de RAM",
"RAM Latency Editor": "Editor de latencias de RAM", "RAM Latency Editor": "Editor de latencias de RAM",
"RAM Timing Reductions": "Reducción de timings de RAM", "RAM Timing Reductions": "Reducción de timings de RAM",
@@ -102,6 +115,15 @@
"Memory Latencies": "Latencias de memoria", "Memory Latencies": "Latencias de memoria",
"Read Latency": "Latencia de lectura", "Read Latency": "Latencia de lectura",
"Write Latency": "Latencia de escritura", "Write Latency": "Latencia de escritura",
"High speedo needed!": "¡Se necesita alto speedo!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (requiere Speedo/PLL extremo)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (requiere Speedo/PLL extremo)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (requiere Speedo/PLL extremo)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (requiere Speedo/PLL muy alto)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (requiere Speedo/PLL muy alto)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (requiere Speedo/PLL muy alto)",
"JEDEC.": "JEDEC",
"CPU Boost Clock": "Frecuencia boost de CPU", "CPU Boost Clock": "Frecuencia boost de CPU",
"CPU UV": "Undervolt de CPU", "CPU UV": "Undervolt de CPU",
"CPU Unlock": "Desbloqueo de CPU", "CPU Unlock": "Desbloqueo de CPU",
@@ -114,6 +136,7 @@
"CPU High UV": "Undervolt alto de CPU", "CPU High UV": "Undervolt alto de CPU",
"CPU Low VMIN": "VMIN bajo de CPU", "CPU Low VMIN": "VMIN bajo de CPU",
"CPU High VMIN": "VMIN alto de CPU", "CPU High VMIN": "VMIN alto de CPU",
"No Undervolt": "Sin undervolt", "No Undervolt": "Sin undervolt",
"SLT Table": "Tabla SLT", "SLT Table": "Tabla SLT",
"HiOPT Table": "Tabla HiOPT", "HiOPT Table": "Tabla HiOPT",
@@ -123,19 +146,70 @@
"GPU VMIN": "VMIN de GPU", "GPU VMIN": "VMIN de GPU",
"GPU Maximum Voltage": "Voltaje máximo de GPU", "GPU Maximum Voltage": "Voltaje máximo de GPU",
"GPU Voltage Offset": "Offset de voltaje de GPU", "GPU Voltage Offset": "Offset de voltaje de GPU",
"Do not override": "No sobrescribir",
"Enabled (Default)": "Activado (predeterminado)",
"96.6% limit": "Límite 96,6%",
"99.7% limit": "Límite 99,7%",
"GPU Scheduling Override": "Sobrescritura de scheduling de GPU",
"Official Service": "Servicio oficial",
"GPU DVFS Mode": "Modo DVFS de GPU", "GPU DVFS Mode": "Modo DVFS de GPU",
"GPU DVFS Offset": "Offset DVFS de GPU", "GPU DVFS Offset": "Offset DVFS de GPU",
"GPU Voltage Table": "Tabla de voltaje de GPU", "GPU Voltage Table": "Tabla de voltaje de GPU",
"GPU Custom Table (mV)": "Tabla personalizada de GPU (mV)", "GPU Custom Table (mV)": "Tabla personalizada de GPU (mV)",
"Official Service": "Servicio oficial",
"96.6% limit": "Límite 96,6%",
"99.7% limit": "Límite 99,7%",
" Setting GPU Clocks past": "Ajustar frecuencias de GPU más allá",
"1228MHz without a proper undervolt": "1228MHz sin undervolt adecuado",
"can cause degradation or damage": "puede causar degradación o daños",
"to your console!": "a tu consola.",
"1075MHz without UV, 1152MHz on SLT": "1075MHz sin undervolt, 1152MHz en SLT", "1075MHz without UV, 1152MHz on SLT": "1075MHz sin undervolt, 1152MHz en SLT",
"or 1228MHz on HiOPT can cause ": "o 1228MHz en HiOPT pueden causar ", "or 1228MHz on HiOPT can cause ": "o 1228MHz en HiOPT pueden causar ",
"permanent damage to your Switch!": "¡daño permanente a tu Switch!", "permanent damage to your Switch!": "¡daño permanente a tu Switch!",
"921MHz without UV and 960MHz on": "921MHz sin undervolt y 960MHz en", "921MHz without UV and 960MHz on": "921MHz sin undervolt y 960MHz en",
"SLT or HiOPT can cause ": "SLT o HiOPT pueden causar " "SLT or HiOPT can cause ": "SLT o HiOPT pueden causar ",
}
"Default (Mariko)": "Predeterminado (Mariko)",
"Default (Erista)": "Predeterminado (Erista)",
"Rating": "Valor",
"Safe Max (Mariko)": "Máximo seguro (Mariko)",
"Safe Max (Erista)": "Máximo seguro (Erista)",
"Voltages": "Voltajes",
"RAM Voltage:": "Voltaje RAM:",
"Display Voltage:": "Voltaje de pantalla:",
"Temperatures": "Temperaturas",
"PLLX Temp:": "PLLX Temp:",
"AOTAG Temp:": "AOTAG Temp:",
"BQ24193 Temp:": "BQ24193 Temp:",
"Normal": "Normal",
"Warm": "Cálido",
"Hot": "Caliente",
"Overheat": "Sobrecalentamiento",
"Not Patched": "Sin parche",
"Invalid": "Inválido",
"RAM Bandwidth": "Ancho de banda RAM",
"RAM BW (Peak):": "BW RAM (Pico):",
"RAM BW (All):": "BW RAM (Todo):",
"RAM BW (CPU):": "BW RAM (CPU):",
"RAM BW (GPU):": "BW RAM (GPU):",
"Hardware Info": "Info de hardware",
"Console Type:": "Tipo de consola:",
"Speedo:": "Speedo:",
"DRAM Module: ": "Módulo DRAM: ",
"Software Info": "Info de software",
"KIP version:": "Versión KIP:",
"sys-dock status:": "Estado de sys-dock:",
"SaltyNX status:": "Estado de SaltyNX:",
"RR Display status:": "Estado de pantalla RR:",
"Wafer Position:": "Posición del wafer:",
"IDDQ:": "IDDQ:",
"Module: ": "Módulo:",
"Board": "Placa",
"Display": "Pantalla",
"Developers": "Desarrolladores",
"Contributors": "Colaboradores",
"Testers": "Testers",
"Translators": "Traductores",
"Special Thanks": "Agradecimientos especiales",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%u mV",
"Compiling with minimal features": "Compilado con funciones mínimas",
"THE BEER-WARE LICENSE": "LICENCIA BEER-WARE"
}

View File

@@ -1,141 +1,215 @@
{ {
"Information": "Informations", "Information": "Informations",
"IDDQ:": "IDDQ :",
"Module: ": "Module :",
"sys-dock status:": "état du dock système :",
"SaltyNX status:": "Statut SaltyNX :",
"RR Display status:": "Etat d'affichage RR :",
"Wafer Position:": "Position de la plaquette :",
"Credits": "Crédits",
"Developers": "Développeurs",
"Contributors": "Contributeurs",
"Testers": "Testeurs",
"Special Thanks": "Remerciements spéciaux",
"Unknown": "Inconnu", "Unknown": "Inconnu",
"Installed": "Installé", "Installed": "Installé",
"Not Installed": "Non installé", "Not Installed": "Non installé",
"X: %u Y: %u": "X : %u Y : %u",
"THE BEER-WARE LICENSE": "LA LICENCE DE LA BIÈRE",
"Default": "Par défaut", "Default": "Par défaut",
"Do Not Override": "Ne pas remplacer", "Do Not Override": "Ne pas remplacer",
"Do not override": "Ne pas remplacer",
"Disabled": "Désactivé", "Disabled": "Désactivé",
"Enabled": "Activé", "Enabled": "Activé",
" \\ue0e3 Reset": "\\ue0e3 Réinitialiser", "Enabled (Default)": "Activé (par défaut)",
"Display": "Affichage", "Enable": "Activer",
"Application changed\\n\\n": "Application modifiée\\n\\n", "Fatal error": "Erreur fatale",
"The running application changed\\n\\n": "L'application en cours d'exécution a changé\\n\\n", "Could not connect to hoc-clk sysmodule.\\n\\n": "Impossible de se connecter au sysmodule hoc-clk.\\n\\n",
"while editing was going on.": "pendant le montage.",
"Board": "Conseil",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Impossible de se connecter au module système hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Veuillez vous assurer que tout est\\n\\n", "Please make sure everything is\\n\\n": "Veuillez vous assurer que tout est\\n\\n",
"correctly installed and enabled.": "correctement installé et activé.", "correctly installed and enabled.": "correctement installé et activé.",
"Fatal error": "Erreur fatale",
"Temporary Overrides ": "Remplacements temporaires", "Edit App Profile": "Modifier le profil de l'app",
"Sleep Mode": "Mode veille",
"Stock": "Actions",
"Dev OC": "Développeur OC",
"Boost Mode": "Mode Boost",
"Safe Max": "Coffre-fort maximum",
"Unsafe Max": "Dangereux Max",
"Absolute Max": "Max absolu",
"Handheld Safe Max": "Coffre-fort portatif Max",
"Enable": "Activer",
"Edit App Profile": "Modifier le profil de l'application",
"Edit Global Profile": "Modifier le profil global", "Edit Global Profile": "Modifier le profil global",
"Temporary Overrides": "Remplacements temporaires", "Temporary Overrides": "Forçages temporaires",
"Temporary Overrides ": "Forçages temporaires ",
"  Reset": " Réinitialiser",
"Settings": "Paramètres", "Settings": "Paramètres",
"About": "À propos", "About": "À propos",
"Compiling with minimal features": "Compilation avec des fonctionnalités minimales", "Credits": "Crédits",
"Application changed\\n\\n": "Application modifiée\\n\\n",
"The running application changed\\n\\n": "L'application en cours d'exécution a changé\\n\\n",
"while editing was going on.": "pendant la modification.",
"Sleep Mode": "Mode veille",
"Stock": "D'origine",
"Dev OC": "OC Développeur",
"Boost Mode": "Mode Boost",
"Safe Max": "Max sûr",
"Unsafe Max": "Max non sûr",
"Absolute Max": "Max absolu",
"Handheld Safe Max": "Max sûr (mode portable)",
"General Settings": "Paramètres généraux", "General Settings": "Paramètres généraux",
"Governor Settings": "Paramètres du gouverneur", "Governor Settings": "Paramètres du gouverneur",
"Safety Settings": "Paramètres de sécurité", "Safety Settings": "Paramètres de sécurité",
"Save KIP Settings": "Enregistrer les paramètres KIP", "Save KIP Settings": "Enregistrer les paramètres KIP",
"RAM Settings": "Paramètres de la RAM", "RAM Settings": "Paramètres RAM",
"CPU Settings": "Paramètres du processeur", "CPU Settings": "Paramètres CPU",
"GPU Settings": "Paramètres du processeur graphique", "GPU Settings": "Paramètres GPU",
"Display Settings": "Paramètres d'affichage", "Display Settings": "Paramètres d'affichage",
"Experimental Settings": "Paramètres expérimentaux",
"Experimental": "Expérimental", "Experimental": "Expérimental",
"GPU Scheduling Override Method": "Méthode de remplacement de la planification GPU",
"can be dangerous and may cause": "peut être dangereux et provoquer", " Settings marked in blue": "Les paramètres en bleu",
"damage to your battery or charger!": "dommages à votre batterie ou à votre chargeur !", "don't require a reboot to apply!": "ne nécessitent pas de redémarrage !",
"Charge Current Override": "Remplacement du courant de charge", "You can also press  to show": "Appuyez aussi sur  pour afficher",
"RAM Voltage Display Mode": "Mode d'affichage de la tension de la RAM", "information about each setting.": "les informations sur chaque paramètre.",
" Experimental Settings are incomplete ": "Les paramètres expérimentaux sont incomplets",
"and may not work correctly or at all!": "et peuvent ne pas fonctionner du tout !",
"Here be dragons!": "Ici, il y a des dragons !",
"RAM Voltage Display Mode": "Mode d'affichage de la tension RAM",
"RAM Display Unit": "Unité d'affichage RAM",
"Polling Interval": "Intervalle d'interrogation", "Polling Interval": "Intervalle d'interrogation",
"CPU Governor Minimum Frequency": "Fréquence minimale du gouverneur du processeur",
"refresh rates may cause stress": "les taux de rafraîchissement peuvent causer du stress", "GPU Scheduling Override Method": "Méthode de Forçage de l'ordonnancement GPU",
"or damage to your display! ": "ou endommager votre écran !", "GPU Scheduling Override": "Forçage de l'ordonnancement GPU",
"Proceed at your own risk!": "Procédez à vos propres risques !", "GPU Boot Volt": "Tension d'amorçage GPU",
"Max Handheld Display": "Affichage portable maximum", "GPU Boot Voltage": "Tension d'amorçage GPU",
"Display Clock": "Affichage de l'horloge", "Memory Frequency Measurement Mode": "Mode de mesure de fréquence mémoire",
" Overriding the charge current": "Le forçage du courant de charge",
"can be dangerous and may cause": "peut être dangereux et causer des",
"damage to your battery or charger!": "dommages à votre batterie ou chargeur !",
"Charge Current Override": "Forçage du courant de charge",
"Display Color Preset": "Préréglage de couleur",
"Basic": "Basique",
"Saturated": "Saturé",
"Washed": "Délavé",
"Natural": "Naturel",
"Vivid": "Vif",
"CPU Governor Minimum Frequency": "Fréquence minimale du gouverneur CPU",
" Usage of unsafe display": "L'utilisation de taux de rafraîchissement",
"refresh rates may cause stress": "les taux de rafraîchissement peuvent stresser",
"or damage to your display! ": "ou endommager votre écran !",
"Proceed at your own risk!": "À utiliser à vos propres risques !",
"Max Handheld Display": "Affichage portable max",
"Max Handheld Display Hz": "Hz max en mode portable",
"Display Clock": "Fréquence d'affichage",
" Adjust the display voltage": "Réglez la tension d'affichage",
"with caution to avoid damage": "avec précaution pour éviter des dommages",
"to your display panel! ": "à votre dalle d'affichage !",
"Display Voltage": "Tension d'affichage",
"Thermal Throttle Limit": "Limite d'étranglement thermique",
"Official Rating": "Classement officiel", "Official Rating": "Classement officiel",
"TDP Threshold": "Seuil TDP", "TDP Threshold": "Seuil TDP",
"Power": "Puissance", "Power": "Alimentation",
"Thermal Throttle Limit": "Limite d'accélérateur thermique",
"HP Mode": "Mode HP", "HP Mode": "Mode HP",
"Default (Mariko)": "Par défaut (Mariko)",
"Default (Erista)": "Par défaut (Erista)", "DVB Shift": "Décalage DVB",
"Rating": "Note", "SoC Max Volt": "Tension max SoC",
"Safe Max (Mariko)": "Coffre-fort Max (Mariko)", "Step Mode": "Mode pas à pas",
"Safe Max (Erista)": "Coffre-fort Max (Erista)", "RAM VDD2 Voltage": "Tension RAM VDD2",
"RAM VDD2 Voltage": "Tension de la RAM VDD2", "RAM VDDQ Voltage": "Tension RAM VDDQ",
"Voltage": "Tension", "Voltage": "Tension",
"RAM VDDQ Voltage": "Tension VDDQ de la RAM",
"RAM Frequency Editor": "Éditeur de fréquence RAM", "RAM Frequency Editor": "Éditeur de fréquence RAM",
"JEDEC.": "JEDEC.", "Ram Max Clock": "Fréquence RAM max",
"High speedo needed!": "Besoin d'un speedo haut !",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (nécessite un Speedo/PLL extrême)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (nécessite un Speedo/PLL extrême)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (nécessite un Speedo/PLL extrême)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (nécessite un Speedo/PLL ridicule)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (nécessite un Speedo/PLL ridicule)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (nécessite un Speedo/PLL ridicule)",
"Ram Max Clock": "Ram Max Horloge",
"RAM Latency Editor": "Éditeur de latence RAM", "RAM Latency Editor": "Éditeur de latence RAM",
"RAM Timing Reductions": "Réductions de synchronisation de la RAM", "RAM Timing Reductions": "Réductions des timings RAM",
"Memory Timings": "Horaires de mémoire", "Memory Timings": "Timings mémoire",
"Advanced": "Avancé", "Advanced": "Avancé",
"t6 tRTW Fine Tune": "t6 tRTW réglage fin", "t6 tRTW Fine Tune": "Ajustement précis t6 tRTW",
"tRTW Fine Tune": "tRTW Réglage fin", "tRTW Fine Tune": "Ajustement précis tRTW",
"t7 tWTR Fine Tune": "t7 tWTR réglage fin", "t7 tWTR Fine Tune": "Ajustement précis t7 tWTR",
"tWTR Fine Tune": "Réglage fin du tWTR", "tWTR Fine Tune": "Ajustement précis tWTR",
"Memory Latencies": "Latences de mémoire", "Memory Latencies": "Latences mémoire",
"Read Latency": "Latence de lecture", "Read Latency": "Latence de lecture",
"Write Latency": "Latence d'écriture", "Write Latency": "Latence d'écriture",
"CPU Boost Clock": "Horloge d'augmentation du processeur", "High speedo needed!": "Speedo élevé requis !",
"CPU UV": "UV du processeur", "3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (nécessite Speedo/PLL extrême)",
"CPU Unlock": "Déverrouillage du processeur", "3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (nécessite Speedo/PLL extrême)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (nécessite Speedo/PLL extrême)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (nécessite Speedo/PLL ridicule)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (nécessite Speedo/PLL ridicule)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (nécessite Speedo/PLL ridicule)",
"JEDEC.": "JEDEC.",
"CPU Boost Clock": "Fréquence Boost CPU",
"CPU UV": "UV CPU",
"CPU Unlock": "Déverrouillage CPU",
"CPU VMIN": "CPU VMIN", "CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "Tension maximale du processeur", "CPU Max Voltage": "Tension CPU max",
"CPU Max Clock": "Horloge maximale du processeur", "CPU Max Clock": "Fréquence CPU max",
"Extreme UV Table": "Table UV Extrême", "Extreme UV Table": "Table d'UV extrême",
"CPU UV Table": "Tableau UV du processeur", "CPU UV Table": "Table d'UV CPU",
"CPU Low UV": "CPU faible UV", "CPU Low UV": "UV CPU faible",
"CPU High UV": "CPU UV élevé", "CPU High UV": "UV CPU élevé",
"CPU Low VMIN": "CPU faible VMIN", "CPU Low VMIN": "VMIN CPU faible",
"CPU High VMIN": "Processeur VMIN élevé", "CPU High VMIN": "VMIN CPU élevé",
"No Undervolt": "Pas de sous-tension",
"SLT Table": "Tableau SLT", "No Undervolt": "Aucun Undervolt",
"HiOPT Table": "Tableau HiOPT", "SLT Table": "Table SLT",
"GPU Undervolt Table": "Tableau de sous-tension GPU", "HiOPT Table": "Table HiOPT",
"GPU Minimum Voltage": "Tension minimale du GPU", "GPU Undervolt Table": "Table d'undervolt GPU",
"Calculate GPU Vmin": "Calculer la Vmin du GPU", "GPU Minimum Voltage": "Tension GPU minimale",
"Calculate GPU Vmin": "Calculer Vmin GPU",
"GPU VMIN": "GPU VMIN", "GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "Tension maximale du GPU", "GPU Maximum Voltage": "Tension GPU maximale",
"GPU Voltage Offset": "Décalage de tension du GPU", "GPU Voltage Offset": "Offset de tension GPU",
"Do not override": "Ne remplacez pas",
"Enabled (Default)": "Activé (par défaut)",
"96.6% limit": "Limite de 96,6 %",
"99.7% limit": "Limite de 99,7 %",
"GPU Scheduling Override": "Remplacement de la planification GPU",
"Official Service": "Service officiel",
"GPU DVFS Mode": "Mode GPU DVFS", "GPU DVFS Mode": "Mode GPU DVFS",
"GPU DVFS Offset": "Décalage GPU DVFS", "GPU DVFS Offset": "Offset GPU DVFS",
"GPU Voltage Table": "Tableau de tension du GPU", "GPU Voltage Table": "Table de tension GPU",
"GPU Custom Table (mV)": "Tableau personnalisé GPU (mV)", "GPU Custom Table (mV)": "Table de GPU personnalisée (mV)",
"Official Service": "Service officiel",
"96.6% limit": "Limite de 96,6 %",
"99.7% limit": "Limite de 99,7 %",
" Setting GPU Clocks past": "Régler les fréquences GPU au-delà",
"1228MHz without a proper undervolt": "1228 MHz sans undervolt approprié",
"can cause degradation or damage": "peut causer une dégradation ou des dommages",
"to your console!": "à votre console !",
"1075MHz without UV, 1152MHz on SLT": "1075 MHz sans UV, 1152 MHz sur SLT", "1075MHz without UV, 1152MHz on SLT": "1075 MHz sans UV, 1152 MHz sur SLT",
"or 1228MHz on HiOPT can cause ": "ou 1228 MHz sur HiOPT peut provoquer", "or 1228MHz on HiOPT can cause ": "ou 1228 MHz sur HiOPT peut causer des",
"permanent damage to your Switch!": "dommages permanents à votre Switch !", "permanent damage to your Switch!": "dommages permanents à votre Switch !",
"921MHz without UV and 960MHz on": "921 MHz sans UV et 960 MHz activé", "921MHz without UV and 960MHz on": "921 MHz sans UV et 960 MHz sur",
"SLT or HiOPT can cause ": "SLT ou HiOPT peuvent provoquer" "SLT or HiOPT can cause ": "SLT ou HiOPT peuvent causer des",
"Default (Mariko)": "Par défaut (Mariko)",
"Default (Erista)": "Par défaut (Erista)",
"Rating": "Évaluation",
"Safe Max (Mariko)": "Max sûr (Mariko)",
"Safe Max (Erista)": "Max sûr (Erista)",
"Voltages": "Tensions",
"RAM Voltage:": "Tension RAM :",
"Display Voltage:": "Tension d'affichage :",
"Temperatures": "Températures",
"PLLX Temp:": "PLLX Temp :",
"AOTAG Temp:": "AOTAG Temp :",
"BQ24193 Temp:": "BQ24193 Temp :",
"Normal": "Normal",
"Warm": "Chaud",
"Hot": "Très chaud",
"Overheat": "Surchauffe",
"Not Patched": "Non patché",
"Invalid": "Invalide",
"RAM Bandwidth": "Bande passante RAM",
"RAM BW (Peak):": "BW RAM (Pic) :",
"RAM BW (All):": "BW RAM (Tout) :",
"RAM BW (CPU):": "BW RAM (CPU) :",
"RAM BW (GPU):": "BW RAM (GPU) :",
"Hardware Info": "Infos matériel",
"Console Type:": "Type de console :",
"Speedo:": "Speedo :",
"DRAM Module: ": "Module DRAM : ",
"Software Info": "Infos logiciel",
"KIP version:": "Version KIP :",
"sys-dock status:": "Statut de sys-dock :",
"SaltyNX status:": "Statut de SaltyNX :",
"RR Display status:": "Statut de l'affichage RR :",
"Wafer Position:": "Position du wafer :",
"IDDQ:": "IDDQ :",
"Module: ": "Module :",
"Board": "Carte",
"Display": "Écran",
"Developers": "Développeurs",
"Contributors": "Contributeurs",
"Testers": "Testeurs",
"Translators": "Traducteurs",
"Special Thanks": "Remerciements spéciaux",
"X: %u Y: %u": "X : %u Y : %u",
"%u.%u%u mV": "%u.%u%u mV",
"Compiling with minimal features": "Compilation avec fonctionnalités minimales",
"THE BEER-WARE LICENSE": "LA LICENCE BEER-WARE"
} }

View File

@@ -1,37 +1,33 @@
{ {
"Information": "Informazioni", "Information": "Informazioni",
"IDDQ:": "IDDQ:",
"Module: ": "Modulo:",
"sys-dock status:": "stato di sys-dock",
"SaltyNX status:": "Stato di SaltyNX:",
"RR Display status:": "Stato del RR:",
"Wafer Position:": "Posizione nel Wafer:",
"Credits": "Crediti",
"Developers": "Sviluppatori",
"Contributors": "Collaboratori",
"Testers": "Tester",
"Special Thanks": "Un Ringraziamento Speciale",
"Unknown": "Sconosciuto", "Unknown": "Sconosciuto",
"Installed": "Installato", "Installed": "Installato",
"Not Installed": "Non installato", "Not Installed": "Non installato",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "THE BEER-WARE LICENSE",
"Default": "Predefinito", "Default": "Predefinito",
"Do Not Override": "Non Sovrascrivere", "Do Not Override": "Non Sovrascrivere",
"Do not override": "Non sovrascrivere",
"Disabled": "Disabilitato", "Disabled": "Disabilitato",
"Enabled": "Abilitato", "Enabled": "Abilitato",
" \\ue0e3 Reset": "\\ue0e3 Ripristina", "Enabled (Default)": "Abilitato (impostazione predefinita)",
"Display": "Schermo", "Enable": "Abilita",
"Application changed\\n\\n": "Applicazione modificata\\n\\n", "Fatal error": "Errore fatale",
"The running application changed\\n\\n": "L'applicazione in esecuzione è cambiata\\n\\n",
"while editing was going on.": "mentre era in corso la modifica.",
"Board": "Scheda",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Impossibile connettersi al sysmodule hoc-clk.\\n\\n", "Could not connect to hoc-clk sysmodule.\\n\\n": "Impossibile connettersi al sysmodule hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Assicurati che tutto sia\\n\\n", "Please make sure everything is\\n\\n": "Assicurati che tutto sia\\n\\n",
"correctly installed and enabled.": "correttamente installato e abilitato.", "correctly installed and enabled.": "correttamente installato e abilitato.",
"Fatal error": "Errore fatale",
"Edit App Profile": "Modifica Profilo Dell'App",
"Edit Global Profile": "Modifica Profilo Globale",
"Temporary Overrides": "Sostituzioni Temporanee",
"Temporary Overrides ": "Sostituzioni Temporanee", "Temporary Overrides ": "Sostituzioni Temporanee",
"  Reset": " Ripristina",
"Settings": "Impostazioni",
"About": "A Riguardo Di",
"Credits": "Crediti",
"Application changed\\n\\n": "Applicazione modificata\\n\\n",
"The running application changed\\n\\n": "L'applicazione in esecuzione è cambiata\\n\\n",
"while editing was going on.": "mentre era in corso la modifica.",
"Sleep Mode": "Modalità di Sospensione", "Sleep Mode": "Modalità di Sospensione",
"Stock": "Originale", "Stock": "Originale",
"Dev OC": "OC dev", "Dev OC": "OC dev",
@@ -40,13 +36,7 @@
"Unsafe Max": "Massimo Non Sicuro", "Unsafe Max": "Massimo Non Sicuro",
"Absolute Max": "Massimo Assoluto", "Absolute Max": "Massimo Assoluto",
"Handheld Safe Max": "Massimo Sicuro Modalità Portatile", "Handheld Safe Max": "Massimo Sicuro Modalità Portatile",
"Enable": "Abilita",
"Edit App Profile": "Modifica Profilo Dell'App",
"Edit Global Profile": "Modifica Profilo Globale",
"Temporary Overrides": "Sostituzioni Temporanee",
"Settings": "Impostazioni",
"About": "A Riguardo Di",
"Compiling with minimal features": "Compilazione con funzionalità minime",
"General Settings": "Impostazioni Generali", "General Settings": "Impostazioni Generali",
"Governor Settings": "Impostazioni Del Governor", "Governor Settings": "Impostazioni Del Governor",
"Safety Settings": "Impostazioni Di Sicurezza", "Safety Settings": "Impostazioni Di Sicurezza",
@@ -55,41 +45,64 @@
"CPU Settings": "Impostazioni della CPU", "CPU Settings": "Impostazioni della CPU",
"GPU Settings": "Impostazioni della GPU", "GPU Settings": "Impostazioni della GPU",
"Display Settings": "Impostazioni dello Schermo", "Display Settings": "Impostazioni dello Schermo",
"Experimental Settings": "Impostazioni sperimentali",
"Experimental": "Sperimentale", "Experimental": "Sperimentale",
" Settings marked in blue": "Le impostazioni in blu",
"don't require a reboot to apply!": "non richiedono un riavvio per applicarsi!",
"You can also press  to show": "Premi anche  per mostrare",
"information about each setting.": "informazioni su ogni impostazione.",
" Experimental Settings are incomplete ": "Le impostazioni sperimentali sono incomplete",
"and may not work correctly or at all!": "e potrebbero non funzionare correttamente!",
"Here be dragons!": "Qui ci sono draghi!",
"RAM Voltage Display Mode": "Modalità di Visualizzazione della Tensione RAM",
"RAM Display Unit": "Unità di visualizzazione RAM",
"Polling Interval": "Intervallo di polling",
"GPU Scheduling Override Method": "Metodo di override dello scheduling GPU", "GPU Scheduling Override Method": "Metodo di override dello scheduling GPU",
"GPU Scheduling Override": "Override dello Scheduling GPU",
"GPU Boot Volt": "Tensione di avvio GPU",
"GPU Boot Voltage": "Tensione di avvio GPU",
"Memory Frequency Measurement Mode": "Modalità di misurazione della frequenza della memoria",
" Overriding the charge current": "L'override della corrente di carica",
"can be dangerous and may cause": "può essere pericoloso e può causare", "can be dangerous and may cause": "può essere pericoloso e può causare",
"damage to your battery or charger!": "danni alla batteria o al caricabatterie!", "damage to your battery or charger!": "danni alla batteria o al caricabatterie!",
"Charge Current Override": "Override della Corrente di Carica", "Charge Current Override": "Override della Corrente di Carica",
"RAM Voltage Display Mode": "Modalità di Visualizzazione della Tensione RAM", "Display Color Preset": "Preimpostazione colore",
"Polling Interval": "Intervallo di polling", "Basic": "Base",
"Saturated": "Saturo",
"Washed": "Sbiadito",
"Natural": "Naturale",
"Vivid": "Vivace",
"CPU Governor Minimum Frequency": "Frequenza minima del Governor della CPU", "CPU Governor Minimum Frequency": "Frequenza minima del Governor della CPU",
" Usage of unsafe display": "L'uso di frequenze di aggiornamento",
"refresh rates may cause stress": "le frequenze di aggiornamento possono causare stress", "refresh rates may cause stress": "le frequenze di aggiornamento possono causare stress",
"or damage to your display! ": "o danni al display!", "or damage to your display! ": "o danni al display!",
"Proceed at your own risk!": "Procedi a tuo rischio e pericolo!", "Proceed at your own risk!": "Procedi a tuo rischio e pericolo!",
"Max Handheld Display": "Display Massimo in Modalità Portatile", "Max Handheld Display": "Display Massimo in Modalità Portatile",
"Max Handheld Display Hz": "Hz max in modalità portatile",
"Display Clock": "Frequenza del Display", "Display Clock": "Frequenza del Display",
" Adjust the display voltage": "Regola la tensione del display",
"with caution to avoid damage": "con cautela per evitare danni",
"to your display panel! ": "al pannello del display!",
"Display Voltage": "Tensione display",
"Thermal Throttle Limit": "Limite Termico",
"Official Rating": "Rating Ufficiale", "Official Rating": "Rating Ufficiale",
"TDP Threshold": "Soglia TDP", "TDP Threshold": "Soglia TDP",
"Power": "Potenza", "Power": "Potenza",
"Thermal Throttle Limit": "Limite Termico",
"HP Mode": "Modalità HP", "HP Mode": "Modalità HP",
"Default (Mariko)": "Predefinito (Mariko)",
"Default (Erista)": "Predefinito (Erista)", "DVB Shift": "Offset DVB",
"Rating": "Valutazione", "SoC Max Volt": "Tensione massima SoC",
"Safe Max (Mariko)": "Massimo Sicuro (Mariko)", "Step Mode": "Modalità passo",
"Safe Max (Erista)": "Massimo Sicuro (Erista)",
"RAM VDD2 Voltage": "Tensione RAM VDD2", "RAM VDD2 Voltage": "Tensione RAM VDD2",
"Voltage": "Voltaggio",
"RAM VDDQ Voltage": "Voltaggio VDDQ della RAM", "RAM VDDQ Voltage": "Voltaggio VDDQ della RAM",
"Voltage": "Voltaggio",
"RAM Frequency Editor": "Editor della frequenza RAM", "RAM Frequency Editor": "Editor della frequenza RAM",
"JEDEC.": "JEDEC.",
"High speedo needed!": "Alto Valore Speedo Necessario!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (richiede Speedo/PLL altissimo)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (richiede Speedo/PLL altissimo)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (richiede Speedo/PLL altissimo)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (richiede Speedo/PLL estremo)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (richiede Speedo/PLL estremo)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (richiede Speedo/PLL estremo)",
"Ram Max Clock": "Frequenza Massima Ram", "Ram Max Clock": "Frequenza Massima Ram",
"RAM Latency Editor": "Editor della Latenza RAM", "RAM Latency Editor": "Editor della Latenza RAM",
"RAM Timing Reductions": "Riduzioni dei Timing della RAM", "RAM Timing Reductions": "Riduzioni dei Timing della RAM",
@@ -102,6 +115,15 @@
"Memory Latencies": "Latenza della Memoria", "Memory Latencies": "Latenza della Memoria",
"Read Latency": "Latenza di Lettura", "Read Latency": "Latenza di Lettura",
"Write Latency": "Latenza di Scrittura", "Write Latency": "Latenza di Scrittura",
"High speedo needed!": "Alto Valore Speedo Necessario!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (richiede Speedo/PLL altissimo)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (richiede Speedo/PLL altissimo)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (richiede Speedo/PLL altissimo)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (richiede Speedo/PLL estremo)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (richiede Speedo/PLL estremo)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (richiede Speedo/PLL estremo)",
"JEDEC.": "JEDEC.",
"CPU Boost Clock": "Frequenza CPU in Boost", "CPU Boost Clock": "Frequenza CPU in Boost",
"CPU UV": "Undervolt CPU", "CPU UV": "Undervolt CPU",
"CPU Unlock": "Sblocco della CPU", "CPU Unlock": "Sblocco della CPU",
@@ -114,6 +136,7 @@
"CPU High UV": "CPU UV Alta Frequenza", "CPU High UV": "CPU UV Alta Frequenza",
"CPU Low VMIN": "CPU VMIN Bassa Frequenza", "CPU Low VMIN": "CPU VMIN Bassa Frequenza",
"CPU High VMIN": "CPU VMIN Alta Frequenza", "CPU High VMIN": "CPU VMIN Alta Frequenza",
"No Undervolt": "Nessun Undervolt", "No Undervolt": "Nessun Undervolt",
"SLT Table": "Tabella SLT", "SLT Table": "Tabella SLT",
"HiOPT Table": "Tabella HiOPT", "HiOPT Table": "Tabella HiOPT",
@@ -123,19 +146,70 @@
"GPU VMIN": "GPU VMIN", "GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "Voltaggio massimo della GPU", "GPU Maximum Voltage": "Voltaggio massimo della GPU",
"GPU Voltage Offset": "Offset di Voltaggio della GPU", "GPU Voltage Offset": "Offset di Voltaggio della GPU",
"Do not override": "Non sovrascrivere",
"Enabled (Default)": "Abilitato (impostazione predefinita)",
"96.6% limit": "Limite del 96,6%.",
"99.7% limit": "Limite del 99,7%.",
"GPU Scheduling Override": "Override dello Scheduling GPU",
"Official Service": "Servizio ufficiale",
"GPU DVFS Mode": "Modalità DVFS GPU", "GPU DVFS Mode": "Modalità DVFS GPU",
"GPU DVFS Offset": "Offset DVFS della GPU", "GPU DVFS Offset": "Offset DVFS della GPU",
"GPU Voltage Table": "Tabella delle Tensioni della GPU", "GPU Voltage Table": "Tabella delle Tensioni della GPU",
"GPU Custom Table (mV)": "Tabella GPU Personalizzata (mV)", "GPU Custom Table (mV)": "Tabella GPU Personalizzata (mV)",
"Official Service": "Servizio ufficiale",
"96.6% limit": "Limite del 96,6%",
"99.7% limit": "Limite del 99,7%",
" Setting GPU Clocks past": "Impostare le frequenze GPU oltre",
"1228MHz without a proper undervolt": "1228 MHz senza undervolt appropriato",
"can cause degradation or damage": "può causare degrado o danni",
"to your console!": "alla tua console!",
"1075MHz without UV, 1152MHz on SLT": "1075 MHz senza UV, 1152 MHz su SLT", "1075MHz without UV, 1152MHz on SLT": "1075 MHz senza UV, 1152 MHz su SLT",
"or 1228MHz on HiOPT can cause ": "o 1228 MHz su HiOPT possono causare", "or 1228MHz on HiOPT can cause ": "o 1228 MHz su HiOPT possono causare",
"permanent damage to your Switch!": "danni permanenti alla tua Switch!", "permanent damage to your Switch!": "danni permanenti alla tua Switch!",
"921MHz without UV and 960MHz on": "921 MHz senza UV e 960 MHz su", "921MHz without UV and 960MHz on": "921 MHz senza UV e 960 MHz su",
"SLT or HiOPT can cause ": "SLT o HiOPT possono causare" "SLT or HiOPT can cause ": "SLT o HiOPT possono causare",
"Default (Mariko)": "Predefinito (Mariko)",
"Default (Erista)": "Predefinito (Erista)",
"Rating": "Valutazione",
"Safe Max (Mariko)": "Massimo Sicuro (Mariko)",
"Safe Max (Erista)": "Massimo Sicuro (Erista)",
"Voltages": "Tensioni",
"RAM Voltage:": "Tensione RAM:",
"Display Voltage:": "Tensione display:",
"Temperatures": "Temperature",
"PLLX Temp:": "PLLX Temp:",
"AOTAG Temp:": "AOTAG Temp:",
"BQ24193 Temp:": "BQ24193 Temp:",
"Normal": "Normale",
"Warm": "Caldo",
"Hot": "Molto caldo",
"Overheat": "Surriscaldamento",
"Not Patched": "Non patchato",
"Invalid": "Non valido",
"RAM Bandwidth": "Banda RAM",
"RAM BW (Peak):": "BW RAM (Picco):",
"RAM BW (All):": "BW RAM (Tutto):",
"RAM BW (CPU):": "BW RAM (CPU):",
"RAM BW (GPU):": "BW RAM (GPU):",
"Hardware Info": "Info hardware",
"Console Type:": "Tipo di console:",
"Speedo:": "Speedo:",
"DRAM Module: ": "Modulo DRAM: ",
"Software Info": "Info software",
"KIP version:": "Versione KIP:",
"sys-dock status:": "stato di sys-dock",
"SaltyNX status:": "Stato di SaltyNX:",
"RR Display status:": "Stato del RR:",
"Wafer Position:": "Posizione nel Wafer:",
"IDDQ:": "IDDQ:",
"Module: ": "Modulo:",
"Board": "Scheda",
"Display": "Schermo",
"Developers": "Sviluppatori",
"Contributors": "Collaboratori",
"Testers": "Tester",
"Translators": "Traduttori",
"Special Thanks": "Un Ringraziamento Speciale",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%u mV",
"Compiling with minimal features": "Compilazione con funzionalità minime",
"THE BEER-WARE LICENSE": "THE BEER-WARE LICENSE"
} }

View File

@@ -1,52 +1,42 @@
{ {
"Information": "情報", "Information": "情報",
"IDDQ:": "IDQ:",
"Module: ": "モジュール:",
"sys-dock status:": "システムドックのステータス:",
"SaltyNX status:": "SaltyNX ステータス:",
"RR Display status:": "RR 表示ステータス:",
"Wafer Position:": "ウェーハの位置:",
"Credits": "クレジット",
"Developers": "開発者",
"Contributors": "貢献者",
"Testers": "テスター",
"Special Thanks": "特別な感謝の気持ち",
"Unknown": "不明", "Unknown": "不明",
"Installed": "インストール済み", "Installed": "インストール済み",
"Not Installed": "インストールされていません", "Not Installed": "インストールされていません",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "ビール製品ライセンス",
"Default": "デフォルト", "Default": "デフォルト",
"Do Not Override": "上書きしないでください", "Do Not Override": "上書きしないでください",
"Disabled": "障害者", "Do not override": "上書きしないでください",
"Disabled": "無効",
"Enabled": "有効", "Enabled": "有効",
" \\ue0e3 Reset": "\\ue0e3 リセット", "Enabled (Default)": "有効 (デフォルト)",
"Display": "ディスプレイ", "Enable": "有効にする",
"Application changed\\n\\n": "アプリケーションが変更されました\\n\\n", "Fatal error": "致命的なエラー",
"The running application changed\\n\\n": "実行中のアプリケーションが変更されました\\n\\n",
"while editing was going on.": "編集を進めている最中でした。",
"Board": "理事会",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "hoc-clk sysmodule に接続できませんでした。\\n\\n", "Could not connect to hoc-clk sysmodule.\\n\\n": "hoc-clk sysmodule に接続できませんでした。\\n\\n",
"Please make sure everything is\\n\\n": "すべてが正しいことを確認してください\\n\\n", "Please make sure everything is\\n\\n": "すべてが正しいことを確認してください\\n\\n",
"correctly installed and enabled.": "正しくインストールされ、有効になっています。", "correctly installed and enabled.": "正しくインストールされ、有効になっています。",
"Fatal error": "致命的なエラー",
"Edit App Profile": "アプリプロファイルの編集",
"Edit Global Profile": "グローバルプロファイルの編集",
"Temporary Overrides": "一時的なオーバーライド",
"Temporary Overrides ": "一時的なオーバーライド", "Temporary Overrides ": "一時的なオーバーライド",
"  Reset": " リセット",
"Settings": "設定",
"About": "について",
"Credits": "クレジット",
"Application changed\\n\\n": "アプリケーションが変更されました\\n\\n",
"The running application changed\\n\\n": "実行中のアプリケーションが変更されました\\n\\n",
"while editing was going on.": "編集を進めている最中でした。",
"Sleep Mode": "スリープモード", "Sleep Mode": "スリープモード",
"Stock": "在庫", "Stock": "標準",
"Dev OC": "開発OC", "Dev OC": "開発OC",
"Boost Mode": "ブーストモード", "Boost Mode": "ブーストモード",
"Safe Max": "セーフマックス", "Safe Max": "セーフマックス",
"Unsafe Max": "危険なマックス", "Unsafe Max": "危険なマックス",
"Absolute Max": "絶対最大値", "Absolute Max": "絶対最大値",
"Handheld Safe Max": "手持ち金庫マックス", "Handheld Safe Max": "手持ち安全マックス",
"Enable": "有効にする",
"Edit App Profile": "アプリプロファイルの編集",
"Edit Global Profile": "グローバルプロファイルの編集",
"Temporary Overrides": "一時的なオーバーライド",
"Settings": "設定",
"About": "について",
"Compiling with minimal features": "最小限の機能でコンパイルする",
"General Settings": "一般設定", "General Settings": "一般設定",
"Governor Settings": "ガバナーの設定", "Governor Settings": "ガバナーの設定",
"Safety Settings": "安全設定", "Safety Settings": "安全設定",
@@ -55,41 +45,64 @@
"CPU Settings": "CPUの設定", "CPU Settings": "CPUの設定",
"GPU Settings": "GPU設定", "GPU Settings": "GPU設定",
"Display Settings": "表示設定", "Display Settings": "表示設定",
"Experimental Settings": "実験的設定",
"Experimental": "実験的", "Experimental": "実験的",
" Settings marked in blue": "青色でマークされた設定",
"don't require a reboot to apply!": "再起動なしで適用できます!",
"You can also press  to show": " を押して表示することもできます",
"information about each setting.": "各設定の情報を。",
" Experimental Settings are incomplete ": "実験的設定は未完成です",
"and may not work correctly or at all!": "正しく動作しない場合があります!",
"Here be dragons!": "ここにドラゴンあり!",
"RAM Voltage Display Mode": "RAM電圧表示モード",
"RAM Display Unit": "RAM表示単位",
"Polling Interval": "ポーリング間隔",
"GPU Scheduling Override Method": "GPU スケジューリング オーバーライド メソッド", "GPU Scheduling Override Method": "GPU スケジューリング オーバーライド メソッド",
"GPU Scheduling Override": "GPU スケジュールのオーバーライド",
"GPU Boot Volt": "GPU起動電圧",
"GPU Boot Voltage": "GPU起動電圧",
"Memory Frequency Measurement Mode": "メモリ周波数測定モード",
" Overriding the charge current": "充電電流のオーバーライド",
"can be dangerous and may cause": "危険であり、原因となる可能性があります", "can be dangerous and may cause": "危険であり、原因となる可能性があります",
"damage to your battery or charger!": "バッテリーまたは充電器が損傷します。", "damage to your battery or charger!": "バッテリーまたは充電器が損傷します。",
"Charge Current Override": "充電電流オーバーライド", "Charge Current Override": "充電電流オーバーライド",
"RAM Voltage Display Mode": "RAM電圧表示モード", "Display Color Preset": "ディスプレイカラープリセット",
"Polling Interval": "ポーリング間隔", "Basic": "ベーシック",
"Saturated": "鮮やか",
"Washed": "色あせ",
"Natural": "ナチュラル",
"Vivid": "ビビッド",
"CPU Governor Minimum Frequency": "CPU ガバナの最小周波数", "CPU Governor Minimum Frequency": "CPU ガバナの最小周波数",
" Usage of unsafe display": "危険なリフレッシュレートの使用",
"refresh rates may cause stress": "リフレッシュレートがストレスを引き起こす可能性がある", "refresh rates may cause stress": "リフレッシュレートがストレスを引き起こす可能性がある",
"or damage to your display! ": "ディスプレイに損傷を与えてしまいます。", "or damage to your display! ": "ディスプレイに損傷を与えてしまいます。",
"Proceed at your own risk!": "自己責任で進めてください!", "Proceed at your own risk!": "自己責任で進めてください!",
"Max Handheld Display": "最大ハンドヘルドディスプレイ", "Max Handheld Display": "最大ハンドヘルドディスプレイ",
"Max Handheld Display Hz": "最大ハンドヘルドHz",
"Display Clock": "時計の表示", "Display Clock": "時計の表示",
" Adjust the display voltage": "ディスプレイ電圧を調整",
"with caution to avoid damage": "損傷を避けるため注意して",
"to your display panel! ": "ディスプレイパネルに!",
"Display Voltage": "ディスプレイ電圧",
"Thermal Throttle Limit": "サーマルスロットル制限",
"Official Rating": "公式評価", "Official Rating": "公式評価",
"TDP Threshold": "TDP しきい値", "TDP Threshold": "TDP しきい値",
"Power": "パワー", "Power": "パワー",
"Thermal Throttle Limit": "サーマルスロットル制限",
"HP Mode": "HPモード", "HP Mode": "HPモード",
"Default (Mariko)": "デフォルト(マリコ)",
"Default (Erista)": "デフォルト(エリスタ)", "DVB Shift": "DVBシフト",
"Rating": "評価", "SoC Max Volt": "SoC最大電圧",
"Safe Max (Mariko)": "セーフマックス(マリコ)", "Step Mode": "ステップモード",
"Safe Max (Erista)": "セーフマックス(エリスタ)",
"RAM VDD2 Voltage": "RAM VDD2 電圧", "RAM VDD2 Voltage": "RAM VDD2 電圧",
"Voltage": "電圧",
"RAM VDDQ Voltage": "RAM VDDQ 電圧", "RAM VDDQ Voltage": "RAM VDDQ 電圧",
"Voltage": "電圧",
"RAM Frequency Editor": "RAM周波数エディター", "RAM Frequency Editor": "RAM周波数エディター",
"JEDEC.": "JEDEC。",
"High speedo needed!": "ハイスピードが必要です!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (エクストリーム Speedo/PLL が必要)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (エクストリーム Speedo/PLL が必要)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (エクストリーム Speedo/PLL が必要)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (とんでもない Speedo/PLL が必要)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (とんでもない Speedo/PLL が必要)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (とんでもない Speedo/PLL が必要)",
"Ram Max Clock": "ラムマックスクロック", "Ram Max Clock": "ラムマックスクロック",
"RAM Latency Editor": "RAM レイテンシ エディター", "RAM Latency Editor": "RAM レイテンシ エディター",
"RAM Timing Reductions": "RAM タイミングの削減", "RAM Timing Reductions": "RAM タイミングの削減",
@@ -102,6 +115,15 @@
"Memory Latencies": "メモリレイテンシ", "Memory Latencies": "メモリレイテンシ",
"Read Latency": "読み取りレイテンシー", "Read Latency": "読み取りレイテンシー",
"Write Latency": "書き込みレイテンシ", "Write Latency": "書き込みレイテンシ",
"High speedo needed!": "ハイスピードが必要です!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (エクストリーム Speedo/PLL が必要)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (エクストリーム Speedo/PLL が必要)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (エクストリーム Speedo/PLL が必要)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (とんでもない Speedo/PLL が必要)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (とんでもない Speedo/PLL が必要)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (とんでもない Speedo/PLL が必要)",
"JEDEC.": "JEDEC。",
"CPU Boost Clock": "CPUブーストクロック", "CPU Boost Clock": "CPUブーストクロック",
"CPU UV": "CPU UV", "CPU UV": "CPU UV",
"CPU Unlock": "CPUロック解除", "CPU Unlock": "CPUロック解除",
@@ -111,10 +133,11 @@
"Extreme UV Table": "エクストリーム UV テーブル", "Extreme UV Table": "エクストリーム UV テーブル",
"CPU UV Table": "CPU UV テーブル", "CPU UV Table": "CPU UV テーブル",
"CPU Low UV": "CPU 低 UV", "CPU Low UV": "CPU 低 UV",
"CPU High UV": "CPU 高紫外線", "CPU High UV": "CPU 高 UV",
"CPU Low VMIN": "CPU 低 VMIN", "CPU Low VMIN": "CPU 低 VMIN",
"CPU High VMIN": "CPU の高い VMIN", "CPU High VMIN": "CPU VMIN",
"No Undervolt": "不足電圧なし",
"No Undervolt": "アンダーボルトなし",
"SLT Table": "SLTテーブル", "SLT Table": "SLTテーブル",
"HiOPT Table": "HiOPT テーブル", "HiOPT Table": "HiOPT テーブル",
"GPU Undervolt Table": "GPUアンダーボルトテーブル", "GPU Undervolt Table": "GPUアンダーボルトテーブル",
@@ -123,19 +146,70 @@
"GPU VMIN": "GPU VMIN", "GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "GPU最大電圧", "GPU Maximum Voltage": "GPU最大電圧",
"GPU Voltage Offset": "GPU電圧オフセット", "GPU Voltage Offset": "GPU電圧オフセット",
"Do not override": "上書きしないでください",
"Enabled (Default)": "有効 (デフォルト)",
"96.6% limit": "96.6%制限",
"99.7% limit": "99.7%制限",
"GPU Scheduling Override": "GPU スケジュールのオーバーライド",
"Official Service": "正式サービス",
"GPU DVFS Mode": "GPU DVFS モード", "GPU DVFS Mode": "GPU DVFS モード",
"GPU DVFS Offset": "GPU DVFS オフセット", "GPU DVFS Offset": "GPU DVFS オフセット",
"GPU Voltage Table": "GPU電圧テーブル", "GPU Voltage Table": "GPU電圧テーブル",
"GPU Custom Table (mV)": "GPUカスタムテーブル(mV)", "GPU Custom Table (mV)": "GPUカスタムテーブル(mV)",
"Official Service": "正式サービス",
"96.6% limit": "96.6%制限",
"99.7% limit": "99.7%制限",
" Setting GPU Clocks past": "GPUクロックを超えて設定",
"1228MHz without a proper undervolt": "適切なアンダーボルトなしで1228MHz",
"can cause degradation or damage": "劣化や損傷を引き起こす可能性があります",
"to your console!": "あなたのコンソールに!",
"1075MHz without UV, 1152MHz on SLT": "UVなしで1075MHz、SLTで1152MHz", "1075MHz without UV, 1152MHz on SLT": "UVなしで1075MHz、SLTで1152MHz",
"or 1228MHz on HiOPT can cause ": "HiOPT で 1228MHz を使用すると、次のような問題が発生する可能性があります。", "or 1228MHz on HiOPT can cause ": "HiOPT で 1228MHz を使用すると問題が発生する可能性があります。",
"permanent damage to your Switch!": "Switch に永久的なダメージを与えます!", "permanent damage to your Switch!": "Switch に永久的なダメージを与えます!",
"921MHz without UV and 960MHz on": "921MHzUVなし、960MHzUVあり", "921MHz without UV and 960MHz on": "921MHzUVなし、960MHzUVあり",
"SLT or HiOPT can cause ": "SLT または HiOPT が原因となる可能性があります" "SLT or HiOPT can cause ": "SLT または HiOPT が原因となる可能性があります",
"Default (Mariko)": "デフォルト(マリコ)",
"Default (Erista)": "デフォルト(エリスタ)",
"Rating": "評価",
"Safe Max (Mariko)": "セーフマックス(マリコ)",
"Safe Max (Erista)": "セーフマックス(エリスタ)",
"Voltages": "電圧",
"RAM Voltage:": "RAM電圧:",
"Display Voltage:": "ディスプレイ電圧:",
"Temperatures": "温度",
"PLLX Temp:": "PLLX 温度:",
"AOTAG Temp:": "AOTAG 温度:",
"BQ24193 Temp:": "BQ24193 温度:",
"Normal": "正常",
"Warm": "温かい",
"Hot": "熱い",
"Overheat": "過熱",
"Not Patched": "パッチなし",
"Invalid": "無効",
"RAM Bandwidth": "RAM帯域幅",
"RAM BW (Peak):": "RAM帯域(最大):",
"RAM BW (All):": "RAM帯域(全):",
"RAM BW (CPU):": "RAM帯域(CPU):",
"RAM BW (GPU):": "RAM帯域(GPU):",
"Hardware Info": "ハードウェア情報",
"Console Type:": "コンソールタイプ:",
"Speedo:": "Speedo:",
"DRAM Module: ": "DRAMモジュール: ",
"Software Info": "ソフトウェア情報",
"KIP version:": "KIPバージョン:",
"sys-dock status:": "システムドックのステータス:",
"SaltyNX status:": "SaltyNX ステータス:",
"RR Display status:": "RR 表示ステータス:",
"Wafer Position:": "ウェーハの位置:",
"IDDQ:": "IDQ:",
"Module: ": "モジュール:",
"Board": "理事会",
"Display": "ディスプレイ",
"Developers": "開発者",
"Contributors": "貢献者",
"Testers": "テスター",
"Translators": "翻訳者",
"Special Thanks": "特別な感謝の気持ち",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%u mV",
"Compiling with minimal features": "最小限の機能でコンパイルする",
"THE BEER-WARE LICENSE": "ビール製品ライセンス"
} }

View File

@@ -1,52 +1,42 @@
{ {
"Information": "정보", "Information": "정보",
"IDDQ:": "IDDQ:",
"Module: ": "모듈:",
"sys-dock status:": "sys-dock 상태:",
"SaltyNX status:": "SaltyNX 상태:",
"RR Display status:": "RR 표시 상태:",
"Wafer Position:": "웨이퍼 위치:",
"Credits": "크레딧",
"Developers": "개발자",
"Contributors": "기여자",
"Testers": "테스터",
"Special Thanks": "특별한 분",
"Unknown": "알 수 없음", "Unknown": "알 수 없음",
"Installed": "설치됨", "Installed": "설치됨",
"Not Installed": "설치되지 않음", "Not Installed": "설치되지 않음",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "맥주 제품 라이센스",
"Default": "기본값", "Default": "기본값",
"Do Not Override": "재정의하지 마십시오", "Do Not Override": "재정의하지 마십시오",
"Do not override": "재정의하지 않음",
"Disabled": "비활성화", "Disabled": "비활성화",
"Enabled": "활성화됨", "Enabled": "활성화됨",
" \\ue0e3 Reset": "\\ue0e3 재설정", "Enabled (Default)": "활성화됨(기본값)",
"Display": "디스플레이", "Enable": "활성화",
"Application changed\\n\\n": "애플리케이션이 변경되었습니다.\\n\\n", "Fatal error": "치명적인 오류",
"The running application changed\\n\\n": "실행 중인 애플리케이션이 변경되었습니다.\\n\\n",
"while editing was going on.": "편집이 진행되는 동안.",
"Board": "보드",
"%u.%u%u mV": "%u.%u%umV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "hoc-clk 시스템 모듈에 연결할 수 없습니다.\\n\\n", "Could not connect to hoc-clk sysmodule.\\n\\n": "hoc-clk 시스템 모듈에 연결할 수 없습니다.\\n\\n",
"Please make sure everything is\\n\\n": "모든 것이 올바른지 확인하십시오.\\n\\n", "Please make sure everything is\\n\\n": "모든 것이 올바른지 확인하십시오.\\n\\n",
"correctly installed and enabled.": "올바르게 설치되고 활성화되었습니다.", "correctly installed and enabled.": "올바르게 설치되고 활성화되었습니다.",
"Fatal error": "치명적인 오류",
"Edit App Profile": "앱 프로필 편집",
"Edit Global Profile": "글로벌 프로필 편집",
"Temporary Overrides": "임시 재정의",
"Temporary Overrides ": "임시 재정의", "Temporary Overrides ": "임시 재정의",
"  Reset": " 재설정",
"Settings": "설정",
"About": "소개",
"Credits": "크레딧",
"Application changed\\n\\n": "애플리케이션이 변경되었습니다.\\n\\n",
"The running application changed\\n\\n": "실행 중인 애플리케이션이 변경되었습니다.\\n\\n",
"while editing was going on.": "편집이 진행되는 동안.",
"Sleep Mode": "절전 모드", "Sleep Mode": "절전 모드",
"Stock": "주식", "Stock": "기본 설정",
"Dev OC": "개발 OC", "Dev OC": "개발 OC",
"Overwrite Boost Mode": "부스트 모드 덮어쓰기", "Boost Mode": "부스트 모드",
"Safe Max": "안전함 최대값", "Safe Max": "안전함 최대값",
"Unsafe Max": "불안정 최대값", "Unsafe Max": "불안정 최대값",
"Absolute Max": "절대 최대값", "Absolute Max": "절대 최대값",
"Handheld Safe Max": "휴대모드 안전함 최대값", "Handheld Safe Max": "휴대모드 안전함 최대값",
"Enable": "활성화",
"Edit App Profile": "앱 프로필 편집",
"Edit Global Profile": "글로벌 프로필 편집",
"Temporary Overrides": "임시 재정의",
"Settings": "설정",
"About": "소개",
"Compiling with minimal features": "최소한의 기능으로 컴파일하기",
"General Settings": "일반 설정", "General Settings": "일반 설정",
"Governor Settings": "거버너 설정", "Governor Settings": "거버너 설정",
"Safety Settings": "안전 설정", "Safety Settings": "안전 설정",
@@ -55,41 +45,64 @@
"CPU Settings": "CPU 설정", "CPU Settings": "CPU 설정",
"GPU Settings": "GPU 설정", "GPU Settings": "GPU 설정",
"Display Settings": "디스플레이 설정", "Display Settings": "디스플레이 설정",
"Experimental Settings": "실험적 설정",
"Experimental": "실험적", "Experimental": "실험적",
" Settings marked in blue": "파란색으로 표시된 설정은",
"don't require a reboot to apply!": "재부팅 없이 적용됩니다!",
"You can also press  to show": "을 눌러 표시할 수도 있습니다",
"information about each setting.": "각 설정에 대한 정보를.",
" Experimental Settings are incomplete ": "실험적 설정은 미완성입니다",
"and may not work correctly or at all!": "올바르게 작동하지 않을 수 있습니다!",
"Here be dragons!": "여기에 드래곤이 있습니다!",
"RAM Voltage Display Mode": "RAM 전압 표시 모드",
"RAM Display Unit": "RAM 표시 단위",
"Polling Interval": "폴링 간격",
"GPU Scheduling Override Method": "GPU 스케줄링 재정의 방법", "GPU Scheduling Override Method": "GPU 스케줄링 재정의 방법",
"GPU Scheduling Override": "GPU 스케줄링 재정의",
"GPU Boot Volt": "GPU 부팅 전압",
"GPU Boot Voltage": "GPU 부팅 전압",
"Memory Frequency Measurement Mode": "메모리 주파수 측정 모드",
" Overriding the charge current": "충전 전류 오버라이드",
"can be dangerous and may cause": "위험할 수 있고 원인이 될 수 있습니다.", "can be dangerous and may cause": "위험할 수 있고 원인이 될 수 있습니다.",
"damage to your battery or charger!": "배터리나 충전기가 손상되었습니다!", "damage to your battery or charger!": "배터리나 충전기가 손상되었습니다!",
"Charge Current Override": "충전 전류 오버라이드", "Charge Current Override": "충전 전류 오버라이드",
"RAM Voltage Display Mode": "RAM 전압 표시 모드", "Display Color Preset": "디스플레이 색상 프리셋",
"Polling Interval": "폴링 간격", "Basic": "기본",
"Saturated": "채도 높음",
"Washed": "연한색",
"Natural": "자연스러움",
"Vivid": "선명함",
"CPU Governor Minimum Frequency": "CPU 거버너 최소 주파수", "CPU Governor Minimum Frequency": "CPU 거버너 최소 주파수",
" Usage of unsafe display": "안전하지 않은 주사율 사용",
"refresh rates may cause stress": "디스플레이 주사율 빈도 변경은", "refresh rates may cause stress": "디스플레이 주사율 빈도 변경은",
"or damage to your display! ": "기기에 손상이 발생될 수 있습니다!", "or damage to your display! ": "기기에 손상이 발생될 수 있습니다!",
"Proceed at your own risk!": "책임하에 주의해서 사용하십시오!", "Proceed at your own risk!": "책임하에 주의해서 사용하십시오!",
"Max Handheld Display": "최대 휴대용 디스플레이", "Max Handheld Display": "최대 휴대용 디스플레이",
"Max Handheld Display Hz": "최대 휴대용 Hz",
"Display Clock": "디스플레이 클럭", "Display Clock": "디스플레이 클럭",
" Adjust the display voltage": "디스플레이 전압 조정",
"with caution to avoid damage": "손상을 피하기 위해 주의하여",
"to your display panel! ": "디스플레이 패널에!",
"Display Voltage": "디스플레이 전압",
"Thermal Throttle Limit": "열 스로틀 한계",
"Official Rating": "공식 등급", "Official Rating": "공식 등급",
"TDP Threshold": "TDP 임계값", "TDP Threshold": "TDP 임계값",
"Power": "힘", "Power": "힘",
"Thermal Throttle Limit": "열 스로틀 한계",
"HP Mode": "HP 모드", "HP Mode": "HP 모드",
"Default (Mariko)": "기본값(마리코)",
"Default (Erista)": "기본값(에리스타)", "DVB Shift": "DVB 시프트",
"Rating": "표준값", "SoC Max Volt": "SoC 최대 전압",
"Safe Max (Mariko)": "안전함 최대치(마리코)", "Step Mode": "스텝 모드",
"Safe Max (Erista)": "안전함 최대치(에리스타)",
"RAM VDD2 Voltage": "RAM VDD2 전압", "RAM VDD2 Voltage": "RAM VDD2 전압",
"Voltage": "전압",
"RAM VDDQ Voltage": "RAM VDDQ 전압", "RAM VDDQ Voltage": "RAM VDDQ 전압",
"Voltage": "전압",
"RAM Frequency Editor": "RAM 주파수 편집기", "RAM Frequency Editor": "RAM 주파수 편집기",
"JEDEC.": "JEDEC.",
"High speedo needed!": "높은 스피도값이 필요합니다!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz(극단적인 Speedo/PLL 필요)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz(극단적인 Speedo/PLL 필요)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz(극단적인 Speedo/PLL 필요)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (말도 안 되는 Speedo/PLL 필요)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz(터무니없는 Speedo/PLL 필요)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz(터무니없는 Speedo/PLL 필요)",
"Ram Max Clock": "RAM 최대 클럭", "Ram Max Clock": "RAM 최대 클럭",
"RAM Latency Editor": "RAM 지연 시간 편집기", "RAM Latency Editor": "RAM 지연 시간 편집기",
"RAM Timing Reductions": "RAM 타이밍 편집기", "RAM Timing Reductions": "RAM 타이밍 편집기",
@@ -102,6 +115,15 @@
"Memory Latencies": "메모리 지연 시간", "Memory Latencies": "메모리 지연 시간",
"Read Latency": "읽기 지연 시간", "Read Latency": "읽기 지연 시간",
"Write Latency": "쓰기 지연 시간", "Write Latency": "쓰기 지연 시간",
"High speedo needed!": "높은 스피도값이 필요합니다!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz(극단적인 Speedo/PLL 필요)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz(극단적인 Speedo/PLL 필요)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz(극단적인 Speedo/PLL 필요)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz(터무니없는 Speedo/PLL 필요)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz(터무니없는 Speedo/PLL 필요)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz(터무니없는 Speedo/PLL 필요)",
"JEDEC.": "JEDEC.",
"CPU Boost Clock": "CPU 부스트 클럭", "CPU Boost Clock": "CPU 부스트 클럭",
"CPU UV": "CPU 언더볼트", "CPU UV": "CPU 언더볼트",
"CPU Unlock": "CPU 잠금 해제", "CPU Unlock": "CPU 잠금 해제",
@@ -114,6 +136,7 @@
"CPU High UV": "CPU 고주파 언더볼트", "CPU High UV": "CPU 고주파 언더볼트",
"CPU Low VMIN": "CPU 저주파 최소 전압", "CPU Low VMIN": "CPU 저주파 최소 전압",
"CPU High VMIN": "CPU 고주파 최소 전압", "CPU High VMIN": "CPU 고주파 최소 전압",
"No Undervolt": "언더볼트 없음", "No Undervolt": "언더볼트 없음",
"SLT Table": "SLT 테이블", "SLT Table": "SLT 테이블",
"HiOPT Table": "HiOPT 테이블", "HiOPT Table": "HiOPT 테이블",
@@ -123,19 +146,70 @@
"GPU VMIN": "GPU VMIN", "GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "GPU 최대 전압", "GPU Maximum Voltage": "GPU 최대 전압",
"GPU Voltage Offset": "GPU 전압 오프셋", "GPU Voltage Offset": "GPU 전압 오프셋",
"Do not override": "재정의하지 않음",
"Enabled (Default)": "활성화됨(기본값)",
"96.6% limit": "96.6% 한도",
"99.7% limit": "99.7% 한도",
"GPU Scheduling Override": "GPU 스케줄링 재정의",
"Official Service": "공식 서비스",
"GPU DVFS Mode": "GPU DVFS 모드", "GPU DVFS Mode": "GPU DVFS 모드",
"GPU DVFS Offset": "GPU DVFS 오프셋", "GPU DVFS Offset": "GPU DVFS 오프셋",
"GPU Voltage Table": "GPU 전압 테이블", "GPU Voltage Table": "GPU 전압 테이블",
"GPU Custom Table (mV)": "GPU 사용자 정의 테이블(mV)", "GPU Custom Table (mV)": "GPU 사용자 정의 테이블(mV)",
"Official Service": "공식 서비스",
"96.6% limit": "96.6% 한도",
"99.7% limit": "99.7% 한도",
" Setting GPU Clocks past": "GPU 클럭을 초과 설정",
"1228MHz without a proper undervolt": "적절한 언더볼트 없이 1228MHz",
"can cause degradation or damage": "열화 또는 손상을 유발할 수 있습니다",
"to your console!": "콘솔에!",
"1075MHz without UV, 1152MHz on SLT": "UV 없이 1075MHz, SLT에서 1152MHz", "1075MHz without UV, 1152MHz on SLT": "UV 없이 1075MHz, SLT에서 1152MHz",
"or 1228MHz on HiOPT can cause ": "또는 HiOPT에서 1228MHz를 사용하면", "or 1228MHz on HiOPT can cause ": "또는 HiOPT에서 1228MHz를 사용하면",
"permanent damage to your Switch!": "스위치가 영구적으로 손상될 수 있습니다!", "permanent damage to your Switch!": "스위치가 영구적으로 손상될 수 있습니다!",
"921MHz without UV and 960MHz on": "UV가 없는 경우 921MHz, 켜진 경우에는 960MHz", "921MHz without UV and 960MHz on": "UV가 없는 경우 921MHz, 켜진 경우에는 960MHz",
"SLT or HiOPT can cause ": "SLT 또는 HiOPT는 다음을 유발할 수 있습니다." "SLT or HiOPT can cause ": "SLT 또는 HiOPT는 다음을 유발할 수 있습니다.",
"Default (Mariko)": "기본값(마리코)",
"Default (Erista)": "기본값(에리스타)",
"Rating": "표준값",
"Safe Max (Mariko)": "안전함 최대치(마리코)",
"Safe Max (Erista)": "안전함 최대치(에리스타)",
"Voltages": "전압",
"RAM Voltage:": "RAM 전압:",
"Display Voltage:": "디스플레이 전압:",
"Temperatures": "온도",
"PLLX Temp:": "PLLX 온도:",
"AOTAG Temp:": "AOTAG 온도:",
"BQ24193 Temp:": "BQ24193 온도:",
"Normal": "정상",
"Warm": "따뜻함",
"Hot": "뜨거움",
"Overheat": "과열",
"Not Patched": "패치 안 됨",
"Invalid": "유효하지 않음",
"RAM Bandwidth": "RAM 대역폭",
"RAM BW (Peak):": "RAM 대역폭 (최대):",
"RAM BW (All):": "RAM 대역폭 (전체):",
"RAM BW (CPU):": "RAM 대역폭 (CPU):",
"RAM BW (GPU):": "RAM 대역폭 (GPU):",
"Hardware Info": "하드웨어 정보",
"Console Type:": "콘솔 유형:",
"Speedo:": "Speedo:",
"DRAM Module: ": "DRAM 모듈: ",
"Software Info": "소프트웨어 정보",
"KIP version:": "KIP 버전:",
"sys-dock status:": "sys-dock 상태:",
"SaltyNX status:": "SaltyNX 상태:",
"RR Display status:": "RR 표시 상태:",
"Wafer Position:": "웨이퍼 위치:",
"IDDQ:": "IDDQ:",
"Module: ": "모듈:",
"Board": "보드",
"Display": "디스플레이",
"Developers": "개발자",
"Contributors": "기여자",
"Testers": "테스터",
"Translators": "번역자",
"Special Thanks": "특별한 분",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%umV",
"Compiling with minimal features": "최소한의 기능으로 컴파일하기",
"THE BEER-WARE LICENSE": "맥주 제품 라이센스"
} }

View File

@@ -1,52 +1,42 @@
{ {
"Information": "Informatie", "Information": "Informatie",
"IDDQ:": "IDDQ:",
"Module: ": "module:",
"sys-dock status:": "sys-dock-status:",
"SaltyNX status:": "SaltyNX-status:",
"RR Display status:": "RR Weergavestatus:",
"Wafer Position:": "Waferpositie:",
"Credits": "Kredieten",
"Developers": "Ontwikkelaars",
"Contributors": "Bijdragers",
"Testers": "Testers",
"Special Thanks": "Speciale dank",
"Unknown": "Onbekend", "Unknown": "Onbekend",
"Installed": "Geïnstalleerd", "Installed": "Geïnstalleerd",
"Not Installed": "Niet geïnstalleerd", "Not Installed": "Niet geïnstalleerd",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "DE LICENTIE VOOR BIERWAREN",
"Default": "Standaard", "Default": "Standaard",
"Do Not Override": "Niet overschrijven", "Do Not Override": "Niet overschrijven",
"Do not override": "Niet overschrijven",
"Disabled": "Uitgeschakeld", "Disabled": "Uitgeschakeld",
"Enabled": "Ingeschakeld", "Enabled": "Ingeschakeld",
" \\ue0e3 Reset": "\\ue0e3 Opnieuw instellen", "Enabled (Default)": "Ingeschakeld (standaard)",
"Display": "Weergave", "Enable": "Inschakelen",
"Application changed\\n\\n": "Applicatie gewijzigd\\n\\n", "Fatal error": "Fatale fout",
"The running application changed\\n\\n": "De actieve applicatie is gewijzigd\\n\\n",
"while editing was going on.": "terwijl er werd bewerkt.",
"Board": "Bord",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Kan geen verbinding maken met hoc-clk sysmodule.\\n\\n", "Could not connect to hoc-clk sysmodule.\\n\\n": "Kan geen verbinding maken met hoc-clk sysmodule.\\n\\n",
"Please make sure everything is\\n\\n": "Zorg ervoor dat alles in orde is\\n\\n", "Please make sure everything is\\n\\n": "Zorg ervoor dat alles in orde is\\n\\n",
"correctly installed and enabled.": "correct geïnstalleerd en ingeschakeld.", "correctly installed and enabled.": "correct geïnstalleerd en ingeschakeld.",
"Fatal error": "Fatale fout",
"Edit App Profile": "App-profiel bewerken",
"Edit Global Profile": "Globaal profiel bewerken",
"Temporary Overrides": "Tijdelijke overschrijvingen",
"Temporary Overrides ": "Tijdelijke overschrijvingen", "Temporary Overrides ": "Tijdelijke overschrijvingen",
"  Reset": " Opnieuw instellen",
"Settings": "Instellingen",
"About": "Over",
"Credits": "Kredieten",
"Application changed\\n\\n": "Applicatie gewijzigd\\n\\n",
"The running application changed\\n\\n": "De actieve applicatie is gewijzigd\\n\\n",
"while editing was going on.": "terwijl er werd bewerkt.",
"Sleep Mode": "Slaapmodus", "Sleep Mode": "Slaapmodus",
"Stock": "Voorraad", "Stock": "Voorraad",
"Dev OC": "Ontwikkelaar OC", "Dev OC": "Ontwikkelaar OC",
"Boost Mode": "Boost-modus", "Boost Mode": "Boost-modus",
"Safe Max": "Veilig Max", "Safe Max": "Veilig Max",
"Unsafe Max": "OnveiligMax", "Unsafe Max": "Onveilig Max",
"Absolute Max": "Absoluut Max", "Absolute Max": "Absoluut Max",
"Handheld Safe Max": "Handkluis Max", "Handheld Safe Max": "Handheld Veilig Max",
"Enable": "Inschakelen",
"Edit App Profile": "App-profiel bewerken",
"Edit Global Profile": "Globaal profiel bewerken",
"Temporary Overrides": "Tijdelijke overschrijvingen",
"Settings": "Instellingen",
"About": "Over",
"Compiling with minimal features": "Compileren met minimale functies",
"General Settings": "Algemene instellingen", "General Settings": "Algemene instellingen",
"Governor Settings": "Gouverneur instellingen", "Governor Settings": "Gouverneur instellingen",
"Safety Settings": "Veiligheidsinstellingen", "Safety Settings": "Veiligheidsinstellingen",
@@ -55,41 +45,64 @@
"CPU Settings": "CPU-instellingen", "CPU Settings": "CPU-instellingen",
"GPU Settings": "GPU-instellingen", "GPU Settings": "GPU-instellingen",
"Display Settings": "Weergave-instellingen", "Display Settings": "Weergave-instellingen",
"Experimental Settings": "Experimentele instellingen",
"Experimental": "Experimenteel", "Experimental": "Experimenteel",
" Settings marked in blue": "In blauw gemarkeerde instellingen",
"don't require a reboot to apply!": "vereisen geen herstart om toe te passen!",
"You can also press  to show": "Druk ook op  om te tonen",
"information about each setting.": "informatie over elke instelling.",
" Experimental Settings are incomplete ": "Experimentele instellingen zijn onvolledig",
"and may not work correctly or at all!": "en werken mogelijk helemaal niet!",
"Here be dragons!": "Hier zijn draken!",
"RAM Voltage Display Mode": "Weergavemodus RAM-spanning",
"RAM Display Unit": "RAM-weergave-eenheid",
"Polling Interval": "Polling-interval",
"GPU Scheduling Override Method": "Methode voor het overschrijven van GPU-planning", "GPU Scheduling Override Method": "Methode voor het overschrijven van GPU-planning",
"GPU Scheduling Override": "GPU-planning negeren",
"GPU Boot Volt": "GPU opstartspanning",
"GPU Boot Voltage": "GPU opstartspanning",
"Memory Frequency Measurement Mode": "Geheugenfrequentie-meetmodus",
" Overriding the charge current": "Het overschrijven van de laadstroom",
"can be dangerous and may cause": "kan gevaarlijk zijn en kan veroorzaken", "can be dangerous and may cause": "kan gevaarlijk zijn en kan veroorzaken",
"damage to your battery or charger!": "schade aan uw accu of lader!", "damage to your battery or charger!": "schade aan uw accu of lader!",
"Charge Current Override": "Laadstroom overschrijven", "Charge Current Override": "Laadstroom overschrijven",
"RAM Voltage Display Mode": "Weergavemodus RAM-spanning", "Display Color Preset": "Kleurvoorinstelling",
"Polling Interval": "Polling-interval", "Basic": "Basis",
"Saturated": "Verzadigd",
"Washed": "Uitgewassen",
"Natural": "Natuurlijk",
"Vivid": "Levendig",
"CPU Governor Minimum Frequency": "Minimale frequentie CPU-regelaar", "CPU Governor Minimum Frequency": "Minimale frequentie CPU-regelaar",
" Usage of unsafe display": "Het gebruik van onveilige schermfrequenties",
"refresh rates may cause stress": "vernieuwingsfrequenties kunnen stress veroorzaken", "refresh rates may cause stress": "vernieuwingsfrequenties kunnen stress veroorzaken",
"or damage to your display! ": "of schade aan uw display!", "or damage to your display! ": "of schade aan uw display!",
"Proceed at your own risk!": "Ga verder op eigen risico!", "Proceed at your own risk!": "Ga verder op eigen risico!",
"Max Handheld Display": "Maximaal handheld-display", "Max Handheld Display": "Maximaal handheld-display",
"Max Handheld Display Hz": "Max handheld Hz",
"Display Clock": "Klok weergeven", "Display Clock": "Klok weergeven",
" Adjust the display voltage": "Pas de displayspanning aan",
"with caution to avoid damage": "met voorzichtigheid om schade te vermijden",
"to your display panel! ": "van uw beeldschermpaneel!",
"Display Voltage": "Displayspanning",
"Thermal Throttle Limit": "Thermische gaslimiet",
"Official Rating": "Officiële beoordeling", "Official Rating": "Officiële beoordeling",
"TDP Threshold": "TDP-drempel", "TDP Threshold": "TDP-drempel",
"Power": "Macht", "Power": "Macht",
"Thermal Throttle Limit": "Thermische gaslimiet",
"HP Mode": "HP-modus", "HP Mode": "HP-modus",
"Default (Mariko)": "Standaard (Mariko)",
"Default (Erista)": "Standaard (Erista)", "DVB Shift": "DVB-verschuiving",
"Rating": "Beoordeling", "SoC Max Volt": "SoC max spanning",
"Safe Max (Mariko)": "Veilig Max (Mariko)", "Step Mode": "Stappmodus",
"Safe Max (Erista)": "Veilige Max (Erista)",
"RAM VDD2 Voltage": "RAM VDD2-spanning", "RAM VDD2 Voltage": "RAM VDD2-spanning",
"Voltage": "Spanning",
"RAM VDDQ Voltage": "RAM VDDQ-spanning", "RAM VDDQ Voltage": "RAM VDDQ-spanning",
"Voltage": "Spanning",
"RAM Frequency Editor": "RAM-frequentie-editor", "RAM Frequency Editor": "RAM-frequentie-editor",
"JEDEC.": "JEDEC.",
"High speedo needed!": "Hoge snelheid nodig!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (vereist extreme snelheidsmeter/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (vereist extreme snelheidsmeter/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (vereist extreme snelheidsmeter/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (heeft een belachelijke snelheidsmeter/PLL nodig)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (heeft een belachelijke snelheidsmeter/PLL nodig)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (heeft een belachelijke snelheidsmeter/PLL nodig)",
"Ram Max Clock": "Ram Max-klok", "Ram Max Clock": "Ram Max-klok",
"RAM Latency Editor": "RAM-latentie-editor", "RAM Latency Editor": "RAM-latentie-editor",
"RAM Timing Reductions": "RAM-timingreducties", "RAM Timing Reductions": "RAM-timingreducties",
@@ -102,6 +115,15 @@
"Memory Latencies": "Geheugenlatenties", "Memory Latencies": "Geheugenlatenties",
"Read Latency": "Lees Latentie", "Read Latency": "Lees Latentie",
"Write Latency": "Schrijf latentie", "Write Latency": "Schrijf latentie",
"High speedo needed!": "Hoge Speedo-waarde nodig!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (vereist extreme Speedo/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (vereist extreme Speedo/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (vereist extreme Speedo/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (heeft een belachelijke Speedo/PLL nodig)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (heeft een belachelijke Speedo/PLL nodig)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (heeft een belachelijke Speedo/PLL nodig)",
"JEDEC.": "JEDEC.",
"CPU Boost Clock": "CPU-boostklok", "CPU Boost Clock": "CPU-boostklok",
"CPU UV": "CPU-UV", "CPU UV": "CPU-UV",
"CPU Unlock": "CPU-ontgrendeling", "CPU Unlock": "CPU-ontgrendeling",
@@ -114,6 +136,7 @@
"CPU High UV": "CPU Hoge UV", "CPU High UV": "CPU Hoge UV",
"CPU Low VMIN": "CPU Lage VMIN", "CPU Low VMIN": "CPU Lage VMIN",
"CPU High VMIN": "CPU Hoge VMIN", "CPU High VMIN": "CPU Hoge VMIN",
"No Undervolt": "Geen ondervolt", "No Undervolt": "Geen ondervolt",
"SLT Table": "SLT-tabel", "SLT Table": "SLT-tabel",
"HiOPT Table": "HiOPT-tabel", "HiOPT Table": "HiOPT-tabel",
@@ -123,19 +146,70 @@
"GPU VMIN": "GPU-VMIN", "GPU VMIN": "GPU-VMIN",
"GPU Maximum Voltage": "GPU maximale spanning", "GPU Maximum Voltage": "GPU maximale spanning",
"GPU Voltage Offset": "GPU-spanningsoffset", "GPU Voltage Offset": "GPU-spanningsoffset",
"Do not override": "Niet overschrijven",
"Enabled (Default)": "Ingeschakeld (standaard)",
"96.6% limit": "96,6% limiet",
"99.7% limit": "99,7% limiet",
"GPU Scheduling Override": "GPU-planning negeren",
"Official Service": "Officiële dienst",
"GPU DVFS Mode": "GPU DVFS-modus", "GPU DVFS Mode": "GPU DVFS-modus",
"GPU DVFS Offset": "GPU DVFS-offset", "GPU DVFS Offset": "GPU DVFS-offset",
"GPU Voltage Table": "GPU-spanningstabel", "GPU Voltage Table": "GPU-spanningstabel",
"GPU Custom Table (mV)": "Aangepaste GPU-tabel (mV)", "GPU Custom Table (mV)": "Aangepaste GPU-tabel (mV)",
"Official Service": "Officiële dienst",
"96.6% limit": "96,6% limiet",
"99.7% limit": "99,7% limiet",
" Setting GPU Clocks past": "GPU-klokken instellen voorbij",
"1228MHz without a proper undervolt": "1228MHz zonder goede onderspanning",
"can cause degradation or damage": "kan degradatie of schade veroorzaken",
"to your console!": "aan uw console!",
"1075MHz without UV, 1152MHz on SLT": "1075MHz zonder UV, 1152MHz op SLT", "1075MHz without UV, 1152MHz on SLT": "1075MHz zonder UV, 1152MHz op SLT",
"or 1228MHz on HiOPT can cause ": "of 1228MHz op HiOPT kan dit veroorzaken", "or 1228MHz on HiOPT can cause ": "of 1228MHz op HiOPT kan dit veroorzaken",
"permanent damage to your Switch!": "blijvende schade aan uw Switch!", "permanent damage to your Switch!": "blijvende schade aan uw Switch!",
"921MHz without UV and 960MHz on": "921MHz zonder UV en 960MHz aan", "921MHz without UV and 960MHz on": "921MHz zonder UV en 960MHz aan",
"SLT or HiOPT can cause ": "SLT of HiOPT kunnen dit veroorzaken" "SLT or HiOPT can cause ": "SLT of HiOPT kunnen dit veroorzaken",
"Default (Mariko)": "Standaard (Mariko)",
"Default (Erista)": "Standaard (Erista)",
"Rating": "Beoordeling",
"Safe Max (Mariko)": "Veilig Max (Mariko)",
"Safe Max (Erista)": "Veilige Max (Erista)",
"Voltages": "Spanningen",
"RAM Voltage:": "RAM-spanning:",
"Display Voltage:": "Displayspanning:",
"Temperatures": "Temperaturen",
"PLLX Temp:": "PLLX Temp:",
"AOTAG Temp:": "AOTAG Temp:",
"BQ24193 Temp:": "BQ24193 Temp:",
"Normal": "Normaal",
"Warm": "Warm",
"Hot": "Heet",
"Overheat": "Oververhitting",
"Not Patched": "Niet gepatcht",
"Invalid": "Ongeldig",
"RAM Bandwidth": "RAM-bandbreedte",
"RAM BW (Peak):": "RAM-BW (Piek):",
"RAM BW (All):": "RAM-BW (Alle):",
"RAM BW (CPU):": "RAM-BW (CPU):",
"RAM BW (GPU):": "RAM-BW (GPU):",
"Hardware Info": "Hardware-info",
"Console Type:": "Consoletype:",
"Speedo:": "Speedo:",
"DRAM Module: ": "DRAM-module: ",
"Software Info": "Software-info",
"KIP version:": "KIP-versie:",
"sys-dock status:": "sys-dock-status:",
"SaltyNX status:": "SaltyNX-status:",
"RR Display status:": "RR Weergavestatus:",
"Wafer Position:": "Waferpositie:",
"IDDQ:": "IDDQ:",
"Module: ": "module:",
"Board": "Bord",
"Display": "Weergave",
"Developers": "Ontwikkelaars",
"Contributors": "Bijdragers",
"Testers": "Testers",
"Translators": "Vertalers",
"Special Thanks": "Speciale dank",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%u mV",
"Compiling with minimal features": "Compileren met minimale functies",
"THE BEER-WARE LICENSE": "DE LICENTIE VOOR BIERWAREN"
} }

View File

@@ -1,37 +1,33 @@
{ {
"Information": "Informacje", "Information": "Informacje",
"IDDQ:": "IDDQ:",
"Module: ": "Moduł:",
"sys-dock status:": "stan sys-dock:",
"SaltyNX status:": "Stan SaltyNX:",
"RR Display status:": "Stan wyświetlacza:",
"Wafer Position:": "Pozycja wafla:",
"Credits": "Kredyty",
"Developers": "Deweloperzy",
"Contributors": "Współautorzy",
"Testers": "Testery",
"Special Thanks": "Specjalne podziękowania",
"Unknown": "Nieznany", "Unknown": "Nieznany",
"Installed": "Zainstalowany", "Installed": "Zainstalowany",
"Not Installed": "Nie zainstalowano", "Not Installed": "Nie zainstalowano",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "LICENCJA NA WYROBY PIWNE",
"Default": "Domyślne", "Default": "Domyślne",
"Do Not Override": "Nie zastępuj", "Do Not Override": "Nie zastępuj",
"Disabled": "Niepełnosprawny", "Do not override": "Nie zastępuj",
"Disabled": "Wyłączony",
"Enabled": "Włączone", "Enabled": "Włączone",
" \\ue0e3 Reset": "\\ue0e3 Zresetuj", "Enabled (Default)": "Włączone (domyślnie)",
"Display": "Wyświetlacz", "Enable": "Włącz",
"Application changed\\n\\n": "Aplikacja została zmieniona\\n\\n", "Fatal error": "Fatalny błąd",
"The running application changed\\n\\n": "Działająca aplikacja została zmieniona\\n\\n",
"while editing was going on.": "podczas gdy edycja była w toku.",
"Board": "Deska",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Nie można połączyć się z modułem sysmodule hoc-clk.\\n\\n", "Could not connect to hoc-clk sysmodule.\\n\\n": "Nie można połączyć się z modułem sysmodule hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Upewnij się, że wszystko jest\\n\\n", "Please make sure everything is\\n\\n": "Upewnij się, że wszystko jest\\n\\n",
"correctly installed and enabled.": "poprawnie zainstalowany i włączony.", "correctly installed and enabled.": "poprawnie zainstalowany i włączony.",
"Fatal error": "Fatalny błąd",
"Edit App Profile": "Edytuj profil aplikacji",
"Edit Global Profile": "Edytuj profil globalny",
"Temporary Overrides": "Tymczasowe nadpisania",
"Temporary Overrides ": "Tymczasowe nadpisania", "Temporary Overrides ": "Tymczasowe nadpisania",
"  Reset": " Zresetuj",
"Settings": "Ustawienia",
"About": "O",
"Credits": "Kredyty",
"Application changed\\n\\n": "Aplikacja została zmieniona\\n\\n",
"The running application changed\\n\\n": "Działająca aplikacja została zmieniona\\n\\n",
"while editing was going on.": "podczas gdy edycja była w toku.",
"Sleep Mode": "Tryb uśpienia", "Sleep Mode": "Tryb uśpienia",
"Stock": "Zapas", "Stock": "Zapas",
"Dev OC": "Dev OC", "Dev OC": "Dev OC",
@@ -39,14 +35,8 @@
"Safe Max": "Bezpieczny maks", "Safe Max": "Bezpieczny maks",
"Unsafe Max": "Niebezpieczny maks", "Unsafe Max": "Niebezpieczny maks",
"Absolute Max": "Absolutny maks", "Absolute Max": "Absolutny maks",
"Handheld Safe Max": "Sejf ręczny Max", "Handheld Safe Max": "Przenośny bezpieczny maks",
"Enable": "Włącz",
"Edit App Profile": "Edytuj profil aplikacji",
"Edit Global Profile": "Edytuj profil globalny",
"Temporary Overrides": "Tymczasowe nadpisania",
"Settings": "Ustawienia",
"About": "O",
"Compiling with minimal features": "Kompilacja z minimalnymi funkcjami",
"General Settings": "Ustawienia ogólne", "General Settings": "Ustawienia ogólne",
"Governor Settings": "Ustawienia gubernatora", "Governor Settings": "Ustawienia gubernatora",
"Safety Settings": "Ustawienia bezpieczeństwa", "Safety Settings": "Ustawienia bezpieczeństwa",
@@ -55,41 +45,64 @@
"CPU Settings": "Ustawienia procesora", "CPU Settings": "Ustawienia procesora",
"GPU Settings": "Ustawienia GPU", "GPU Settings": "Ustawienia GPU",
"Display Settings": "Ustawienia wyświetlania", "Display Settings": "Ustawienia wyświetlania",
"Experimental Settings": "Ustawienia eksperymentalne",
"Experimental": "Eksperymentalny", "Experimental": "Eksperymentalny",
" Settings marked in blue": "Ustawienia zaznaczone na niebiesko",
"don't require a reboot to apply!": "nie wymagają ponownego uruchomienia!",
"You can also press  to show": "Możesz też wcisnąć  aby wyświetlić",
"information about each setting.": "informacje o każdym ustawieniu.",
" Experimental Settings are incomplete ": "Ustawienia eksperymentalne są niekompletne",
"and may not work correctly or at all!": "i mogą w ogóle nie działać!",
"Here be dragons!": "Tu są smoki!",
"RAM Voltage Display Mode": "Tryb wyświetlania napięcia RAM",
"RAM Display Unit": "Jednostka wyświetlania RAM",
"Polling Interval": "Interwał odpytywania",
"GPU Scheduling Override Method": "Metoda obejścia harmonogramu GPU", "GPU Scheduling Override Method": "Metoda obejścia harmonogramu GPU",
"GPU Scheduling Override": "Zastąpienie harmonogramu GPU",
"GPU Boot Volt": "Napięcie startowe GPU",
"GPU Boot Voltage": "Napięcie startowe GPU",
"Memory Frequency Measurement Mode": "Tryb pomiaru częstotliwości pamięci",
" Overriding the charge current": "Nadpisanie prądu ładowania",
"can be dangerous and may cause": "może być niebezpieczne i powodować", "can be dangerous and may cause": "może być niebezpieczne i powodować",
"damage to your battery or charger!": "uszkodzenie akumulatora lub ładowarki!", "damage to your battery or charger!": "uszkodzenie akumulatora lub ładowarki!",
"Charge Current Override": "Obejście prądu ładowania", "Charge Current Override": "Obejście prądu ładowania",
"RAM Voltage Display Mode": "Tryb wyświetlania napięcia RAM", "Display Color Preset": "Preset koloru",
"Polling Interval": "Interwał odpytywania", "Basic": "Podstawowy",
"Saturated": "Nasycony",
"Washed": "Wyblakły",
"Natural": "Naturalny",
"Vivid": "Żywy",
"CPU Governor Minimum Frequency": "Minimalna częstotliwość regulatora procesora", "CPU Governor Minimum Frequency": "Minimalna częstotliwość regulatora procesora",
" Usage of unsafe display": "Użycie niebezpiecznych częstotliwości",
"refresh rates may cause stress": "częstotliwości odświeżania mogą powodować stres", "refresh rates may cause stress": "częstotliwości odświeżania mogą powodować stres",
"or damage to your display! ": "lub uszkodzenie wyświetlacza!", "or damage to your display! ": "lub uszkodzenie wyświetlacza!",
"Proceed at your own risk!": "Postępuj na własne ryzyko!", "Proceed at your own risk!": "Postępuj na własne ryzyko!",
"Max Handheld Display": "Maksymalny wyświetlacz ręczny", "Max Handheld Display": "Maksymalny wyświetlacz ręczny",
"Max Handheld Display Hz": "Maks. Hz w trybie przenośnym",
"Display Clock": "Wyświetl zegar", "Display Clock": "Wyświetl zegar",
" Adjust the display voltage": "Dostosuj napięcie wyświetlacza",
"with caution to avoid damage": "ostrożnie, aby uniknąć uszkodzeń",
"to your display panel! ": "panelu wyświetlacza!",
"Display Voltage": "Napięcie wyświetlacza",
"Thermal Throttle Limit": "Limit przepustnicy termicznej",
"Official Rating": "Oficjalna ocena", "Official Rating": "Oficjalna ocena",
"TDP Threshold": "Próg TDP", "TDP Threshold": "Próg TDP",
"Power": "Moc", "Power": "Moc",
"Thermal Throttle Limit": "Limit przepustnicy termicznej",
"HP Mode": "Tryb HP", "HP Mode": "Tryb HP",
"Default (Mariko)": "Domyślny (Mariko)",
"Default (Erista)": "Domyślny (Erista)", "DVB Shift": "Przesunięcie DVB",
"Rating": "Ocena", "SoC Max Volt": "Maks. napięcie SoC",
"Safe Max (Mariko)": "Bezpieczny Max (Mariko)", "Step Mode": "Tryb krokowy",
"Safe Max (Erista)": "Bezpieczny Max (Erista)",
"RAM VDD2 Voltage": "Napięcie pamięci RAM VDD2", "RAM VDD2 Voltage": "Napięcie pamięci RAM VDD2",
"Voltage": "Napięcie",
"RAM VDDQ Voltage": "Napięcie RAM VDDQ", "RAM VDDQ Voltage": "Napięcie RAM VDDQ",
"Voltage": "Napięcie",
"RAM Frequency Editor": "Edytor częstotliwości RAM", "RAM Frequency Editor": "Edytor częstotliwości RAM",
"JEDEC.": "JEDEC.",
"High speedo needed!": "Potrzebna duża prędkość!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (wymaga ekstremalnego Speedo/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (wymaga ekstremalnego Speedo/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (wymaga ekstremalnego Speedo/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (potrzebuje śmiesznego Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (potrzebuje śmiesznego Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (potrzebuje śmiesznego Speedo/PLL)",
"Ram Max Clock": "Zegar Ram Max", "Ram Max Clock": "Zegar Ram Max",
"RAM Latency Editor": "Edytor opóźnień pamięci RAM", "RAM Latency Editor": "Edytor opóźnień pamięci RAM",
"RAM Timing Reductions": "Zmniejszenie taktowania pamięci RAM", "RAM Timing Reductions": "Zmniejszenie taktowania pamięci RAM",
@@ -100,8 +113,17 @@
"t7 tWTR Fine Tune": "t7 tWTR Dostosuj", "t7 tWTR Fine Tune": "t7 tWTR Dostosuj",
"tWTR Fine Tune": "tWTR Dostosuj", "tWTR Fine Tune": "tWTR Dostosuj",
"Memory Latencies": "Opóźnienia pamięci", "Memory Latencies": "Opóźnienia pamięci",
"Read Latency": "Przeczytaj Opóźnienie", "Read Latency": "Opóźnienie odczytu",
"Write Latency": "Opóźnienie zapisu", "Write Latency": "Opóźnienie zapisu",
"High speedo needed!": "Potrzebna duża wartość Speedo!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (wymaga ekstremalnego Speedo/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (wymaga ekstremalnego Speedo/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (wymaga ekstremalnego Speedo/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (potrzebuje śmiesznego Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (potrzebuje śmiesznego Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (potrzebuje śmiesznego Speedo/PLL)",
"JEDEC.": "JEDEC.",
"CPU Boost Clock": "Zegar wzmocnienia procesora", "CPU Boost Clock": "Zegar wzmocnienia procesora",
"CPU UV": "Procesor UV", "CPU UV": "Procesor UV",
"CPU Unlock": "Odblokowanie procesora", "CPU Unlock": "Odblokowanie procesora",
@@ -114,6 +136,7 @@
"CPU High UV": "Wysokie promieniowanie UV procesora", "CPU High UV": "Wysokie promieniowanie UV procesora",
"CPU Low VMIN": "Niski poziom VMIN procesora", "CPU Low VMIN": "Niski poziom VMIN procesora",
"CPU High VMIN": "Wysoki poziom VMIN procesora", "CPU High VMIN": "Wysoki poziom VMIN procesora",
"No Undervolt": "Brak Undervolta", "No Undervolt": "Brak Undervolta",
"SLT Table": "Stół SLT", "SLT Table": "Stół SLT",
"HiOPT Table": "Stół HiOPT", "HiOPT Table": "Stół HiOPT",
@@ -123,19 +146,70 @@
"GPU VMIN": "VMIN GPU", "GPU VMIN": "VMIN GPU",
"GPU Maximum Voltage": "Maksymalne napięcie procesora graficznego", "GPU Maximum Voltage": "Maksymalne napięcie procesora graficznego",
"GPU Voltage Offset": "Przesunięcie napięcia GPU", "GPU Voltage Offset": "Przesunięcie napięcia GPU",
"Do not override": "Nie zastępuj",
"Enabled (Default)": "Włączone (domyślnie)",
"96.6% limit": "Limit 96,6%.",
"99.7% limit": "Limit 99,7%.",
"GPU Scheduling Override": "Zastąpienie harmonogramu GPU",
"Official Service": "Oficjalny serwis",
"GPU DVFS Mode": "Tryb DVFS procesora graficznego", "GPU DVFS Mode": "Tryb DVFS procesora graficznego",
"GPU DVFS Offset": "Przesunięcie DVFS GPU", "GPU DVFS Offset": "Przesunięcie DVFS GPU",
"GPU Voltage Table": "Tabela napięć GPU", "GPU Voltage Table": "Tabela napięć GPU",
"GPU Custom Table (mV)": "Tabela niestandardowa GPU (mV)", "GPU Custom Table (mV)": "Tabela niestandardowa GPU (mV)",
"Official Service": "Oficjalny serwis",
"96.6% limit": "Limit 96,6%",
"99.7% limit": "Limit 99,7%",
" Setting GPU Clocks past": "Ustawianie zegarów GPU powyżej",
"1228MHz without a proper undervolt": "1228 MHz bez odpowiedniego undervolta",
"can cause degradation or damage": "może powodować degradację lub uszkodzenia",
"to your console!": "Twoją konsolę!",
"1075MHz without UV, 1152MHz on SLT": "1075 MHz bez UV, 1152 MHz na SLT", "1075MHz without UV, 1152MHz on SLT": "1075 MHz bez UV, 1152 MHz na SLT",
"or 1228MHz on HiOPT can cause ": "lub 1228 MHz na HiOPT może powodować", "or 1228MHz on HiOPT can cause ": "lub 1228 MHz na HiOPT może powodować",
"permanent damage to your Switch!": "trwałe uszkodzenie Switcha!", "permanent damage to your Switch!": "trwałe uszkodzenie Switcha!",
"921MHz without UV and 960MHz on": "921 MHz bez UV i 960 MHz włączone", "921MHz without UV and 960MHz on": "921 MHz bez UV i 960 MHz włączone",
"SLT or HiOPT can cause ": "Przyczyną mogą być SLT lub HiOPT" "SLT or HiOPT can cause ": "Przyczyną mogą być SLT lub HiOPT",
"Default (Mariko)": "Domyślny (Mariko)",
"Default (Erista)": "Domyślny (Erista)",
"Rating": "Ocena",
"Safe Max (Mariko)": "Bezpieczny Max (Mariko)",
"Safe Max (Erista)": "Bezpieczny Max (Erista)",
"Voltages": "Napięcia",
"RAM Voltage:": "Napięcie RAM:",
"Display Voltage:": "Napięcie wyświetlacza:",
"Temperatures": "Temperatury",
"PLLX Temp:": "PLLX Temp:",
"AOTAG Temp:": "AOTAG Temp:",
"BQ24193 Temp:": "BQ24193 Temp:",
"Normal": "Normalny",
"Warm": "Ciepły",
"Hot": "Gorący",
"Overheat": "Przegrzanie",
"Not Patched": "Bez patcha",
"Invalid": "Nieprawidłowy",
"RAM Bandwidth": "Przepustowość RAM",
"RAM BW (Peak):": "BW RAM (Maks.):",
"RAM BW (All):": "BW RAM (Wszys.):",
"RAM BW (CPU):": "BW RAM (CPU):",
"RAM BW (GPU):": "BW RAM (GPU):",
"Hardware Info": "Info o sprzęcie",
"Console Type:": "Typ konsoli:",
"Speedo:": "Speedo:",
"DRAM Module: ": "Moduł DRAM: ",
"Software Info": "Info o oprogramowaniu",
"KIP version:": "Wersja KIP:",
"sys-dock status:": "stan sys-dock:",
"SaltyNX status:": "Stan SaltyNX:",
"RR Display status:": "Stan wyświetlacza:",
"Wafer Position:": "Pozycja wafla:",
"IDDQ:": "IDDQ:",
"Module: ": "Moduł:",
"Board": "Deska",
"Display": "Wyświetlacz",
"Developers": "Deweloperzy",
"Contributors": "Współautorzy",
"Testers": "Testery",
"Translators": "Tłumacze",
"Special Thanks": "Specjalne podziękowania",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%u mV",
"Compiling with minimal features": "Kompilacja z minimalnymi funkcjami",
"THE BEER-WARE LICENSE": "LICENCJA NA WYROBY PIWNE"
} }

View File

@@ -1,52 +1,42 @@
{ {
"Information": "Informação", "Information": "Informação",
"IDDQ:": "IDDQ:",
"Module: ": "Módulo:",
"sys-dock status:": "status do dock do sistema:",
"SaltyNX status:": "Status do SaltyNX:",
"RR Display status:": "Status de exibição do RR:",
"Wafer Position:": "Posição da bolacha:",
"Credits": "Créditos",
"Developers": "Desenvolvedores",
"Contributors": "Colaboradores",
"Testers": "Testadores",
"Special Thanks": "Agradecimentos especiais",
"Unknown": "Desconhecido", "Unknown": "Desconhecido",
"Installed": "Instalado", "Installed": "Instalado",
"Not Installed": "Não instalado", "Not Installed": "Não instalado",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "A LICENÇA DE CERVEJA",
"Default": "Padrão", "Default": "Padrão",
"Do Not Override": "Não substituir", "Do Not Override": "Não substituir",
"Do not override": "Não substitua",
"Disabled": "Desativado", "Disabled": "Desativado",
"Enabled": "Habilitado", "Enabled": "Habilitado",
" \\ue0e3 Reset": "\\ue0e3 Redefinir", "Enabled (Default)": "Habilitado (padrão)",
"Display": "Exibição", "Enable": "Habilitar",
"Application changed\\n\\n": "Aplicativo alterado\\n\\n", "Fatal error": "Erro fatal",
"The running application changed\\n\\n": "O aplicativo em execução foi alterado\\n\\n",
"while editing was going on.": "enquanto a edição estava acontecendo.",
"Board": "Conselho",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Não foi possível conectar-se ao sysmodule hoc-clk.\\n\\n", "Could not connect to hoc-clk sysmodule.\\n\\n": "Não foi possível conectar-se ao sysmodule hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Verifique se tudo está\\n\\n", "Please make sure everything is\\n\\n": "Verifique se tudo está\\n\\n",
"correctly installed and enabled.": "corretamente instalado e ativado.", "correctly installed and enabled.": "corretamente instalado e ativado.",
"Fatal error": "Erro fatal",
"Edit App Profile": "Editar perfil do aplicativo",
"Edit Global Profile": "Editar perfil global",
"Temporary Overrides": "Substituições temporárias",
"Temporary Overrides ": "Substituições temporárias", "Temporary Overrides ": "Substituições temporárias",
"  Reset": " Redefinir",
"Settings": "Configurações",
"About": "Sobre",
"Credits": "Créditos",
"Application changed\\n\\n": "Aplicativo alterado\\n\\n",
"The running application changed\\n\\n": "O aplicativo em execução foi alterado\\n\\n",
"while editing was going on.": "enquanto a edição estava acontecendo.",
"Sleep Mode": "Modo de suspensão", "Sleep Mode": "Modo de suspensão",
"Stock": "Estoque", "Stock": "Padrão de fábrica",
"Dev OC": "Desenvolvedor OC", "Dev OC": "Desenvolvedor OC",
"Boost Mode": "Modo de reforço", "Boost Mode": "Modo de reforço",
"Safe Max": "Máx. Seguro", "Safe Max": "Máx. Seguro",
"Unsafe Max": "Máximo inseguro", "Unsafe Max": "Máximo inseguro",
"Absolute Max": "Máximo absoluto", "Absolute Max": "Máximo absoluto",
"Handheld Safe Max": "Portátil Seguro Máx.", "Handheld Safe Max": "Portátil Seguro Máx.",
"Enable": "Habilitar",
"Edit App Profile": "Editar perfil do aplicativo",
"Edit Global Profile": "Editar perfil global",
"Temporary Overrides": "Substituições temporárias",
"Settings": "Configurações",
"About": "Sobre",
"Compiling with minimal features": "Compilando com recursos mínimos",
"General Settings": "Configurações Gerais", "General Settings": "Configurações Gerais",
"Governor Settings": "Configurações do Governador", "Governor Settings": "Configurações do Governador",
"Safety Settings": "Configurações de segurança", "Safety Settings": "Configurações de segurança",
@@ -55,42 +45,65 @@
"CPU Settings": "Configurações de CPU", "CPU Settings": "Configurações de CPU",
"GPU Settings": "Configurações de GPU", "GPU Settings": "Configurações de GPU",
"Display Settings": "Configurações de exibição", "Display Settings": "Configurações de exibição",
"Experimental Settings": "Configurações experimentais",
"Experimental": "Experimental", "Experimental": "Experimental",
" Settings marked in blue": "Configurações marcadas em azul",
"don't require a reboot to apply!": "não requerem reinicialização para aplicar!",
"You can also press  to show": "Pressione também  para mostrar",
"information about each setting.": "informações sobre cada configuração.",
" Experimental Settings are incomplete ": "Configurações experimentais incompletas",
"and may not work correctly or at all!": "e podem não funcionar corretamente!",
"Here be dragons!": "Aqui há dragões!",
"RAM Voltage Display Mode": "Modo de exibição de tensão RAM",
"RAM Display Unit": "Unidade de exibição de RAM",
"Polling Interval": "Intervalo de sondagem",
"GPU Scheduling Override Method": "Método de substituição de agendamento de GPU", "GPU Scheduling Override Method": "Método de substituição de agendamento de GPU",
"GPU Scheduling Override": "Substituição de agendamento de GPU",
"GPU Boot Volt": "Tensão de inicialização da GPU",
"GPU Boot Voltage": "Tensão de inicialização da GPU",
"Memory Frequency Measurement Mode": "Modo de medição de frequência de memória",
" Overriding the charge current": "Substituir a corrente de carga",
"can be dangerous and may cause": "pode ser perigoso e causar", "can be dangerous and may cause": "pode ser perigoso e causar",
"damage to your battery or charger!": "danos à sua bateria ou carregador!", "damage to your battery or charger!": "danos à sua bateria ou carregador!",
"Charge Current Override": "Substituição de corrente de carga", "Charge Current Override": "Substituição de corrente de carga",
"RAM Voltage Display Mode": "Modo de exibição de tensão RAM", "Display Color Preset": "Predefinição de cor",
"Polling Interval": "Intervalo de votação", "Basic": "Básico",
"Saturated": "Saturado",
"Washed": "Desbotado",
"Natural": "Natural",
"Vivid": "Vívido",
"CPU Governor Minimum Frequency": "Frequência Mínima do Governador da CPU", "CPU Governor Minimum Frequency": "Frequência Mínima do Governador da CPU",
" Usage of unsafe display": "O uso de frequências de tela",
"refresh rates may cause stress": "taxas de atualização podem causar estresse", "refresh rates may cause stress": "taxas de atualização podem causar estresse",
"or damage to your display! ": "ou danos ao seu monitor!", "or damage to your display! ": "ou danos ao seu monitor!",
"Proceed at your own risk!": "Prossiga por sua conta e risco!", "Proceed at your own risk!": "Prossiga por sua conta e risco!",
"Max Handheld Display": "Visor portátil máximo", "Max Handheld Display": "Visor portátil máximo",
"Max Handheld Display Hz": "Hz máximo em modo portátil",
"Display Clock": "Exibir relógio", "Display Clock": "Exibir relógio",
" Adjust the display voltage": "Ajuste a tensão do display",
"with caution to avoid damage": "com cuidado para evitar danos",
"to your display panel! ": "ao painel do display!",
"Display Voltage": "Tensão do display",
"Thermal Throttle Limit": "Limite de aceleração térmica",
"Official Rating": "Classificação Oficial", "Official Rating": "Classificação Oficial",
"TDP Threshold": "Limite de TDP", "TDP Threshold": "Limite de TDP",
"Power": "Poder", "Power": "Potência",
"Thermal Throttle Limit": "Limite de aceleração térmica",
"HP Mode": "Modo HP", "HP Mode": "Modo HP",
"Default (Mariko)": "Padrão (Mariko)",
"Default (Erista)": "Padrão (Erista)", "DVB Shift": "Deslocamento DVB",
"Rating": "Avaliação", "SoC Max Volt": "Tensão máxima do SoC",
"Safe Max (Mariko)": "Máximo Seguro (Mariko)", "Step Mode": "Modo passo",
"Safe Max (Erista)": "Seguro Max (Erista)",
"RAM VDD2 Voltage": "Tensão RAM VDD2", "RAM VDD2 Voltage": "Tensão RAM VDD2",
"Voltage": "Tensão",
"RAM VDDQ Voltage": "Tensão RAM VDDQ", "RAM VDDQ Voltage": "Tensão RAM VDDQ",
"Voltage": "Tensão",
"RAM Frequency Editor": "Editor de frequência RAM", "RAM Frequency Editor": "Editor de frequência RAM",
"JEDEC.": "JEDEC.", "Ram Max Clock": "Frequência máxima de Ram",
"High speedo needed!": "Alta velocidade necessária!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (precisa de Speedo/PLL extremo)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (precisa de Speedo/PLL extremo)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (precisa de Speedo/PLL extremo)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (precisa de Speedo/PLL ridículo)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (precisa de Speedo/PLL ridículo)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (precisa de Speedo/PLL ridículo)",
"Ram Max Clock": "Relógio máximo de Ram",
"RAM Latency Editor": "Editor de latência de RAM", "RAM Latency Editor": "Editor de latência de RAM",
"RAM Timing Reductions": "Reduções de tempo de RAM", "RAM Timing Reductions": "Reduções de tempo de RAM",
"Memory Timings": "Tempos de memória", "Memory Timings": "Tempos de memória",
@@ -102,6 +115,15 @@
"Memory Latencies": "Latências de memória", "Memory Latencies": "Latências de memória",
"Read Latency": "Latência de leitura", "Read Latency": "Latência de leitura",
"Write Latency": "Latência de gravação", "Write Latency": "Latência de gravação",
"High speedo needed!": "Alto valor de Speedo necessário!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (precisa de Speedo/PLL extremo)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (precisa de Speedo/PLL extremo)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (precisa de Speedo/PLL extremo)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (precisa de Speedo/PLL ridículo)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (precisa de Speedo/PLL ridículo)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (precisa de Speedo/PLL ridículo)",
"JEDEC.": "JEDEC.",
"CPU Boost Clock": "Relógio de aumento da CPU", "CPU Boost Clock": "Relógio de aumento da CPU",
"CPU UV": "UV da CPU", "CPU UV": "UV da CPU",
"CPU Unlock": "Desbloqueio da CPU", "CPU Unlock": "Desbloqueio da CPU",
@@ -114,6 +136,7 @@
"CPU High UV": "CPU alta UV", "CPU High UV": "CPU alta UV",
"CPU Low VMIN": "CPU baixa VMIN", "CPU Low VMIN": "CPU baixa VMIN",
"CPU High VMIN": "VMIN alto da CPU", "CPU High VMIN": "VMIN alto da CPU",
"No Undervolt": "Sem subtensão", "No Undervolt": "Sem subtensão",
"SLT Table": "Tabela SLT", "SLT Table": "Tabela SLT",
"HiOPT Table": "Tabela HiOPT", "HiOPT Table": "Tabela HiOPT",
@@ -123,19 +146,70 @@
"GPU VMIN": "GPU VMIN", "GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "Tensão máxima da GPU", "GPU Maximum Voltage": "Tensão máxima da GPU",
"GPU Voltage Offset": "Compensação de tensão da GPU", "GPU Voltage Offset": "Compensação de tensão da GPU",
"Do not override": "Não substitua",
"Enabled (Default)": "Habilitado (padrão)",
"96.6% limit": "Limite de 96,6%",
"99.7% limit": "Limite de 99,7%",
"GPU Scheduling Override": "Substituição de agendamento de GPU",
"Official Service": "Serviço Oficial",
"GPU DVFS Mode": "Modo GPU DVFS", "GPU DVFS Mode": "Modo GPU DVFS",
"GPU DVFS Offset": "Deslocamento DVFS da GPU", "GPU DVFS Offset": "Deslocamento DVFS da GPU",
"GPU Voltage Table": "Tabela de tensão da GPU", "GPU Voltage Table": "Tabela de tensão da GPU",
"GPU Custom Table (mV)": "Tabela personalizada de GPU (mV)", "GPU Custom Table (mV)": "Tabela personalizada de GPU (mV)",
"Official Service": "Serviço Oficial",
"96.6% limit": "Limite de 96,6%",
"99.7% limit": "Limite de 99,7%",
" Setting GPU Clocks past": "Definir clocks de GPU além de",
"1228MHz without a proper undervolt": "1228MHz sem undervolt adequado",
"can cause degradation or damage": "pode causar degradação ou danos",
"to your console!": "ao seu console!",
"1075MHz without UV, 1152MHz on SLT": "1075 MHz sem UV, 1152 MHz em SLT", "1075MHz without UV, 1152MHz on SLT": "1075 MHz sem UV, 1152 MHz em SLT",
"or 1228MHz on HiOPT can cause ": "ou 1228 MHz em HiOPT pode causar", "or 1228MHz on HiOPT can cause ": "ou 1228 MHz em HiOPT pode causar",
"permanent damage to your Switch!": "danos permanentes ao seu Switch!", "permanent damage to your Switch!": "danos permanentes ao seu Switch!",
"921MHz without UV and 960MHz on": "921 MHz sem UV e 960 MHz ativado", "921MHz without UV and 960MHz on": "921 MHz sem UV e 960 MHz ativado",
"SLT or HiOPT can cause ": "SLT ou HiOPT podem causar" "SLT or HiOPT can cause ": "SLT ou HiOPT podem causar",
"Default (Mariko)": "Padrão (Mariko)",
"Default (Erista)": "Padrão (Erista)",
"Rating": "Avaliação",
"Safe Max (Mariko)": "Máximo Seguro (Mariko)",
"Safe Max (Erista)": "Seguro Max (Erista)",
"Voltages": "Tensões",
"RAM Voltage:": "Tensão RAM:",
"Display Voltage:": "Tensão do display:",
"Temperatures": "Temperaturas",
"PLLX Temp:": "PLLX Temp:",
"AOTAG Temp:": "AOTAG Temp:",
"BQ24193 Temp:": "BQ24193 Temp:",
"Normal": "Normal",
"Warm": "Morno",
"Hot": "Quente",
"Overheat": "Superaquecimento",
"Not Patched": "Não corrigido",
"Invalid": "Inválido",
"RAM Bandwidth": "Largura de banda RAM",
"RAM BW (Peak):": "BW RAM (Pico):",
"RAM BW (All):": "BW RAM (Total):",
"RAM BW (CPU):": "BW RAM (CPU):",
"RAM BW (GPU):": "BW RAM (GPU):",
"Hardware Info": "Info de hardware",
"Console Type:": "Tipo de console:",
"Speedo:": "Speedo:",
"DRAM Module: ": "Módulo DRAM: ",
"Software Info": "Info de software",
"KIP version:": "Versão KIP:",
"sys-dock status:": "status do dock do sistema:",
"SaltyNX status:": "Status do SaltyNX:",
"RR Display status:": "Status de exibição do RR:",
"Wafer Position:": "Posição do wafer:",
"IDDQ:": "IDDQ:",
"Module: ": "Módulo:",
"Board": "Placa",
"Display": "Exibição",
"Developers": "Desenvolvedores",
"Contributors": "Colaboradores",
"Testers": "Testadores",
"Translators": "Tradutores",
"Special Thanks": "Agradecimentos especiais",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%u mV",
"Compiling with minimal features": "Compilando com recursos mínimos",
"THE BEER-WARE LICENSE": "A LICENÇA DE CERVEJA"
} }

View File

@@ -1,141 +1,216 @@
{ {
"Information": "Информация", "Information": "Информация",
"IDDQ:": "ИДДК:",
"Module: ": "Модуль:",
"sys-dock status:": "Статус системной док-станции:",
"SaltyNX status:": "Статус SaltyNX:",
"RR Display status:": "Статус отображения RR:",
"Wafer Position:": "Позиция вафли:",
"Credits": "Кредиты",
"Developers": "Разработчики",
"Contributors": "Авторы",
"Testers": "Тестеры",
"Special Thanks": "Особая благодарность",
"Unknown": "Неизвестно", "Unknown": "Неизвестно",
"Installed": "Установлено", "Installed": "Установлено",
"Not Installed": "Не установлено", "Not Installed": "Не установлено",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "ЛИЦЕНЗИЯ НА ПРОДАЖУ ПИВА",
"Default": "По умолчанию", "Default": "По умолчанию",
"Do Not Override": "Не переопределять", "Do Not Override": "Не менять",
"Do not override": "Не менять",
"Disabled": "Отключено", "Disabled": "Отключено",
"Enabled": "Включено", "Enabled": "Включено",
" \\ue0e3 Reset": "\\ue0e3 Сброс", "Enabled (Default)": "Включено (По умолчанию)",
"Display": "Дисплей", "Enable": "Включено",
"Fatal error": "Фатальная ошибка",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Не удалось подключиться к сис-модулю hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Пожалуйста, убедитесь, что все\\n\\n",
"correctly installed and enabled.": "правильно установлено и включено.",
"Edit App Profile": "Профиль приложения",
"Edit Global Profile": "Глобальный профиль",
"Temporary Overrides": "Временный профиль",
"Temporary Overrides ": "Временный профиль",
"  Reset": " Сброс",
"Settings": "Настройки",
"About": "Сведения",
"Credits": "Благодарности",
"Application changed\\n\\n": "Приложение изменено\\n\\n", "Application changed\\n\\n": "Приложение изменено\\n\\n",
"The running application changed\\n\\n": "Запущенное приложение изменилось\\n\\n", "The running application changed\\n\\n": "Запущенное приложение изменилось\\n\\n",
"while editing was going on.": "пока шло редактирование.", "while editing was going on.": "пока шло редактирование.",
"Board": "Совет",
"%u.%u%u mV": "%u.%u%u мВ",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Не удалось подключиться к системному модулю hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Пожалуйста, убедитесь, что все в порядке\\n\\n",
"correctly installed and enabled.": "правильно установлен и включен.",
"Fatal error": "Неустранимая ошибка",
"Temporary Overrides ": "Временные переопределения",
"Sleep Mode": "Спящий режим", "Sleep Mode": "Спящий режим",
"Stock": "Акции", "Stock": "Стандарт",
"Dev OC": "Разработчик OC", "Dev OC": "Разгон dev-кита",
"Boost Mode": "Режим повышения", "Boost Mode": "Режим буста",
"Safe Max": "Сейф Макс", "Safe Max": "Безопасный макс.",
"Unsafe Max": "Небезопасный Макс", "Unsafe Max": "Опасный макс.",
"Absolute Max": "Абсолютный Макс", "Absolute Max": "Абсолютный макс.",
"Handheld Safe Max": "Ручной сейф Макс", "Handheld Safe Max": "Портативный безопасный макс.",
"Enable": "Включить",
"Edit App Profile": "Редактировать профиль приложения", "General Settings": "Основные настройки",
"Edit Global Profile": "Редактировать глобальный профиль", "Governor Settings": "Настройки говернора",
"Temporary Overrides": "Временные переопределения",
"Settings": "Настройки",
"About": "О",
"Compiling with minimal features": "Компиляция с минимальными возможностями",
"General Settings": "Общие настройки",
"Governor Settings": "Настройки губернатора",
"Safety Settings": "Настройки безопасности", "Safety Settings": "Настройки безопасности",
"Save KIP Settings": "Сохранить настройки КИП", "Save KIP Settings": "Сохранить настройки KIP",
"RAM Settings": "Настройки ОЗУ", "RAM Settings": "Настройки RAM",
"CPU Settings": "Настройки процессора", "CPU Settings": "Настройки CPU",
"GPU Settings": "Настройки графического процессора", "GPU Settings": "Настройки GPU",
"Display Settings": "Настройки дисплея", "Display Settings": "Настройки дисплея",
"Experimental Settings": "Экспериментальные",
"Experimental": "Экспериментальный", "Experimental": "Экспериментальный",
"GPU Scheduling Override Method": "Метод переопределения планирования графического процессора",
"can be dangerous and may cause": "может быть опасным и может вызвать", " Settings marked in blue": "Настройки помеченные синим",
"damage to your battery or charger!": "повреждение аккумулятора или зарядного устройства!", "don't require a reboot to apply!": "Синие настройки применяются сразу!",
"Charge Current Override": "Блокировка зарядного тока", "You can also press  to show": "Нажмите  для просмотра",
"RAM Voltage Display Mode": "Режим отображения напряжения ОЗУ", "information about each setting.": "информацию о каждом параметре.",
" Experimental Settings are incomplete ": "Экспериментальные настройки не закончены",
"and may not work correctly or at all!": "Экспериментальные настройки могут не работать!",
"Here be dragons!": "Здесь будут драконы!",
"RAM Voltage Display Mode": "Показ вольтажа RAM",
"RAM Display Unit": "Показ единицы измерения RAM",
"Polling Interval": "Интервал опроса", "Polling Interval": "Интервал опроса",
"CPU Governor Minimum Frequency": "Минимальная частота регулятора ЦП",
"refresh rates may cause stress": "частота обновления может вызвать стресс", "GPU Scheduling Override Method": "Метод перезаписи планировщика GPU",
"or damage to your display! ": "или повреждение дисплея!", "GPU Scheduling Override": "Перезапись планировщика",
"GPU Boot Volt": "Напряжение загрузки GPU",
"GPU Boot Voltage": "Напряжение загрузки GPU",
"Memory Frequency Measurement Mode": "Режим измерения частоты RAM",
" Overriding the charge current": "Перезапись зарядного тока может",
"can be dangerous and may cause": "Перезапись зарядного тока может",
"damage to your battery or charger!": "повреждить аккумулятор или зарядку!",
"Charge Current Override": "Перезапись зарядного тока",
"Display Color Preset": "Цветовой пресет",
"Basic": "Базовый",
"Saturated": "Насыщенный",
"Washed": "Бледный",
"Natural": "Натуральный",
"Vivid": "Яркий",
"CPU Governor Minimum Frequency": "Минимальная частота говернора CPU",
" Usage of unsafe display": "Использование не безопасной",
"refresh rates may cause stress": "Не безопасная частота",
"or damage to your display! ": "может повредить ваш экран",
"Proceed at your own risk!": "Действуйте на свой страх и риск!", "Proceed at your own risk!": "Действуйте на свой страх и риск!",
"Max Handheld Display": "Макс. портативный дисплей", "Max Handheld Display": "Макс. дисплей портатива",
"Display Clock": "Дисплей Часы", "Max Handheld Display Hz": "Макс. в портативе",
"Display Clock": "Частота экрана",
" Adjust the display voltage": "Настройте напряжение экрана",
"with caution to avoid damage": "с осторожностью во избежание повреждений",
"to your display panel! ": "повреждений экрана!",
"Display Voltage": "Напряжение экрана",
"Thermal Throttle Limit": "Предел троттлинга",
"Official Rating": "Официальный рейтинг", "Official Rating": "Официальный рейтинг",
"TDP Threshold": "Порог TDP", "TDP Threshold": "Порог TDP",
"Power": "Мощность", "Power": "Мощность",
"Thermal Throttle Limit": "Температурный предел дроссельной заслонки",
"HP Mode": "Режим HP", "HP Mode": "Режим HP",
"Default (Mariko)": "По умолчанию (Марико)",
"Default (Erista)": "По умолчанию (Эриста)", "DVB Shift": "DVB сдвиг",
"Rating": "Рейтинг", "SoC Max Volt": "Макс. вольт SoC",
"Safe Max (Mariko)": "Сейф Макс (Марико)", "Step Mode": "Частотный шаг",
"Safe Max (Erista)": "Сейф Макс (Эриста)", "RAM VDD2 Voltage": "Вольтаж VDD2",
"RAM VDD2 Voltage": "Напряжение ОЗУ VDD2", "RAM VDDQ Voltage": "Вольтаж VDDQ",
"Voltage": "Напряжение", "Voltage": "Вольтаж",
"RAM VDDQ Voltage": "Напряжение ОЗУ VDDQ", "RAM Frequency Editor": "Редактор частоты",
"RAM Frequency Editor": "Редактор частоты оперативной памяти", "Ram Max Clock": "Макс. частота",
"JEDEC.": "ДЖЕДЕК.", "RAM Latency Editor": "Редактор задержек",
"High speedo needed!": "Нужен высокий спидометр!", "RAM Timing Reductions": "Настройка таймингов",
"3333MHz (Needs extreme Speedo/PLL)": "3333 МГц (требуется экстремальный спидометр/PLL)", "Memory Timings": "Тайминги RAM",
"3366MHz (Needs extreme Speedo/PLL)": "3366 МГц (требуется экстремальный спидометр/PLL)", "Advanced": "Расширенные",
"3400MHz (Needs extreme Speedo/PLL)": "3400 МГц (требуется экстремальный спидометр/PLL)", "t6 tRTW Fine Tune": "Точная настройка t6 tRTW",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 МГц (нужен нелепый спидометр/PLL)", "tRTW Fine Tune": "Точная настройка tRTW",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 МГц (нужен нелепый спидометр/PLL)", "t7 tWTR Fine Tune": "Точная настройка t7 tWTR",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 МГц (нужен нелепый спидометр/PLL)", "tWTR Fine Tune": "Точная настройка tWTR",
"Ram Max Clock": "Рам Макс Часы",
"RAM Latency Editor": "Редактор задержки оперативной памяти",
"RAM Timing Reductions": "Сокращение таймингов ОЗУ",
"Memory Timings": "Тайминги памяти",
"Advanced": "Расширенный",
"t6 tRTW Fine Tune": "t6 tRTW Точная настройка",
"tRTW Fine Tune": "tRTW Точная настройка",
"t7 tWTR Fine Tune": "t7 tWTR Тонкая настройка",
"tWTR Fine Tune": "tWTR Тонкая настройка",
"Memory Latencies": "Задержки памяти", "Memory Latencies": "Задержки памяти",
"Read Latency": "Задержка чтения", "Read Latency": "Задержка чтения",
"Write Latency": "Задержка записи", "Write Latency": "Задержка записи",
"CPU Boost Clock": "Тактовая частота процессора", "High speedo needed!": "Для высоких speedo",
"CPU UV": "УФ процессора", "3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (нужны невероятные speedo/PLL)",
"CPU Unlock": "Разблокировка процессора", "3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (нужны невероятные speedo/PLL)",
"CPU VMIN": "ЦП VMIN", "3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (нужны невероятные speedo/PLL)",
"CPU Max Voltage": "Максимальное напряжение процессора", "3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (нужны безумные speedo/PLL)",
"CPU Max Clock": "Максимальная частота процессора", "3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (нужны безумные speedo/PLL)",
"Extreme UV Table": "Стол для экстремального УФ-излучения", "3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (нужны безумные speedo/PLL)",
"CPU UV Table": "UV-таблица процессора", "JEDEC.": "JEDEC.",
"CPU Low UV": "ЦП с низким УФ-излучением",
"CPU High UV": "Процессор с высоким УФ", "CPU Boost Clock": "Частота буста",
"CPU Low VMIN": "Низкий VMIN процессора", "CPU UV": "Андервольт CPU",
"CPU High VMIN": "Высокий VMIN процессора", "CPU Unlock": "Разблокировка CPU",
"No Undervolt": "Нет Андервольта", "CPU VMIN": "Мин. вольтаж",
"SLT Table": "Таблица ТА", "CPU Max Voltage": "Макс. вольтаж",
"CPU Max Clock": "Макс. частота",
"Extreme UV Table": "Экстримальная",
"CPU UV Table": "Таблица андервольта",
"CPU Low UV": "Андервольт нижних частот",
"CPU High UV": "Андервольт верхних частот",
"CPU Low VMIN": "Мин. вольт. нижних частот",
"CPU High VMIN": "Мин. вольт. верхних частот",
"No Undervolt": "Без андервольта",
"SLT Table": "Таблица SLT",
"HiOPT Table": "Таблица HiOPT", "HiOPT Table": "Таблица HiOPT",
"GPU Undervolt Table": "Таблица пониженного напряжения графического процессора", "GPU Undervolt Table": "Таблица андервольта",
"GPU Minimum Voltage": "Минимальное напряжение графического процессора", "GPU Minimum Voltage": "Мин. вольтаж",
"Calculate GPU Vmin": "Рассчитать Vmin графического процессора", "Calculate GPU Vmin": "Вычисление мин. вольтаж",
"GPU VMIN": "Вмин графического процессора", "GPU VMIN": "Мин. вольтаж",
"GPU Maximum Voltage": "Максимальное напряжение графического процессора", "GPU Maximum Voltage": "Макс. вольтаж",
"GPU Voltage Offset": "Смещение напряжения графического процессора", "GPU Voltage Offset": "Смещение вольтажа",
"Do not override": "Не переопределять", "GPU DVFS Mode": "Режим DVFS",
"Enabled (Default)": "Включено (по умолчанию)", "GPU DVFS Offset": "Смещение DVFS",
"96.6% limit": "Предел 96,6%", "GPU Voltage Table": "Таблица вольтажей",
"99.7% limit": "лимит 99,7%", "GPU Custom Table (mV)": "Ручная таблица (мВ)",
"GPU Scheduling Override": "Переопределение планирования графического процессора",
"Official Service": "Официальная служба", "Official Service": "Официальная служба",
"GPU DVFS Mode": "Режим графического процессора DVFS", "96.6% limit": "≤96,6%",
"GPU DVFS Offset": "Смещение DVFS графического процессора", "99.7% limit": "≤99,7%",
"GPU Voltage Table": "Таблица напряжений графического процессора", " Setting GPU Clocks past": "Установка частот GPU выше",
"GPU Custom Table (mV)": "Пользовательская таблица графического процессора (мВ)", "1228MHz without a proper undervolt": "Установка частот GPU выше 1228 МГц",
"1075MHz without UV, 1152MHz on SLT": "1075 МГц без УФ, 1152 МГц на SLT", "can cause degradation or damage": "без хорошего андервольта может",
"to your console!": "повредить вашу консоль!",
"1075MHz without UV, 1152MHz on SLT": "1075 МГц без UV, 1152 МГц на SLT",
"or 1228MHz on HiOPT can cause ": "или 1228 МГц на HiOPT может привести к", "or 1228MHz on HiOPT can cause ": "или 1228 МГц на HiOPT может привести к",
"permanent damage to your Switch!": "необратимое повреждение вашего коммутатора!", "permanent damage to your Switch!": "постоянному повреждению вашей Switch!",
"921MHz without UV and 960MHz on": "921 МГц без УФ и 960 МГц с включенным", "921MHz without UV and 960MHz on": "921 МГц без UV и 960 МГц на",
"SLT or HiOPT can cause ": "SLT или HiOPT могут вызвать" "SLT or HiOPT can cause ": "SLT или HiOPT могут привести к",
"Default (Mariko)": "По умолчанию (M)",
"Default (Erista)": "По умолчанию (E)",
"Rating": "Рейтинг",
"Safe Max (Mariko)": "Сейф Макс (M)",
"Safe Max (Erista)": "Сейф Макс (E)",
"Voltages": "Напряжения",
"RAM Voltage:": "Напряжение RAM:",
"Display Voltage:": "Напряжение дисплея:",
"Temperatures": "Температуры",
"PLLX Temp:": "PLLX Темп.:",
"AOTAG Temp:": "AOTAG Темп.:",
"BQ24193 Temp:": "BQ24193 Темп.:",
"Normal": "Нормальная",
"Warm": "Тёплая",
"Hot": "Горячая",
"Overheat": "Перегрев",
"Not Patched": "Не пропатчено",
"Invalid": "Недействительно",
"RAM Bandwidth": "Пропускная способность RAM",
"RAM BW (Peak):": "Полоса RAM (Макс.):",
"RAM BW (All):": "Полоса RAM (Всего):",
"RAM BW (CPU):": "Полоса RAM (CPU):",
"RAM BW (GPU):": "Полоса RAM (GPU):",
"Hardware Info": "Информация об оборудовании",
"Console Type:": "Тип консоли:",
"Speedo:": "Speedo:",
"DRAM Module: ": "Модуль DRAM: ",
"Software Info": "Информация о программе",
"KIP version:": "Версия KIP:",
"sys-dock status:": "Статус sys-dock:",
"SaltyNX status:": "Статус SaltyNX:",
"RR Display status:": "Статус RR Display:",
"Wafer Position:": "Wafer Position:",
"IDDQ:": "IDDQ:",
"Module: ": "Module:",
"Board": "Board",
"Display": "Дисплей",
"Developers": "Разработчики",
"Contributors": "Внесли вклад",
"Testers": "Тестеры",
"Translators": "Переводчики",
"Special Thanks": "Особая благодарность",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%u мВ",
"Compiling with minimal features": "Собрано с урезанием функций",
"THE BEER-WARE LICENSE": "BEER-WARE LICENSE",
"Auto": "Авто"
} }

View File

@@ -0,0 +1,214 @@
{
"Information": "",
"Unknown": "",
"Installed": "",
"Not Installed": "",
"Default": "",
"Do Not Override": "",
"Do not override": "",
"Disabled": "",
"Enabled": "",
"Enabled (Default)": "",
"Enable": "",
"Fatal error": "",
"Could not connect to hoc-clk sysmodule.\\n\\n": "",
"Please make sure everything is\\n\\n": "",
"correctly installed and enabled.": "",
"Edit App Profile": "",
"Edit Global Profile": "",
"Temporary Overrides": "",
"Temporary Overrides ": "",
"  Reset": "",
"Settings": "",
"About": "",
"Credits": "",
"Application changed\\n\\n": "",
"The running application changed\\n\\n": "",
"while editing was going on.": "",
"Sleep Mode": "",
"Stock": "",
"Dev OC": "",
"Boost Mode": "",
"Safe Max": "",
"Unsafe Max": "",
"Absolute Max": "",
"Handheld Safe Max": "",
"General Settings": "",
"Governor Settings": "",
"Safety Settings": "",
"Save KIP Settings": "",
"RAM Settings": "",
"CPU Settings": "",
"GPU Settings": "",
"Display Settings": "",
"Experimental Settings": "",
"Experimental": "",
" Settings marked in blue": "",
"don't require a reboot to apply!": "",
"You can also press  to show": "",
"information about each setting.": "",
" Experimental Settings are incomplete ": "",
"and may not work correctly or at all!": "",
"Here be dragons!": "",
"RAM Voltage Display Mode": "",
"RAM Display Unit": "",
"Polling Interval": "",
"GPU Scheduling Override Method": "",
"GPU Scheduling Override": "",
"GPU Boot Volt": "",
"GPU Boot Voltage": "",
"Memory Frequency Measurement Mode": "",
" Overriding the charge current": "",
"can be dangerous and may cause": "",
"damage to your battery or charger!": "",
"Charge Current Override": "",
"Display Color Preset": "",
"Basic": "",
"Saturated": "",
"Washed": "",
"Natural": "",
"Vivid": "",
"CPU Governor Minimum Frequency": "",
" Usage of unsafe display": "",
"refresh rates may cause stress": "",
"or damage to your display! ": "",
"Proceed at your own risk!": "",
"Max Handheld Display": "",
"Max Handheld Display Hz": "",
"Display Clock": "",
" Adjust the display voltage": "",
"with caution to avoid damage": "",
"to your display panel! ": "",
"Display Voltage": "",
"Thermal Throttle Limit": "",
"Official Rating": "",
"TDP Threshold": "",
"Power": "",
"HP Mode": "",
"DVB Shift": "",
"SoC Max Volt": "",
"Step Mode": "",
"RAM VDD2 Voltage": "",
"RAM VDDQ Voltage": "",
"Voltage": "",
"RAM Frequency Editor": "",
"Ram Max Clock": "",
"RAM Latency Editor": "",
"RAM Timing Reductions": "",
"Memory Timings": "",
"Advanced": "",
"t6 tRTW Fine Tune": "",
"tRTW Fine Tune": "",
"t7 tWTR Fine Tune": "",
"tWTR Fine Tune": "",
"Memory Latencies": "",
"Read Latency": "",
"Write Latency": "",
"High speedo needed!": "",
"3333MHz (Needs extreme Speedo/PLL)": "",
"3366MHz (Needs extreme Speedo/PLL)": "",
"3400MHz (Needs extreme Speedo/PLL)": "",
"3433MHz (Needs ridiculous Speedo/PLL)": "",
"3466MHz (Needs ridiculous Speedo/PLL)": "",
"3500MHz (Needs ridiculous Speedo/PLL)": "",
"JEDEC.": "",
"CPU Boost Clock": "",
"CPU UV": "",
"CPU Unlock": "",
"CPU VMIN": "",
"CPU Max Voltage": "",
"CPU Max Clock": "",
"Extreme UV Table": "",
"CPU UV Table": "",
"CPU Low UV": "",
"CPU High UV": "",
"CPU Low VMIN": "",
"CPU High VMIN": "",
"No Undervolt": "",
"SLT Table": "",
"HiOPT Table": "",
"GPU Undervolt Table": "",
"GPU Minimum Voltage": "",
"Calculate GPU Vmin": "",
"GPU VMIN": "",
"GPU Maximum Voltage": "",
"GPU Voltage Offset": "",
"GPU DVFS Mode": "",
"GPU DVFS Offset": "",
"GPU Voltage Table": "",
"GPU Custom Table (mV)": "",
"Official Service": "",
"96.6% limit": "",
"99.7% limit": "",
" Setting GPU Clocks past": "",
"1228MHz without a proper undervolt": "",
"can cause degradation or damage": "",
"to your console!": "",
"1075MHz without UV, 1152MHz on SLT": "",
"or 1228MHz on HiOPT can cause ": "",
"permanent damage to your Switch!": "",
"921MHz without UV and 960MHz on": "",
"SLT or HiOPT can cause ": "",
"Default (Mariko)": "",
"Default (Erista)": "",
"Rating": "",
"Safe Max (Mariko)": "",
"Safe Max (Erista)": "",
"Voltages": "",
"RAM Voltage:": "",
"Display Voltage:": "",
"Temperatures": "",
"PLLX Temp:": "",
"AOTAG Temp:": "",
"BQ24193 Temp:": "",
"Normal": "",
"Warm": "",
"Hot": "",
"Overheat": "",
"Not Patched": "",
"Invalid": "",
"RAM Bandwidth": "",
"RAM BW (Peak):": "",
"RAM BW (All):": "",
"RAM BW (CPU):": "",
"RAM BW (GPU):": "",
"Hardware Info": "",
"Console Type:": "",
"Speedo:": "",
"DRAM Module: ": "",
"Software Info": "",
"KIP version:": "",
"sys-dock status:": "",
"SaltyNX status:": "",
"RR Display status:": "",
"Wafer Position:": "",
"IDDQ:": "",
"Module: ": "",
"Board": "",
"Display": "",
"Developers": "",
"Contributors": "",
"Testers": "",
"Translators": "",
"Special Thanks": "",
"X: %u Y: %u": "",
"%u.%u%u mV": "",
"Compiling with minimal features": "",
}

View File

@@ -1,52 +1,42 @@
{ {
"Information": "Інформація", "Information": "Інформація",
"IDDQ:": "IDDQ:",
"Module: ": "Модуль:",
"sys-dock status:": "стан sys-dock:",
"SaltyNX status:": "Статус SaltyNX:",
"RR Display status:": "Статус дисплея RR:",
"Wafer Position:": "Позиція пластини:",
"Credits": "Кредити",
"Developers": "Розробники",
"Contributors": "Дописувачі",
"Testers": "Тестери",
"Special Thanks": "Особлива подяка",
"Unknown": "Невідомий", "Unknown": "Невідомий",
"Installed": "встановлено", "Installed": "встановлено",
"Not Installed": "Не встановлено", "Not Installed": "Не встановлено",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "ЛІЦЕНЗІЯ НА ПИВНИЙ ПОСУД",
"Default": "За замовчуванням", "Default": "За замовчуванням",
"Do Not Override": "Не перевизначати", "Do Not Override": "Не перевизначати",
"Do not override": "Не перевизначати",
"Disabled": "Вимкнено", "Disabled": "Вимкнено",
"Enabled": "Увімкнено", "Enabled": "Увімкнено",
" \\ue0e3 Reset": "\\ue0e3 Скидання", "Enabled (Default)": "Увімкнено (за замовчуванням)",
"Display": "Дисплей", "Enable": "Увімкнути",
"Application changed\\n\\n": "Додаток змінено\\n\\n", "Fatal error": "Фатальна помилка",
"The running application changed\\n\\n": "Запущена програма змінена\\n\\n",
"while editing was going on.": "поки йшло редагування.",
"Board": "дошка",
"%u.%u%u mV": "%u.%u%u мВ",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Не вдалося підключитися до системного модуля hoc-clk.\\n\\n", "Could not connect to hoc-clk sysmodule.\\n\\n": "Не вдалося підключитися до системного модуля hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Переконайтеся, що все\\n\\n", "Please make sure everything is\\n\\n": "Переконайтеся, що все\\n\\n",
"correctly installed and enabled.": "правильно встановлено та включено.", "correctly installed and enabled.": "правильно встановлено та включено.",
"Fatal error": "Фатальна помилка",
"Edit App Profile": "Редагувати профіль програми",
"Edit Global Profile": "Редагувати глобальний профіль",
"Temporary Overrides": "Тимчасові перевизначення",
"Temporary Overrides ": "Тимчасові перевизначення", "Temporary Overrides ": "Тимчасові перевизначення",
"  Reset": " Скидання",
"Settings": "Налаштування",
"About": "про",
"Credits": "Кредити",
"Application changed\\n\\n": "Додаток змінено\\n\\n",
"The running application changed\\n\\n": "Запущена програма змінена\\n\\n",
"while editing was going on.": "поки йшло редагування.",
"Sleep Mode": "Режим сну", "Sleep Mode": "Режим сну",
"Stock": "Запас", "Stock": "Стандарт",
"Dev OC": "Розробник OC", "Dev OC": "Розробник OC",
"Boost Mode": "Режим посилення", "Boost Mode": "Режим посилення",
"Safe Max": "Безпечний макс", "Safe Max": "Безпечний макс",
"Unsafe Max": "Небезпечний макс", "Unsafe Max": "Небезпечний макс",
"Absolute Max": "Абсолютний макс", "Absolute Max": "Абсолютний макс",
"Handheld Safe Max": "Портативний сейф Макс", "Handheld Safe Max": "Портативний безпечний макс",
"Enable": "Увімкнути",
"Edit App Profile": "Редагувати профіль програми",
"Edit Global Profile": "Редагувати глобальний профіль",
"Temporary Overrides": "Тимчасові перевизначення",
"Settings": "Налаштування",
"About": "про",
"Compiling with minimal features": "Компіляція з мінімальними можливостями",
"General Settings": "Загальні налаштування", "General Settings": "Загальні налаштування",
"Governor Settings": "Налаштування губернатора", "Governor Settings": "Налаштування губернатора",
"Safety Settings": "Налаштування безпеки", "Safety Settings": "Налаштування безпеки",
@@ -55,41 +45,64 @@
"CPU Settings": "Налаштування ЦП", "CPU Settings": "Налаштування ЦП",
"GPU Settings": "Налаштування GPU", "GPU Settings": "Налаштування GPU",
"Display Settings": "Налаштування дисплея", "Display Settings": "Налаштування дисплея",
"Experimental Settings": "Експериментальні налаштування",
"Experimental": "Експериментальний", "Experimental": "Експериментальний",
" Settings marked in blue": "Налаштування, позначені синім",
"don't require a reboot to apply!": "не потребують перезавантаження!",
"You can also press  to show": "Також натисніть  для показу",
"information about each setting.": "інформацію про кожне налаштування.",
" Experimental Settings are incomplete ": "Експериментальні налаштування неповні",
"and may not work correctly or at all!": "і можуть взагалі не працювати!",
"Here be dragons!": "Тут є дракони!",
"RAM Voltage Display Mode": "Режим відображення напруги RAM",
"RAM Display Unit": "Одиниця відображення RAM",
"Polling Interval": "Інтервал опитування",
"GPU Scheduling Override Method": "Метод перевизначення планування GPU", "GPU Scheduling Override Method": "Метод перевизначення планування GPU",
"GPU Scheduling Override": "Перевизначення планування GPU",
"GPU Boot Volt": "Напруга завантаження GPU",
"GPU Boot Voltage": "Напруга завантаження GPU",
"Memory Frequency Measurement Mode": "Режим вимірювання частоти пам'яті",
" Overriding the charge current": "Перевизначення струму заряду",
"can be dangerous and may cause": "може бути небезпечним і може спричинити", "can be dangerous and may cause": "може бути небезпечним і може спричинити",
"damage to your battery or charger!": "пошкодження акумулятора або зарядного пристрою!", "damage to your battery or charger!": "пошкодження акумулятора або зарядного пристрою!",
"Charge Current Override": "Перевизначення струму заряду", "Charge Current Override": "Перевизначення струму заряду",
"RAM Voltage Display Mode": "Режим відображення напруги RAM", "Display Color Preset": "Кольоровий пресет дисплея",
"Polling Interval": "Інтервал опитування", "Basic": "Базовий",
"Saturated": "Насичений",
"Washed": "Блідий",
"Natural": "Природний",
"Vivid": "Яскравий",
"CPU Governor Minimum Frequency": "Мінімальна частота регулятора ЦП", "CPU Governor Minimum Frequency": "Мінімальна частота регулятора ЦП",
" Usage of unsafe display": "Використання небезпечних частот екрана",
"refresh rates may cause stress": "частоти оновлення можуть викликати стрес", "refresh rates may cause stress": "частоти оновлення можуть викликати стрес",
"or damage to your display! ": "або пошкодження дисплея!", "or damage to your display! ": "або пошкодження дисплея!",
"Proceed at your own risk!": "Продовжуйте на свій страх і ризик!", "Proceed at your own risk!": "Продовжуйте на свій страх і ризик!",
"Max Handheld Display": "Максимальний портативний дисплей", "Max Handheld Display": "Максимальний портативний дисплей",
"Max Handheld Display Hz": "Макс. Гц в портативному режимі",
"Display Clock": "Відображення годинника", "Display Clock": "Відображення годинника",
" Adjust the display voltage": "Налаштуйте напругу дисплея",
"with caution to avoid damage": "обережно, щоб уникнути пошкоджень",
"to your display panel! ": "до панелі дисплея!",
"Display Voltage": "Напруга дисплея",
"Thermal Throttle Limit": "Термічний дросельний ліміт",
"Official Rating": "Офіційний рейтинг", "Official Rating": "Офіційний рейтинг",
"TDP Threshold": "Поріг TDP", "TDP Threshold": "Поріг TDP",
"Power": "потужність", "Power": "потужність",
"Thermal Throttle Limit": "Термічний дросельний ліміт",
"HP Mode": "Режим HP", "HP Mode": "Режим HP",
"Default (Mariko)": "За замовчуванням (Маріко)",
"Default (Erista)": "За замовчуванням (Erista)", "DVB Shift": "DVB зсув",
"Rating": "Рейтинг", "SoC Max Volt": "Макс. напруга SoC",
"Safe Max (Mariko)": "Сейф Макс (Маріко)", "Step Mode": "Покроковий режим",
"Safe Max (Erista)": "Сейф Макс (Еріста)",
"RAM VDD2 Voltage": "Напруга RAM VDD2", "RAM VDD2 Voltage": "Напруга RAM VDD2",
"Voltage": "Напруга",
"RAM VDDQ Voltage": "Напруга RAM VDDQ", "RAM VDDQ Voltage": "Напруга RAM VDDQ",
"Voltage": "Напруга",
"RAM Frequency Editor": "Редактор частоти оперативної пам'яті", "RAM Frequency Editor": "Редактор частоти оперативної пам'яті",
"JEDEC.": "JEDEC.",
"High speedo needed!": "Потрібна висока швидкість!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 МГц (потрібна екстремальна швидкість/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 МГц (потрібна екстремальна швидкість/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 МГц (потрібна екстремальна швидкість/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 МГц (потрібен смішний Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 МГц (потрібен смішний Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 МГц (потрібен смішний Speedo/PLL)",
"Ram Max Clock": "Годинник Ram Max", "Ram Max Clock": "Годинник Ram Max",
"RAM Latency Editor": "Редактор затримки оперативної пам'яті", "RAM Latency Editor": "Редактор затримки оперативної пам'яті",
"RAM Timing Reductions": "Скорочення оперативної пам'яті", "RAM Timing Reductions": "Скорочення оперативної пам'яті",
@@ -100,20 +113,30 @@
"t7 tWTR Fine Tune": "t7 tWTR Точне налаштування", "t7 tWTR Fine Tune": "t7 tWTR Точне налаштування",
"tWTR Fine Tune": "Точна настройка tWTR", "tWTR Fine Tune": "Точна настройка tWTR",
"Memory Latencies": "Затримки пам'яті", "Memory Latencies": "Затримки пам'яті",
"Read Latency": "Прочитати затримку", "Read Latency": "Затримка читання",
"Write Latency": "Затримка запису", "Write Latency": "Затримка запису",
"High speedo needed!": "Потрібна висока швидкість Speedo!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 МГц (потрібна екстремальна швидкість/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 МГц (потрібна екстремальна швидкість/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 МГц (потрібна екстремальна швидкість/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 МГц (потрібен смішний Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 МГц (потрібен смішний Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 МГц (потрібен смішний Speedo/PLL)",
"JEDEC.": "JEDEC.",
"CPU Boost Clock": "CPU Boost Clock", "CPU Boost Clock": "CPU Boost Clock",
"CPU UV": "CPU UV", "CPU UV": "CPU UV",
"CPU Unlock": "Розблокування ЦП", "CPU Unlock": "Розблокування ЦП",
"CPU VMIN": "CPU VMIN", "CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "Максимальна напруга ЦП", "CPU Max Voltage": "Максимальна напруга ЦП",
"CPU Max Clock": "Максимальна частота ЦП", "CPU Max Clock": "Максимальна частота ЦП",
"Extreme UV Table": "Екстремальний ультрафіолетовий стіл", "Extreme UV Table": "Екстремальна UV таблиця",
"CPU UV Table": "CPU UV Таблиця", "CPU UV Table": "CPU UV Таблиця",
"CPU Low UV": "CPU Low UV", "CPU Low UV": "CPU Low UV",
"CPU High UV": "CPU High UV", "CPU High UV": "CPU High UV",
"CPU Low VMIN": "CPU Low VMIN", "CPU Low VMIN": "CPU Low VMIN",
"CPU High VMIN": "CPU High VMIN", "CPU High VMIN": "CPU High VMIN",
"No Undervolt": "Без андервольта", "No Undervolt": "Без андервольта",
"SLT Table": "Таблиця SLT", "SLT Table": "Таблиця SLT",
"HiOPT Table": "Таблиця HiOPT", "HiOPT Table": "Таблиця HiOPT",
@@ -123,19 +146,70 @@
"GPU VMIN": "GPU VMIN", "GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "Максимальна напруга GPU", "GPU Maximum Voltage": "Максимальна напруга GPU",
"GPU Voltage Offset": "Зсув напруги GPU", "GPU Voltage Offset": "Зсув напруги GPU",
"Do not override": "Не перевизначати",
"Enabled (Default)": "Увімкнено (за замовчуванням)",
"96.6% limit": "96,6% обмеження",
"99.7% limit": "Обмеження 99,7%.",
"GPU Scheduling Override": "Перевизначення планування GPU",
"Official Service": "Офіційний сервіс",
"GPU DVFS Mode": "Режим GPU DVFS", "GPU DVFS Mode": "Режим GPU DVFS",
"GPU DVFS Offset": "GPU DVFS Offset", "GPU DVFS Offset": "GPU DVFS Offset",
"GPU Voltage Table": "Таблиця напруги GPU", "GPU Voltage Table": "Таблиця напруги GPU",
"GPU Custom Table (mV)": "Спеціальна таблиця GPU (мВ)", "GPU Custom Table (mV)": "Спеціальна таблиця GPU (мВ)",
"Official Service": "Офіційний сервіс",
"96.6% limit": "96,6% обмеження",
"99.7% limit": "99,7% обмеження",
" Setting GPU Clocks past": "Встановлення тактових частот GPU вище",
"1228MHz without a proper undervolt": "1228 МГц без належного підвольту",
"can cause degradation or damage": "може спричинити деградацію або пошкодження",
"to your console!": "вашій консолі!",
"1075MHz without UV, 1152MHz on SLT": "1075 МГц без УФ, 1152 МГц на SLT", "1075MHz without UV, 1152MHz on SLT": "1075 МГц без УФ, 1152 МГц на SLT",
"or 1228MHz on HiOPT can cause ": "або 1228 МГц на HiOPT може спричинити", "or 1228MHz on HiOPT can cause ": "або 1228 МГц на HiOPT може спричинити",
"permanent damage to your Switch!": "незворотне пошкодження вашого комутатора!", "permanent damage to your Switch!": "незворотне пошкодження вашого Switch!",
"921MHz without UV and 960MHz on": "921 МГц без УФ і 960 МГц увімкнено", "921MHz without UV and 960MHz on": "921 МГц без УФ і 960 МГц увімкнено",
"SLT or HiOPT can cause ": "SLT або HiOPT можуть спричинити" "SLT or HiOPT can cause ": "SLT або HiOPT можуть спричинити",
"Default (Mariko)": "За замовчуванням (Маріко)",
"Default (Erista)": "За замовчуванням (Erista)",
"Rating": "Рейтинг",
"Safe Max (Mariko)": "Сейф Макс (Маріко)",
"Safe Max (Erista)": "Сейф Макс (Еріста)",
"Voltages": "Напруги",
"RAM Voltage:": "Напруга RAM:",
"Display Voltage:": "Напруга дисплея:",
"Temperatures": "Температури",
"PLLX Temp:": "PLLX Темп.:",
"AOTAG Temp:": "AOTAG Темп.:",
"BQ24193 Temp:": "BQ24193 Темп.:",
"Normal": "Нормально",
"Warm": "Тепло",
"Hot": "Гаряче",
"Overheat": "Перегрів",
"Not Patched": "Не виправлено",
"Invalid": "Недійсний",
"RAM Bandwidth": "Пропускна здатність RAM",
"RAM BW (Peak):": "BW RAM (Пік):",
"RAM BW (All):": "BW RAM (Усі):",
"RAM BW (CPU):": "BW RAM (CPU):",
"RAM BW (GPU):": "BW RAM (GPU):",
"Hardware Info": "Інфо про апаратне забезпечення",
"Console Type:": "Тип консолі:",
"Speedo:": "Speedo:",
"DRAM Module: ": "Модуль DRAM: ",
"Software Info": "Інфо про програмне забезпечення",
"KIP version:": "Версія KIP:",
"sys-dock status:": "стан sys-dock:",
"SaltyNX status:": "Статус SaltyNX:",
"RR Display status:": "Статус дисплея RR:",
"Wafer Position:": "Позиція пластини:",
"IDDQ:": "IDDQ:",
"Module: ": "Модуль:",
"Board": "дошка",
"Display": "Дисплей",
"Developers": "Розробники",
"Contributors": "Дописувачі",
"Testers": "Тестери",
"Translators": "Перекладачі",
"Special Thanks": "Особлива подяка",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%u мВ",
"Compiling with minimal features": "Компіляція з мінімальними можливостями",
"THE BEER-WARE LICENSE": "ЛІЦЕНЗІЯ НА ПИВНИЙ ПОСУД"
} }

View File

@@ -1,37 +1,33 @@
{ {
"Information": "信息", "Information": "信息",
"IDDQ:": "IDDQ:",
"Module: ": "模块: ",
"sys-dock status:": "sys-dock 状态:",
"SaltyNX status:": "SaltyNX 状态:",
"RR Display status:": "RR 显示状态:",
"Wafer Position:": "晶圆位置:",
"Credits": "致谢",
"Developers": "开发者",
"Contributors": "贡献者",
"Testers": "测试者",
"Special Thanks": "特别感谢",
"Unknown": "未知", "Unknown": "未知",
"Installed": "已安装", "Installed": "已安装",
"Not Installed": "未安装", "Not Installed": "未安装",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "啤酒软件许可协议",
"Default": "默认", "Default": "默认",
"Do Not Override": "不修改", "Do Not Override": "不修改",
"Do not override": "不修改",
"Disabled": "已禁用", "Disabled": "已禁用",
"Enabled": "已启用", "Enabled": "已启用",
" \\ue0e3 Reset": " \\ue0e3 重置", "Enabled (Default)": "已启用 (默认)",
"Display": "显示", "Enable": "启用",
"Application changed\\n\\n": "应用已变更\\n\\n", "Fatal error": "致命错误",
"The running application changed\\n\\n": "正在运行的应用已变更\\n\\n",
"while editing was going on.": "编辑过程中发生变更。",
"Board": "主板",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "无法连接到 hoc-clk 系统模块。\\n\\n", "Could not connect to hoc-clk sysmodule.\\n\\n": "无法连接到 hoc-clk 系统模块。\\n\\n",
"Please make sure everything is\\n\\n": "请确保所有内容均已\\n\\n", "Please make sure everything is\\n\\n": "请确保所有内容均已\\n\\n",
"correctly installed and enabled.": "正确安装并启用。", "correctly installed and enabled.": "正确安装并启用。",
"Fatal error": "致命错误",
"Edit App Profile": "编辑应用配置",
"Edit Global Profile": "编辑全局配置",
"Temporary Overrides": "临时配置",
"Temporary Overrides ": "临时配置 ", "Temporary Overrides ": "临时配置 ",
"  Reset": " 重置",
"Settings": "设置",
"About": "关于",
"Credits": "致谢",
"Application changed\\n\\n": "应用已变更\\n\\n",
"The running application changed\\n\\n": "正在运行的应用已变更\\n\\n",
"while editing was going on.": "编辑过程中发生变更。",
"Sleep Mode": "睡眠模式", "Sleep Mode": "睡眠模式",
"Stock": "原厂默认", "Stock": "原厂默认",
"Dev OC": "开发者超频", "Dev OC": "开发者超频",
@@ -40,13 +36,7 @@
"Unsafe Max": "危险最大值", "Unsafe Max": "危险最大值",
"Absolute Max": "绝对最大值", "Absolute Max": "绝对最大值",
"Handheld Safe Max": "掌机模式安全最大值", "Handheld Safe Max": "掌机模式安全最大值",
"Enable": "启用",
"Edit App Profile": "编辑应用配置",
"Edit Global Profile": "编辑全局配置",
"Temporary Overrides": "临时配置",
"Settings": "设置",
"About": "关于",
"Compiling with minimal features": "以最小功能编译",
"General Settings": "通用设置", "General Settings": "通用设置",
"Governor Settings": "调频器设置", "Governor Settings": "调频器设置",
"Safety Settings": "安全设置", "Safety Settings": "安全设置",
@@ -55,61 +45,69 @@
"CPU Settings": "CPU 设置", "CPU Settings": "CPU 设置",
"GPU Settings": "GPU 设置", "GPU Settings": "GPU 设置",
"Display Settings": "显示设置", "Display Settings": "显示设置",
"Experimental Settings": "实验性设置",
"Experimental": "实验性功能", "Experimental": "实验性功能",
" Settings marked in blue": "蓝色标注的设置",
"don't require a reboot to apply!": "无需重启即可应用!",
"You can also press  to show": "也可按  查看",
"information about each setting.": "每项设置的说明。",
" Experimental Settings are incomplete ": "实验性设置尚未完成",
"and may not work correctly or at all!": "且可能无法正常工作!",
"Here be dragons!": "此处有险!",
"RAM Voltage Display Mode": "内存电压显示模式",
"RAM Display Unit": "内存显示单位",
"Polling Interval": "刷新间隔",
"GPU Scheduling Override Method": "GPU 调度覆盖方式", "GPU Scheduling Override Method": "GPU 调度覆盖方式",
"GPU Scheduling Override": "GPU 调度修改",
"GPU Boot Volt": "GPU 启动电压",
"GPU Boot Voltage": "GPU 启动电压",
"Memory Frequency Measurement Mode": "内存频率测量模式",
" Overriding the charge current": "修改充电电流",
"can be dangerous and may cause": "存在风险,可能导致", "can be dangerous and may cause": "存在风险,可能导致",
"damage to your battery or charger!": "电池或充电器损坏!", "damage to your battery or charger!": "电池或充电器损坏!",
"Charge Current Override": "充电电流修改", "Charge Current Override": "充电电流修改",
"RAM Voltage Display Mode": "内存电压显示模式", "Display Color Preset": "显示颜色预设",
"Polling Interval": "刷新间隔", "Basic": "基础",
"Saturated": "饱和",
"Washed": "淡色",
"Natural": "自然",
"Vivid": "鲜艳",
"CPU Governor Minimum Frequency": "CPU 调频器最低频率", "CPU Governor Minimum Frequency": "CPU 调频器最低频率",
"\uE150 Usage of unsafe display": "\uE150 不安全的显示屏", " Usage of unsafe display": "不安全的显示屏",
"refresh rates may cause stress": "刷新率可能会对", "refresh rates may cause stress": "刷新率可能会对",
"or damage to your display! ": "显示屏造成压力或损坏! ", "or damage to your display! ": "显示屏造成压力或损坏! ",
"Proceed at your own risk!": "操作风险自负!", "Proceed at your own risk!": "操作风险自负!",
"Max Handheld Display": "掌机模式最大显示率", "Max Handheld Display": "掌机模式最大显示率",
"Max Handheld Display Hz": "掌机最大显示率 Hz",
"Display Clock": "显示时钟", "Display Clock": "显示时钟",
" Adjust the display voltage": "调整显示电压",
"with caution to avoid damage": "请谨慎以避免损坏",
"to your display panel! ": "显示屏面板!",
"Display Voltage": "显示电压",
"Thermal Throttle Limit": "温控设置",
"Official Rating": "官方额定值", "Official Rating": "官方额定值",
"TDP Threshold": "TDP 阈值", "TDP Threshold": "TDP 阈值",
"Power": "电源", "Power": "电源",
"Thermal Throttle Limit": "温控设置",
"HP Mode": "高性能模式", "HP Mode": "高性能模式",
"Default (Mariko)": "默认 (Mariko)",
"Default (Erista)": "默认 (Erista)", "DVB Shift": "DVB 偏移",
"Rating": "额定值", "SoC Max Volt": "SoC 最大电压",
"Safe Max (Mariko)": "安全最大值 (Mariko)", "Step Mode": "步进模式",
"Safe Max (Erista)": "安全最大值 (Erista)",
"RAM VDD2 Voltage": "内存 VDD2 电压", "RAM VDD2 Voltage": "内存 VDD2 电压",
"Voltage": "电压",
"RAM VDDQ Voltage": "内存 VDDQ 电压", "RAM VDDQ Voltage": "内存 VDDQ 电压",
"Voltage": "电压",
"RAM Frequency Editor": "内存频率编辑器", "RAM Frequency Editor": "内存频率编辑器",
"JEDEC.": "JEDEC 标准。",
"High speedo needed!": "需要高 Speedo 配置!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (需要极限 Speedo/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (需要极限 Speedo/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (需要极限 Speedo/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (需要极端 Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (需要极端 Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (需要极端 Speedo/PLL)",
"Ram Max Clock": "内存最大频率", "Ram Max Clock": "内存最大频率",
"RAM Latency Editor": "内存延迟编辑器", "RAM Latency Editor": "内存延迟编辑器",
"RAM Timing Reductions": "内存时序优化", "RAM Timing Reductions": "内存时序优化",
"Memory Timings": "内存时序", "Memory Timings": "内存时序",
"Memory": "内存",
"mem": "内存",
"Governor": "调频器",
"Advanced": "高级", "Advanced": "高级",
"Docked": "底座模式",
"Handheld": "掌机模式",
"Charging": "充电中",
"USB Charger": "USB 充电器",
"PD Charger": "PD 充电器",
"Handheld TDP": "掌机模式功耗限制",
"Thermal Throttle": "温度控制",
"Uncapped Clocks": "解除频率上限",
"Soc DVB Shift": "SoC DVB偏移",
"Overwrite Boost Mode": "接管官方CPU调度",
"Display Refresh Rate Changing": "显示刷新率变更",
"t6 tRTW Fine Tune": "t6 tRTW 微调", "t6 tRTW Fine Tune": "t6 tRTW 微调",
"tRTW Fine Tune": "tRTW 微调", "tRTW Fine Tune": "tRTW 微调",
"t7 tWTR Fine Tune": "t7 tWTR 微调", "t7 tWTR Fine Tune": "t7 tWTR 微调",
@@ -117,6 +115,15 @@
"Memory Latencies": "内存延迟", "Memory Latencies": "内存延迟",
"Read Latency": "读取延迟", "Read Latency": "读取延迟",
"Write Latency": "写入延迟", "Write Latency": "写入延迟",
"High speedo needed!": "需要高 Speedo 配置!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (需要极限 Speedo/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (需要极限 Speedo/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (需要极限 Speedo/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (需要极端 Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (需要极端 Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (需要极端 Speedo/PLL)",
"JEDEC.": "JEDEC 标准。",
"CPU Boost Clock": "CPU 超频频率", "CPU Boost Clock": "CPU 超频频率",
"CPU UV": "CPU 降压", "CPU UV": "CPU 降压",
"CPU Unlock": "CPU 解锁", "CPU Unlock": "CPU 解锁",
@@ -129,6 +136,7 @@
"CPU High UV": "CPU 高压降压", "CPU High UV": "CPU 高压降压",
"CPU Low VMIN": "CPU 低压最低电压", "CPU Low VMIN": "CPU 低压最低电压",
"CPU High VMIN": "CPU 高压最低电压", "CPU High VMIN": "CPU 高压最低电压",
"No Undervolt": "不降压", "No Undervolt": "不降压",
"SLT Table": "SLT 表", "SLT Table": "SLT 表",
"HiOPT Table": "HiOPT 表", "HiOPT Table": "HiOPT 表",
@@ -138,20 +146,70 @@
"GPU VMIN": "GPU 最低电压", "GPU VMIN": "GPU 最低电压",
"GPU Maximum Voltage": "GPU 最大电压", "GPU Maximum Voltage": "GPU 最大电压",
"GPU Voltage Offset": "GPU 电压偏移", "GPU Voltage Offset": "GPU 电压偏移",
"Do not override": "不修改",
"Enabled (Default)": "已启用 (默认)",
"96.6% limit": "96.6% 限制",
"99.7% limit": "99.7% 限制",
"GPU Scheduling Override": "GPU 调度修改",
"Official Service": "官方服务",
"GPU DVFS Mode": "GPU DVFS 模式", "GPU DVFS Mode": "GPU DVFS 模式",
"GPU DVFS Offset": "GPU DVFS 偏移", "GPU DVFS Offset": "GPU DVFS 偏移",
"GPU Voltage Table": "GPU 电压表", "GPU Voltage Table": "GPU 电压表",
"GPU Custom Table (mV)": "GPU 自定义表 (mV)", "GPU Custom Table (mV)": "GPU 自定义表 (mV)",
"\uE150 Setting GPU Clocks past": "\uE150 将 GPU 频率设置超过", "Official Service": "官方服务",
"96.6% limit": "96.6% 限制",
"99.7% limit": "99.7% 限制",
" Setting GPU Clocks past": " 将 GPU 频率设置超过",
"1228MHz without a proper undervolt": "没有适当降压的 1228MHz",
"can cause degradation or damage": "可能导致损耗或损坏",
"to your console!": "您的主机!",
"1075MHz without UV, 1152MHz on SLT": "1075MHz 无降压SLT 表下 1152MHz", "1075MHz without UV, 1152MHz on SLT": "1075MHz 无降压SLT 表下 1152MHz",
"or 1228MHz on HiOPT can cause ": "或 HiOPT 表下 1228MHz 可能导致 ", "or 1228MHz on HiOPT can cause ": "或 HiOPT 表下 1228MHz 可能导致 ",
"permanent damage to your Switch!": "Switch 永久损坏!", "permanent damage to your Switch!": "Switch 永久损坏!",
"921MHz without UV and 960MHz on": "921MHz 无降压SLT/HiOPT 表下 960MHz", "921MHz without UV and 960MHz on": "921MHz 无降压SLT/HiOPT 表下 960MHz",
"SLT or HiOPT can cause ": "可能导致 " "SLT or HiOPT can cause ": "可能导致 ",
"Default (Mariko)": "默认 (Mariko)",
"Default (Erista)": "默认 (Erista)",
"Rating": "额定值",
"Safe Max (Mariko)": "安全最大值 (Mariko)",
"Safe Max (Erista)": "安全最大值 (Erista)",
"Voltages": "电压",
"RAM Voltage:": "内存电压:",
"Display Voltage:": "显示电压:",
"Temperatures": "温度",
"PLLX Temp:": "PLLX 温度:",
"AOTAG Temp:": "AOTAG 温度:",
"BQ24193 Temp:": "BQ24193 温度:",
"Normal": "正常",
"Warm": "温热",
"Hot": "过热",
"Overheat": "严重过热",
"Not Patched": "未修补",
"Invalid": "无效",
"RAM Bandwidth": "内存带宽",
"RAM BW (Peak):": "RAM带宽(峰值):",
"RAM BW (All):": "RAM带宽(全部):",
"RAM BW (CPU):": "RAM带宽(CPU):",
"RAM BW (GPU):": "RAM带宽(GPU):",
"Hardware Info": "硬件信息",
"Console Type:": "主机类型:",
"Speedo:": "Speedo:",
"DRAM Module: ": "DRAM 模块: ",
"Software Info": "软件信息",
"KIP version:": "KIP 版本:",
"sys-dock status:": "sys-dock 状态:",
"SaltyNX status:": "SaltyNX 状态:",
"RR Display status:": "RR 显示状态:",
"Wafer Position:": "晶圆位置:",
"IDDQ:": "IDDQ:",
"Module: ": "模块: ",
"Board": "主板",
"Display": "显示",
"Developers": "开发者",
"Contributors": "贡献者",
"Testers": "测试者",
"Translators": "翻译",
"Special Thanks": "特别感谢",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%u mV",
"Compiling with minimal features": "以最小功能编译",
"THE BEER-WARE LICENSE": "啤酒软件许可协议"
} }

View File

@@ -1,52 +1,42 @@
{ {
"Information": "資訊", "Information": "資訊",
"IDDQ:": "國際電話號碼:",
"Module: ": "模組:",
"sys-dock status:": "系統塢站狀態:",
"SaltyNX status:": "SaltyNX 狀態:",
"RR Display status:": "RR 顯示狀態:",
"Wafer Position:": "晶圓位置:",
"Credits": "製作人員",
"Developers": "開發商",
"Contributors": "貢獻者",
"Testers": "測試人員",
"Special Thanks": "特別感謝",
"Unknown": "未知", "Unknown": "未知",
"Installed": "已安裝", "Installed": "已安裝",
"Not Installed": "未安裝", "Not Installed": "未安裝",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "啤酒製品許可證",
"Default": "預設", "Default": "預設",
"Do Not Override": "不要覆蓋", "Do Not Override": "不要覆蓋",
"Disabled": "殘障人士", "Do not override": "不要覆蓋",
"Enabled": "用", "Disabled": "已停用",
" \\ue0e3 Reset": "\\ue0e3 重設", "Enabled": "已啟用",
"Display": "顯示", "Enabled (Default)": "已啟用(預設)",
"Enable": "啟用",
"Fatal error": "致命錯誤",
"Could not connect to hoc-clk sysmodule.\\n\\n": "無法連接到 hoc-clk 系統模組。\\n\\n",
"Please make sure everything is\\n\\n": "請確保一切正常\\n\\n",
"correctly installed and enabled.": "正確安裝並啟用。",
"Edit App Profile": "編輯應用程式設定檔",
"Edit Global Profile": "編輯全域設定檔",
"Temporary Overrides": "臨時覆蓋",
"Temporary Overrides ": "臨時覆蓋",
"  Reset": " 重設",
"Settings": "設定",
"About": "關於",
"Credits": "製作人員",
"Application changed\\n\\n": "應用程式已更改\\n\\n", "Application changed\\n\\n": "應用程式已更改\\n\\n",
"The running application changed\\n\\n": "正在運行的應用程式已更改\\n\\n", "The running application changed\\n\\n": "正在運行的應用程式已更改\\n\\n",
"while editing was going on.": "當編輯正在進行時。", "while editing was going on.": "當編輯正在進行時。",
"Board": "董事會",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "無法連接到 hoc-clk 系統模組。 \\n\\n",
"Please make sure everything is\\n\\n": "請確保一切正常\\n\\n",
"correctly installed and enabled.": "正確安裝並啟用。",
"Fatal error": "致命錯誤",
"Temporary Overrides ": "臨時覆蓋",
"Sleep Mode": "睡眠模式", "Sleep Mode": "睡眠模式",
"Stock": "庫存", "Stock": "原廠預設",
"Dev OC": "開發OC", "Dev OC": "開發OC",
"Boost Mode": "升壓模式", "Boost Mode": "升壓模式",
"Safe Max": "安全最大值", "Safe Max": "安全最大值",
"Unsafe Max": "不安全最大值", "Unsafe Max": "不安全最大值",
"Absolute Max": "絕對最大值", "Absolute Max": "絕對最大值",
"Handheld Safe Max": "手持式安全最大", "Handheld Safe Max": "手持式安全最大",
"Enable": "啟用",
"Edit App Profile": "編輯應用程式設定檔",
"Edit Global Profile": "編輯全域設定檔",
"Temporary Overrides": "臨時覆蓋",
"Settings": "設定",
"About": "關於",
"Compiling with minimal features": "使用最少的功能進行編譯",
"General Settings": "常規設定", "General Settings": "常規設定",
"Governor Settings": "調速器設定", "Governor Settings": "調速器設定",
"Safety Settings": "安全設定", "Safety Settings": "安全設定",
@@ -55,42 +45,65 @@
"CPU Settings": "中央處理器設定", "CPU Settings": "中央處理器設定",
"GPU Settings": "GPU設定", "GPU Settings": "GPU設定",
"Display Settings": "顯示設定", "Display Settings": "顯示設定",
"Experimental Settings": "實驗性設定",
"Experimental": "實驗性的", "Experimental": "實驗性的",
" Settings marked in blue": "藍色標示的設定",
"don't require a reboot to apply!": "無需重開機即可套用!",
"You can also press  to show": "也可按  顯示",
"information about each setting.": "每項設定的說明。",
" Experimental Settings are incomplete ": "實驗性設定尚未完成",
"and may not work correctly or at all!": "且可能無法正常運作!",
"Here be dragons!": "此處有危險!",
"RAM Voltage Display Mode": "RAM電壓顯示模式",
"RAM Display Unit": "記憶體顯示單位",
"Polling Interval": "輪詢間隔",
"GPU Scheduling Override Method": "GPU調度覆蓋方法", "GPU Scheduling Override Method": "GPU調度覆蓋方法",
"GPU Scheduling Override": "GPU 調度覆蓋",
"GPU Boot Volt": "GPU 啟動電壓",
"GPU Boot Voltage": "GPU 啟動電壓",
"Memory Frequency Measurement Mode": "記憶體頻率測量模式",
" Overriding the charge current": "覆蓋充電電流",
"can be dangerous and may cause": "可能很危險並可能導致", "can be dangerous and may cause": "可能很危險並可能導致",
"damage to your battery or charger!": "損壞電池或充電器!", "damage to your battery or charger!": "損壞電池或充電器!",
"Charge Current Override": "充電電流覆蓋", "Charge Current Override": "充電電流覆蓋",
"RAM Voltage Display Mode": "RAM電壓顯示模式", "Display Color Preset": "顯示顏色預設",
"Polling Interval": "輪詢間隔", "Basic": "基本",
"Saturated": "飽和",
"Washed": "淡色",
"Natural": "自然",
"Vivid": "鮮艷",
"CPU Governor Minimum Frequency": "CPU調速器最低頻率", "CPU Governor Minimum Frequency": "CPU調速器最低頻率",
" Usage of unsafe display": "不安全的顯示率",
"refresh rates may cause stress": "刷新率可能會造成壓力", "refresh rates may cause stress": "刷新率可能會造成壓力",
"or damage to your display! ": "或損壞您的顯示器!", "or damage to your display! ": "或損壞您的顯示器!",
"Proceed at your own risk!": "請自行承擔風險!", "Proceed at your own risk!": "請自行承擔風險!",
"Max Handheld Display": "最大手持顯示器", "Max Handheld Display": "最大手持顯示器",
"Max Handheld Display Hz": "最大手持顯示率 Hz",
"Display Clock": "顯示時鐘", "Display Clock": "顯示時鐘",
" Adjust the display voltage": "調整顯示電壓",
"with caution to avoid damage": "請謹慎操作以避免損壞",
"to your display panel! ": "顯示面板!",
"Display Voltage": "顯示電壓",
"Thermal Throttle Limit": "熱油門限制",
"Official Rating": "官方評級", "Official Rating": "官方評級",
"TDP Threshold": "TDP閾值", "TDP Threshold": "TDP閾值",
"Power": "電源", "Power": "電源",
"Thermal Throttle Limit": "熱油門限制", "HP Mode": "高效能模式",
"HP Mode": "惠普模式",
"Default (Mariko)": "預設(真理子)", "DVB Shift": "DVB 偏移",
"Default (Erista)": "預設(埃里斯塔)", "SoC Max Volt": "SoC 最大電壓",
"Rating": "評級", "Step Mode": "步進模式",
"Safe Max (Mariko)": "安全最大(真理子)",
"Safe Max (Erista)": "安全最大(埃里斯塔)",
"RAM VDD2 Voltage": "RAM VDD2 電壓", "RAM VDD2 Voltage": "RAM VDD2 電壓",
"Voltage": "電壓",
"RAM VDDQ Voltage": "RAM VDDQ 電壓", "RAM VDDQ Voltage": "RAM VDDQ 電壓",
"Voltage": "電壓",
"RAM Frequency Editor": "RAM頻率編輯器", "RAM Frequency Editor": "RAM頻率編輯器",
"JEDEC.": "JEDEC。", "Ram Max Clock": "記憶體最大時脈",
"High speedo needed!": "需要高速!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz需要極高的 Speedo/PLL",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz需要極高的 Speedo/PLL",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz需要極高的 Speedo/PLL",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz需要荒謬的 Speedo/PLL",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz需要荒謬的 Speedo/PLL",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz需要荒謬的 Speedo/PLL",
"Ram Max Clock": "記憶體最大時鐘",
"RAM Latency Editor": "RAM 延遲編輯器", "RAM Latency Editor": "RAM 延遲編輯器",
"RAM Timing Reductions": "RAM 時序減少", "RAM Timing Reductions": "RAM 時序減少",
"Memory Timings": "記憶體時序", "Memory Timings": "記憶體時序",
@@ -102,18 +115,28 @@
"Memory Latencies": "記憶體延遲", "Memory Latencies": "記憶體延遲",
"Read Latency": "讀取延遲", "Read Latency": "讀取延遲",
"Write Latency": "寫入延遲", "Write Latency": "寫入延遲",
"CPU Boost Clock": "CPU 升壓時鐘", "High speedo needed!": "需要高 Speedo 值!",
"CPU UV": "中央處理器紫外線", "3333MHz (Needs extreme Speedo/PLL)": "3333MHz需要極高的 Speedo/PLL",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz需要極高的 Speedo/PLL",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz需要極高的 Speedo/PLL",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz需要荒謬的 Speedo/PLL",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz需要荒謬的 Speedo/PLL",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz需要荒謬的 Speedo/PLL",
"JEDEC.": "JEDEC。",
"CPU Boost Clock": "CPU 升壓時脈",
"CPU UV": "CPU 降壓",
"CPU Unlock": "CPU解鎖", "CPU Unlock": "CPU解鎖",
"CPU VMIN": "CPU最低電壓", "CPU VMIN": "CPU 最低電壓",
"CPU Max Voltage": "CPU最大電壓", "CPU Max Voltage": "CPU最大電壓",
"CPU Max Clock": "CPU 最大時脈", "CPU Max Clock": "CPU 最大時脈",
"Extreme UV Table": "極端紫外線表", "Extreme UV Table": "極限降壓表",
"CPU UV Table": "CPU UV表", "CPU UV Table": "CPU 降壓表",
"CPU Low UV": "CPU低紫外線", "CPU Low UV": "CPU 低壓降壓",
"CPU High UV": "CPU高紫外線", "CPU High UV": "CPU 高壓降壓",
"CPU Low VMIN": "CPU 低 VMIN", "CPU Low VMIN": "CPU 低 VMIN",
"CPU High VMIN": "CPU 高 VMIN", "CPU High VMIN": "CPU 高 VMIN",
"No Undervolt": "無欠壓", "No Undervolt": "無欠壓",
"SLT Table": "SLT表", "SLT Table": "SLT表",
"HiOPT Table": "HiOPT表", "HiOPT Table": "HiOPT表",
@@ -123,19 +146,70 @@
"GPU VMIN": "GPU VMIN", "GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "GPU最大電壓", "GPU Maximum Voltage": "GPU最大電壓",
"GPU Voltage Offset": "GPU電壓偏移", "GPU Voltage Offset": "GPU電壓偏移",
"Do not override": "不要覆蓋",
"Enabled (Default)": "啟用(預設)",
"96.6% limit": "96.6%限制",
"99.7% limit": "99.7%限制",
"GPU Scheduling Override": "GPU 調度覆蓋",
"Official Service": "官方服務",
"GPU DVFS Mode": "GPU DVFS 模式", "GPU DVFS Mode": "GPU DVFS 模式",
"GPU DVFS Offset": "GPU DVFS 偏移", "GPU DVFS Offset": "GPU DVFS 偏移",
"GPU Voltage Table": "GPU電壓表", "GPU Voltage Table": "GPU電壓表",
"GPU Custom Table (mV)": "GPU 自訂表 (mV)", "GPU Custom Table (mV)": "GPU 自訂表 (mV)",
"Official Service": "官方服務",
"96.6% limit": "96.6%限制",
"99.7% limit": "99.7%限制",
" Setting GPU Clocks past": "將 GPU 頻率設定超過",
"1228MHz without a proper undervolt": "1228MHz 未適當降壓",
"can cause degradation or damage": "可能導致劣化或損壞",
"to your console!": "您的主機!",
"1075MHz without UV, 1152MHz on SLT": "無 UV 時為 1075MHzSLT 時為 1152MHz", "1075MHz without UV, 1152MHz on SLT": "無 UV 時為 1075MHzSLT 時為 1152MHz",
"or 1228MHz on HiOPT can cause ": "或 HiOPT 上的 1228MHz 可能會導致", "or 1228MHz on HiOPT can cause ": "或 HiOPT 上的 1228MHz 可能會導致",
"permanent damage to your Switch!": "對您的 Switch 造成永久性損壞!", "permanent damage to your Switch!": "對您的 Switch 造成永久性損壞!",
"921MHz without UV and 960MHz on": "無 UV 時為 921MHz開啟時為 960MHz", "921MHz without UV and 960MHz on": "無 UV 時為 921MHz開啟時為 960MHz",
"SLT or HiOPT can cause ": "SLT 或 HiOPT 可能會導致" "SLT or HiOPT can cause ": "SLT 或 HiOPT 可能會導致",
"Default (Mariko)": "預設 (Mariko)",
"Default (Erista)": "預設 (Erista)",
"Rating": "評級",
"Safe Max (Mariko)": "安全最大值 (Mariko)",
"Safe Max (Erista)": "安全最大值 (Erista)",
"Voltages": "電壓",
"RAM Voltage:": "記憶體電壓:",
"Display Voltage:": "顯示電壓:",
"Temperatures": "溫度",
"PLLX Temp:": "PLLX 溫度:",
"AOTAG Temp:": "AOTAG 溫度:",
"BQ24193 Temp:": "BQ24193 溫度:",
"Normal": "正常",
"Warm": "溫熱",
"Hot": "過熱",
"Overheat": "嚴重過熱",
"Not Patched": "未修補",
"Invalid": "無效",
"RAM Bandwidth": "記憶體頻寬",
"RAM BW (Peak):": "RAM頻寬(峰值)",
"RAM BW (All):": "RAM頻寬(全部)",
"RAM BW (CPU):": "RAM頻寬(CPU)",
"RAM BW (GPU):": "RAM頻寬(GPU)",
"Hardware Info": "硬體資訊",
"Console Type:": "主機類型:",
"Speedo:": "Speedo",
"DRAM Module: ": "DRAM 模組:",
"Software Info": "軟體資訊",
"KIP version:": "KIP 版本:",
"sys-dock status:": "系統塢站狀態:",
"SaltyNX status:": "SaltyNX 狀態:",
"RR Display status:": "RR 顯示狀態:",
"Wafer Position:": "晶圓位置:",
"IDDQ:": "IDDQ",
"Module: ": "模組:",
"Board": "主板",
"Display": "顯示",
"Developers": "開發商",
"Contributors": "貢獻者",
"Testers": "測試人員",
"Translators": "翻譯",
"Special Thanks": "特別感謝",
"X: %u Y: %u": "X: %u Y: %u",
"%u.%u%u mV": "%u.%u%u mV",
"Compiling with minimal features": "使用最少的功能進行編譯",
"THE BEER-WARE LICENSE": "啤酒製品許可證"
} }

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,17 +24,16 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#pragma once #pragma once
#if defined(__cplusplus) #if defined(__cplusplus)
#include "cpp_util.hpp" #include "cpp_util.hpp"
extern "C" extern "C" {
{
#endif #endif
#include <hocclk.h> #include <hocclk.h>
#include <hocclk/client/ipc.h> #include <hocclk/client/ipc.h>
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,74 +24,62 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#define TESLA_INIT_IMPL #define TESLA_INIT_IMPL
#include <tesla.hpp> #include <tesla.hpp>
#include "ui/gui/fatal_gui.h" #include "ui/gui/fatal_gui.h"
#include "ui/gui/main_gui.h" #include "ui/gui/main_gui.h"
#include "rgltr_services.h" // for extern Service g_rgltrSrv, etc.
class AppOverlay : public tsl::Overlay class AppOverlay : public tsl::Overlay {
{
public: public:
AppOverlay() {} AppOverlay() {
~AppOverlay() {} }
~AppOverlay() {
}
//virtual void initServices() override { // virtual void initServices() override {
// rgltrInitialize(); // rgltrInitialize();
//} // }
virtual void exitServices() override { virtual void exitServices() override {
rgltrExit(); hocclkIpcExit();
hocclkIpcExit(); }
virtual std::unique_ptr<tsl::Gui> loadInitialGui() override {
uint32_t apiVersion;
smInitialize();
tsl::hlp::ScopeGuard smGuard([] { smExit(); });
if (!hocclkIpcRunning()) {
return initially<FatalGui>("hoc-clk is not running.\n\n"
"\n"
"Please make sure it is correctly\n\n"
"installed and enabled.",
"");
} }
virtual std::unique_ptr<tsl::Gui> loadInitialGui() override if (R_FAILED(hocclkIpcInitialize()) || R_FAILED(hocclkIpcGetAPIVersion(&apiVersion))) {
{ return initially<FatalGui>("Could not connect to hoc-clk.\n\n"
uint32_t apiVersion; "\n"
smInitialize(); "Please make sure it is correctly\n\n"
"installed and enabled.",
tsl::hlp::ScopeGuard smGuard([] { smExit(); }); "");
if(!hocclkIpcRunning())
{
return initially<FatalGui>(
"hoc-clk is not running.\n\n"
"\n"
"Please make sure it is correctly\n\n"
"installed and enabled.",
""
);
}
if(R_FAILED(hocclkIpcInitialize()) || R_FAILED(hocclkIpcGetAPIVersion(&apiVersion)))
{
return initially<FatalGui>(
"Could not connect to hoc-clk.\n\n"
"\n"
"Please make sure it is correctly\n\n"
"installed and enabled.",
""
);
}
if(HOCCLK_IPC_API_VERSION != apiVersion)
{
return initially<FatalGui>(
"Overlay not compatible with\n\n"
"the running hoc-clk version.\n\n"
"\n"
"Please make sure everything is\n\n"
"installed and up to date.",
""
);
}
return initially<MainGui>();
} }
if (HOCCLK_IPC_API_VERSION != apiVersion) {
return initially<FatalGui>("Overlay not compatible with\n\n"
"the running hoc-clk version.\n\n"
"\n"
"Please make sure everything is\n\n"
"installed and up to date.",
"");
}
return initially<MainGui>();
}
}; };
int main(int argc, char **argv) int main(int argc, char **argv) {
{
return tsl::loop<AppOverlay>(argc, argv); return tsl::loop<AppOverlay>(argc, argv);
} }

View File

@@ -28,20 +28,21 @@
#pragma once #pragma once
#include <tesla.hpp> #include <tesla.hpp>
#include "../gui/base_gui.h"
class BaseGui;
static constexpr u16 HOC_HEADER_HEIGHT = 287;
// Bottom edge of the drawn box: 106 + TOP_Y_OFFSET(15) + 156 = 277
static constexpr u16 HOC_BOX_BOTTOM = 277;
class BaseFrame : public tsl::elm::HeaderOverlayFrame class BaseFrame : public tsl::elm::HeaderOverlayFrame
{ {
public: public:
BaseFrame(BaseGui* gui) : tsl::elm::HeaderOverlayFrame(234) { BaseFrame(BaseGui* gui, u16 headerHeight = HOC_HEADER_HEIGHT) : tsl::elm::HeaderOverlayFrame(headerHeight) {
this->gui = gui; this->gui = gui;
} }
void draw(tsl::gfx::Renderer* renderer) override void draw(tsl::gfx::Renderer* renderer) override;
{
tsl::elm::HeaderOverlayFrame::draw(renderer);
this->gui->preDraw(renderer);
}
protected: protected:
BaseGui* gui; BaseGui* gui;

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,20 +24,18 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#pragma once #pragma once
#include <cstdint>
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <cstdint>
#include <hocclk/board.h> #include <hocclk/board.h>
#define FREQ_DEFAULT_TEXT "Do not override" #define FREQ_DEFAULT_TEXT "Do not override"
static inline std::string formatListFreqMHz(std::uint32_t mhz) static inline std::string formatListFreqMHz(std::uint32_t mhz) {
{ if (mhz == 0) {
if(mhz == 0)
{
return FREQ_DEFAULT_TEXT; return FREQ_DEFAULT_TEXT;
} }
@@ -45,17 +43,17 @@ static inline std::string formatListFreqMHz(std::uint32_t mhz)
return std::string(buf, snprintf(buf, sizeof(buf), "%u MHz", mhz)); return std::string(buf, snprintf(buf, sizeof(buf), "%u MHz", mhz));
} }
static inline std::string formatListFreqHz(uint32_t hz) { return formatListFreqMHz(hz / 1000000); } static inline std::string formatListFreqHz(uint32_t hz) {
return formatListFreqMHz(hz / 1000000);
}
static inline std::string formatListFreqMem(uint32_t mhz, RamDisplayUnit unit) static inline std::string formatListFreqMem(uint32_t mhz, RamDisplayUnit unit) {
{ if (mhz == 0)
if(mhz == 0)
return FREQ_DEFAULT_TEXT; return FREQ_DEFAULT_TEXT;
uint32_t mts = mhz * 2; uint32_t mts = mhz * 2;
char buf[24]; char buf[24];
switch(unit) switch (unit) {
{
case RamDisplayUnit_MHz: case RamDisplayUnit_MHz:
snprintf(buf, sizeof(buf), "%u MHz", mhz); snprintf(buf, sizeof(buf), "%u MHz", mhz);
break; break;
@@ -70,18 +68,15 @@ static inline std::string formatListFreqMem(uint32_t mhz, RamDisplayUnit unit)
return buf; return buf;
} }
static inline std::string formatListFreqHzMem(uint32_t hz, RamDisplayUnit unit) static inline std::string formatListFreqHzMem(uint32_t hz, RamDisplayUnit unit) {
{
return formatListFreqMem(hz / 1000000, unit); return formatListFreqMem(hz / 1000000, unit);
} }
static inline std::string formatMemClockKhzLabel(uint32_t khz, RamDisplayUnit unit) static inline std::string formatMemClockKhzLabel(uint32_t khz, RamDisplayUnit unit) {
{
uint32_t mhz = khz / 1000; uint32_t mhz = khz / 1000;
uint32_t mts = khz / 500; uint32_t mts = khz / 500;
char buf[32]; char buf[32];
switch(unit) switch (unit) {
{
case RamDisplayUnit_MHz: case RamDisplayUnit_MHz:
snprintf(buf, sizeof(buf), "%u MHz", mhz); snprintf(buf, sizeof(buf), "%u MHz", mhz);
break; break;

View File

@@ -22,6 +22,8 @@
#include "cat.h" #include "cat.h"
#include "ult_ext.h" #include "ult_ext.h"
// tsl::elm::ListItem* custRevItem = NULL;
tsl::elm::ListItem* kipVersionItem = NULL;
tsl::elm::ListItem* SpeedoItem = NULL; tsl::elm::ListItem* SpeedoItem = NULL;
tsl::elm::ListItem* IddqItem = NULL; tsl::elm::ListItem* IddqItem = NULL;
tsl::elm::ListItem* DramModule = NULL; tsl::elm::ListItem* DramModule = NULL;
@@ -36,11 +38,14 @@ tsl::elm::ListItem* ramBWItemAll = NULL;
tsl::elm::ListItem* ramBWItemCpu = NULL; tsl::elm::ListItem* ramBWItemCpu = NULL;
tsl::elm::ListItem* ramBWItemGpu = NULL; tsl::elm::ListItem* ramBWItemGpu = NULL;
tsl::elm::ListItem* ramBWItemMax = NULL; tsl::elm::ListItem* ramBWItemMax = NULL;
tsl::elm::ListItem* bqtempitem = NULL;
tsl::elm::ListItem* aotagTempItem = NULL;
tsl::elm::ListItem* cTypeItem = NULL;
tsl::elm::ListItem* creditsItem = NULL;
ImageElement* CatImage = NULL; #define R_ARROW "\u2192"
HideableCategoryHeader* CatHeader = NULL;
HideableCustomDrawer* CatSpacer = NULL; class CreditsSubMenu;
int lightosClickCount = 0;
AboutGui::AboutGui() AboutGui::AboutGui()
{ {
@@ -53,13 +58,18 @@ AboutGui::~AboutGui()
void AboutGui::listUI() void AboutGui::listUI()
{ {
BaseMenuGui::refresh();
if (!this->context)
return;
this->listElement->addItem( this->listElement->addItem(
new tsl::elm::CategoryHeader("Voltages and Temps") new tsl::elm::CategoryHeader("Voltages")
); );
ramVoltItem = ramVoltItem =
new tsl::elm::ListItem("RAM Voltage:"); new tsl::elm::ListItem("RAM Voltage:");
if(IsMariko()) { if(IsMariko()) {
this->listElement->addItem(ramVoltItem); this->listElement->addItem(ramVoltItem);
} }
@@ -67,12 +77,23 @@ void AboutGui::listUI()
new tsl::elm::ListItem("Display Voltage:"); new tsl::elm::ListItem("Display Voltage:");
this->listElement->addItem(dispVoltItem); this->listElement->addItem(dispVoltItem);
this->listElement->addItem(
new tsl::elm::CategoryHeader("Temperatures")
);
eristaPLLXItem = eristaPLLXItem =
new tsl::elm::ListItem("PLLX Temp:"); new tsl::elm::ListItem("PLLX Temp:");
if(IsErista()) { if(this->context->temps[HocClkThermalSensor_AO] > 0) { // Only show if the value is valid (not -126, which means not patched)
this->listElement->addItem(eristaPLLXItem); this->listElement->addItem(eristaPLLXItem);
} }
aotagTempItem =
new tsl::elm::ListItem("AOTAG Temp:");
this->listElement->addItem(aotagTempItem);
bqtempitem =
new tsl::elm::ListItem("BQ24193 Temp:");
this->listElement->addItem(bqtempitem);
this->listElement->addItem( this->listElement->addItem(
new tsl::elm::CategoryHeader("RAM Bandwidth") new tsl::elm::CategoryHeader("RAM Bandwidth")
); );
@@ -88,15 +109,20 @@ void AboutGui::listUI()
ramBWItemCpu = ramBWItemCpu =
new tsl::elm::ListItem("RAM BW (CPU):"); new tsl::elm::ListItem("RAM BW (CPU):");
this->listElement->addItem(ramBWItemCpu); this->listElement->addItem(ramBWItemCpu);
ramBWItemGpu = ramBWItemGpu =
new tsl::elm::ListItem("RAM BW (GPU):"); new tsl::elm::ListItem("RAM BW (GPU):");
this->listElement->addItem(ramBWItemGpu); this->listElement->addItem(ramBWItemGpu);
this->listElement->addItem( this->listElement->addItem(
new tsl::elm::CategoryHeader("HW Info") new tsl::elm::CategoryHeader("Hardware Info")
); );
cTypeItem =
new tsl::elm::ListItem("Console Type:");
this->listElement->addItem(cTypeItem);
SpeedoItem = SpeedoItem =
new tsl::elm::ListItem("Speedo:"); new tsl::elm::ListItem("Speedo:");
this->listElement->addItem(SpeedoItem); this->listElement->addItem(SpeedoItem);
@@ -106,7 +132,7 @@ void AboutGui::listUI()
this->listElement->addItem(IddqItem); this->listElement->addItem(IddqItem);
DramModule = DramModule =
new tsl::elm::ListItem("Module: "); new tsl::elm::ListItem("DRAM Module: ");
this->listElement->addItem(DramModule); this->listElement->addItem(DramModule);
waferCordsItem = waferCordsItem =
@@ -123,6 +149,12 @@ void AboutGui::listUI()
new tsl::elm::CategoryHeader("Software Info") new tsl::elm::CategoryHeader("Software Info")
); );
// custRevItem = new tsl::elm::ListItem("CUST revision:");
// this->listElement->addItem(custRevItem);
kipVersionItem = new tsl::elm::ListItem("KIP version:");
this->listElement->addItem(kipVersionItem);
if(!IsHoag()) { if(!IsHoag()) {
sysdockStatusItem = sysdockStatusItem =
new tsl::elm::ListItem("sys-dock status:"); new tsl::elm::ListItem("sys-dock status:");
@@ -134,156 +166,19 @@ void AboutGui::listUI()
this->listElement->addItem(saltyNXStatusItem); this->listElement->addItem(saltyNXStatusItem);
this->listElement->addItem( this->listElement->addItem(
new tsl::elm::CategoryHeader("Credits") new tsl::elm::CategoryHeader("General Info")
); );
this->listElement->addItem( creditsItem = new tsl::elm::ListItem("Credits");
new tsl::elm::CategoryHeader("Developers") creditsItem->setClickListener([](u64 keys) {
);
this->listElement->addItem(
new tsl::elm::ListItem("Souldbminer")
);
// Create special clickable item for Lightos
auto lightosItem = new tsl::elm::ListItem("Lightos_");
lightosItem->setClickListener([this](u64 keys) -> bool {
if (keys & HidNpadButton_A) { if (keys & HidNpadButton_A) {
lightosClickCount++; tsl::changeTo<CreditsSubMenu>();
if (lightosClickCount >= 10) {
if (CatImage != NULL) CatImage->setVisible(true);
if (CatHeader != NULL) CatHeader->setVisible(true);
if (CatSpacer != NULL) CatSpacer->setVisible(true);
}
return true; return true;
} }
return false; return false;
}); });
this->listElement->addItem(lightosItem); creditsItem->setValue(R_ARROW);
this->listElement->addItem(creditsItem);
// ---- Contributors ----
this->listElement->addItem(
new tsl::elm::CategoryHeader("Contributors")
);
this->listElement->addItem(
new tsl::elm::ListItem("Dom")
);
this->listElement->addItem(
new tsl::elm::ListItem("Blaise25")
);
// ---- Testers ----
this->listElement->addItem(
new tsl::elm::CategoryHeader("Testers")
);
this->listElement->addItem(
new tsl::elm::ListItem("Dom")
);
this->listElement->addItem(
new tsl::elm::ListItem("Samybigio2011")
);
this->listElement->addItem(
new tsl::elm::ListItem("Delta")
);
this->listElement->addItem(
new tsl::elm::ListItem("Miki1305")
);
this->listElement->addItem(
new tsl::elm::ListItem("Happy")
);
this->listElement->addItem(
new tsl::elm::ListItem("Flopsider")
);
this->listElement->addItem(
new tsl::elm::ListItem("Winnerboi77")
);
this->listElement->addItem(
new tsl::elm::ListItem("Blaise25")
);
this->listElement->addItem(
new tsl::elm::ListItem("WE1ZARD")
);
this->listElement->addItem(
new tsl::elm::ListItem("Alvise")
);
this->listElement->addItem(
new tsl::elm::ListItem("TDRR")
);
this->listElement->addItem(
new tsl::elm::ListItem("agjeococh")
);
this->listElement->addItem(
new tsl::elm::ListItem("Xenshen")
);
this->listElement->addItem(
new tsl::elm::ListItem("Frost")
);
// ---- Special Thanks ----
this->listElement->addItem(
new tsl::elm::CategoryHeader("Special Thanks")
);
this->listElement->addItem(
new tsl::elm::ListItem("ScriesM - Atmosphere CFW")
);
this->listElement->addItem(
new tsl::elm::ListItem("KazushiMe - Switch OC Suite")
);
this->listElement->addItem(
new tsl::elm::ListItem("hanai3bi - Switch OC Suite & EOS")
);
this->listElement->addItem(
new tsl::elm::ListItem("NaGaa95 - L4T-OC-Kernel")
);
this->listElement->addItem(
new tsl::elm::ListItem("B3711 - EOS")
);
this->listElement->addItem(
new tsl::elm::ListItem("RetroNX - sys-clk")
);
this->listElement->addItem(
new tsl::elm::ListItem("b0rd2death - Ultrahand")
);
this->listElement->addItem(
new tsl::elm::ListItem("MasaGratoR - Status Monitor")
);
// Create cat elements but hide them initially
CatHeader = new HideableCategoryHeader("Cat");
CatHeader->setVisible(false);
this->listElement->addItem(CatHeader);
CatImage = new ImageElement(CAT_DATA, CAT_WIDTH, CAT_HEIGHT);
CatImage->setVisible(false);
this->listElement->addItem(CatImage);
CatSpacer = new HideableCustomDrawer(75);
CatSpacer->setVisible(false);
this->listElement->addItem(CatSpacer);
} }
std::string AboutGui::formatRamModule() { std::string AboutGui::formatRamModule() {
@@ -337,7 +232,7 @@ void AboutGui::update()
void AboutGui::refresh() void AboutGui::refresh()
{ {
BaseMenuGui::refresh(); BaseMenuGui::refresh();
if (!this->context) if (!this->context)
return; return;
// Format strings once per refresh // Format strings once per refresh
@@ -347,26 +242,38 @@ void AboutGui::refresh()
SpeedoItem->setValue(strings[0]); SpeedoItem->setValue(strings[0]);
IddqItem->setValue(strings[1]); IddqItem->setValue(strings[1]);
DramModule->setValue(formatRamModule()); DramModule->setValue(formatRamModule());
// custRevItem->setValue(std::to_string(this->context->custRev));
kipVersionItem->setValue(std::to_string((this->context->kipVersion / 100) % 10) + "." + std::to_string((this->context->kipVersion / 10) % 10) + "." + std::to_string( this->context->kipVersion % 10) + " (Cust Rev " + std::to_string(this->context->custRev) + ")");
if(!IsHoag()) if(!IsHoag())
sysdockStatusItem->setValue(this->context->isSysDockInstalled ? "Installed" : "Not Installed"); sysdockStatusItem->setValue(this->context->isSysDockInstalled ? "Installed" : "Not Installed");
saltyNXStatusItem->setValue(this->context->isSaltyNXInstalled ? "Installed" : "Not Installed"); saltyNXStatusItem->setValue(this->context->isSaltyNXInstalled ? "Installed" : "Not Installed");
if(IsHoag()) if(IsHoag())
RETROStatusItem->setValue(this->context->isUsingRetroSuper ? "Installed" : "Not Installed"); RETROStatusItem->setValue(this->context->isUsingRetroSuper ? "Installed" : "Not Installed");
sprintf(strings[2], "X: %u Y: %u", this->context->waferX, this->context->waferY); sprintf(strings[2], "X: %d Y: %d", this->context->waferX, this->context->waferY);
waferCordsItem->setValue(strings[2]); waferCordsItem->setValue(strings[2]);
if(IsErista()) { s32 millis = context->temps[HocClkThermalSensor_PLLX];
u32 millis = context->temps[HocClkThermalSensor_PLLX]; sprintf(strings[3], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
sprintf(strings[3], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); eristaPLLXItem->setValue(strings[3]);
eristaPLLXItem->setValue(strings[3]);
millis = context->temps[HocClkThermalSensor_AO];
if(millis > 0) {
sprintf(strings[11], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
} else if (millis == -125) {
sprintf(strings[11], "Invalid");
} else if (millis == -126) {
sprintf(strings[11], "Not Patched");
} }
aotagTempItem->setValue(strings[11]);
sprintf(strings[4], "%u.%u / %u mV", context->voltages[HocClkVoltage_EMCVDD2] / 1000U, (context->voltages[HocClkVoltage_EMCVDD2] % 1000U) / 100U, context->voltages[HocClkVoltage_EMCVDDQ] / 1000); sprintf(strings[4], "%u.%u / %u mV", context->voltages[HocClkVoltage_EMCVDD2] / 1000U, (context->voltages[HocClkVoltage_EMCVDD2] % 1000U) / 100U, context->voltages[HocClkVoltage_EMCVDDQ] / 1000);
ramVoltItem->setValue(strings[4]); ramVoltItem->setValue(strings[4]);
sprintf(strings[5], "%u.%u mV", context->voltages[HocClkVoltage_Display] / 1000U, (context->voltages[HocClkVoltage_Display] % 1000U) / 100U); sprintf(strings[5], "%u.%u mV", context->voltages[HocClkVoltage_Display] / 1000U, (context->voltages[HocClkVoltage_Display] % 1000U) / 100U);
dispVoltItem->setValue(strings[5]); dispVoltItem->setValue(strings[5]);
@@ -382,4 +289,178 @@ void AboutGui::refresh()
sprintf(strings[9], "%u MB/s", context->partLoad[HocClkPartLoad_RamBWPeak]); sprintf(strings[9], "%u MB/s", context->partLoad[HocClkPartLoad_RamBWPeak]);
ramBWItemMax->setValue(strings[9]); ramBWItemMax->setValue(strings[9]);
switch(context->temps[HocClkThermalSensor_BQ24193]) {
case BQ24193Temp_Normal:
strcpy(strings[10], "Normal");
break;
case BQ24193Temp_Warm:
strcpy(strings[10], "Warm");
break;
case BQ24193Temp_Hot:
strcpy(strings[10], "Hot");
break;
case BQ24193Temp_Overheat:
strcpy(strings[10], "Overheat");
break;
default:
strcpy(strings[10], "Unknown");
}
bqtempitem->setValue(strings[10]);
cTypeItem->setValue(hocClkFormatConsoleType(this->context->consoleType, true));
} }
class CreditsSubMenu : public AboutGui {
public:
CreditsSubMenu() { }
protected:
ImageElement* CatImage = NULL;
HideableCategoryHeader* CatHeader = NULL;
HideableCustomDrawer* CatSpacer = NULL;
int lightosClickCount = 0;
void listUI() override {
this->listElement->addItem(
new tsl::elm::CategoryHeader("Developers")
);
this->listElement->addItem(
new tsl::elm::ListItem("Souldbminer")
);
// Create special clickable item for Lightos
auto lightosItem = new tsl::elm::ListItem("Lightos_");
lightosItem->setClickListener([this](u64 keys) -> bool {
if (keys & HidNpadButton_A) {
lightosClickCount++;
if (lightosClickCount >= 10) {
if (CatImage != NULL) CatImage->setVisible(true);
if (CatHeader != NULL) CatHeader->setVisible(true);
if (CatSpacer != NULL) CatSpacer->setVisible(true);
}
return true;
}
return false;
});
this->listElement->addItem(lightosItem);
// ---- Contributors ----
this->listElement->addItem(
new tsl::elm::CategoryHeader("Contributors")
);
this->listElement->addItem(
new tsl::elm::ListItem("Dom")
);
this->listElement->addItem(
new tsl::elm::ListItem("Blaise25")
);
this->listElement->addItem(
new tsl::elm::ListItem("tetetete-ctrl")
);
this->listElement->addItem(
new tsl::elm::ListItem("B3711")
);
this->listElement->addItem(
new tsl::elm::ListItem("TDRR")
);
this->listElement->addItem(
new tsl::elm::ListItem("MasaGratoR")
);
// ---- Testers ----
this->listElement->addItem(
new tsl::elm::CategoryHeader("Testers")
);
this->listElement->addItem(
new tsl::elm::ListItem("Samybigio2011")
);
this->listElement->addItem(
new tsl::elm::ListItem("arcdelta")
);
this->listElement->addItem(
new tsl::elm::ListItem("Miki1305")
);
this->listElement->addItem(
new tsl::elm::ListItem("Happy")
);
this->listElement->addItem(
new tsl::elm::ListItem("Winnerboi77")
);
this->listElement->addItem(
new tsl::elm::ListItem("Blaise25")
);
this->listElement->addItem(
new tsl::elm::ListItem("WE1ZARD")
);
this->listElement->addItem(
new tsl::elm::ListItem("Alvise")
);
this->listElement->addItem(
new tsl::elm::ListItem("agjeococh")
);
this->listElement->addItem(
new tsl::elm::ListItem("Frost")
);
// ---- Special Thanks ----
this->listElement->addItem(
new tsl::elm::CategoryHeader("Special Thanks")
);
this->listElement->addItem(
new tsl::elm::ListItem("SciresM, hexkyz and Alula - Atmosphere CFW")
);
this->listElement->addItem(
new tsl::elm::ListItem("KazushiMe - Switch OC Suite")
);
this->listElement->addItem(
new tsl::elm::ListItem("hanai3Bi - Switch OC Suite & EOS")
);
this->listElement->addItem(
new tsl::elm::ListItem("RetroNX - sys-clk")
);
this->listElement->addItem(
new tsl::elm::ListItem("ppkantorski - Ultrahand")
);
this->listElement->addItem(
new tsl::elm::ListItem("CtCaer - Hekate, L4T and Proper Timings")
);
// Create cat elements but hide them initially
CatHeader = new HideableCategoryHeader("Cat");
CatHeader->setVisible(false);
this->listElement->addItem(CatHeader);
CatImage = new ImageElement(CAT_DATA, CAT_WIDTH, CAT_HEIGHT);
CatImage->setVisible(false);
this->listElement->addItem(CatImage);
CatSpacer = new HideableCustomDrawer(75);
CatSpacer->setVisible(false);
this->listElement->addItem(CatSpacer);
}
};

View File

@@ -25,6 +25,7 @@
*/ */
#include "ult_ext.h"
#include "app_profile_gui.h" #include "app_profile_gui.h"
#include "../format.h" #include "../format.h"
@@ -303,7 +304,7 @@ public:
static constexpr struct { const char* label; int shift; } kAll[] = { static constexpr struct { const char* label; int shift; } kAll[] = {
{"CPU", 0}, {"GPU", 8}, {"VRR", 16} {"CPU", 0}, {"GPU", 8}, {"VRR", 16}
}; };
int count = configList.values[HocClkConfigValue_OverwriteRefreshRate] || this->context->isUsingRetroSuper ? 3 : 2; int count = configList.values[HocClkConfigValue_OverwriteRefreshRate] || this->context->isUsingRetroSuper || this->context->profile == HocClkProfile_Docked ? 3 : 2;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
u8 cur = (this->profileList->mhzMap[this->profile][HocClkModule_Governor] >> kAll[i].shift) & 0xFF; u8 cur = (this->profileList->mhzMap[this->profile][HocClkModule_Governor] >> kAll[i].shift) & 0xFF;

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -28,54 +28,29 @@
#include "base_menu_gui.h" #include "base_menu_gui.h"
#include "freq_choice_gui.h" #include "freq_choice_gui.h"
#include "value_choice_gui.h" #include "value_choice_gui.h"
#define HOCCLK_GLOBAL_PROFILE_TID 0xA111111111111111 class AppProfileGui : public BaseMenuGui {
class AppProfileGui : public BaseMenuGui
{
protected: protected:
std::uint64_t applicationId; std::uint64_t applicationId;
HocClkTitleProfileList* profileList; HocClkTitleProfileList *profileList;
void openFreqChoiceGui(tsl::elm::ListItem* listItem, HocClkProfile profile, HocClkModule module); void openFreqChoiceGui(tsl::elm::ListItem *listItem, HocClkProfile profile, HocClkModule module);
void addModuleListItem(HocClkProfile profile, HocClkModule module); void addModuleListItem(HocClkProfile profile, HocClkModule module);
void addModuleListItemToggle(HocClkProfile profile, HocClkModule module); void addModuleListItemToggle(HocClkProfile profile, HocClkModule module);
void openValueChoiceGui( void openValueChoiceGui(tsl::elm::ListItem *listItem, std::uint32_t currentValue, const ValueRange &range, const std::string &categoryName,
tsl::elm::ListItem* listItem, ValueChoiceListener listener, const ValueThresholds &thresholds = ValueThresholds(), bool enableThresholds = false,
std::uint32_t currentValue, const std::map<std::uint32_t, std::string> &labels = {}, const std::vector<NamedValue> &namedValues = {},
const ValueRange& range, bool showDefaultValue = true);
const std::string& categoryName, std::string formatValueDisplay(std::uint32_t value, const std::vector<NamedValue> &namedValues, const std::string &suffix, std::uint32_t divisor,
ValueChoiceListener listener, int decimalPlaces);
const ValueThresholds& thresholds = ValueThresholds(), void addModuleListItemValue(HocClkProfile profile, HocClkModule module, const std::string &categoryName, std::uint32_t min, std::uint32_t max,
bool enableThresholds = false, std::uint32_t step, const std::string &suffix, std::uint32_t divisor, int decimalPlaces, ValueThresholds thresholds,
const std::map<std::uint32_t, std::string>& labels = {}, std::vector<NamedValue> namedValues = {}, bool showDefaultValue = true);
const std::vector<NamedValue>& namedValues = {}, void addGovernorSection(HocClkProfile profile);
bool showDefaultValue = true void addProfileUI(HocClkProfile profile);
);
std::string formatValueDisplay(
std::uint32_t value,
const std::vector<NamedValue>& namedValues,
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces
);
void addModuleListItemValue(
HocClkProfile profile,
HocClkModule module,
const std::string& categoryName,
std::uint32_t min,
std::uint32_t max,
std::uint32_t step,
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces,
ValueThresholds thresholds,
std::vector<NamedValue> namedValues = {},
bool showDefaultValue = true
);
void addGovernorSection(HocClkProfile profile);
void addProfileUI(HocClkProfile profile);
public: public:
AppProfileGui(std::uint64_t applicationId, HocClkTitleProfileList* profileList); AppProfileGui(std::uint64_t applicationId, HocClkTitleProfileList *profileList);
~AppProfileGui(); ~AppProfileGui();
void listUI() override; void listUI() override;
static void changeTo(std::uint64_t applicationId); static void changeTo(std::uint64_t applicationId);
void update() override; void update() override;
}; };

View File

@@ -12,7 +12,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
@@ -24,21 +24,41 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#include "../elements/base_frame.h"
#include "base_gui.h" #include "base_gui.h"
#include "../elements/base_frame.h"
#include <tesla.hpp> void BaseFrame::draw(tsl::gfx::Renderer *renderer) {
tsl::elm::HeaderOverlayFrame::draw(renderer);
this->gui->preDraw(renderer);
}
#include <math.h> #include <math.h>
#include <tesla.hpp>
#define LOGO_Y_REAL 65
#define LOGO_X 20 #define LOGO_X 20
#define LOGO_Y 50 #define LOGO_Y 60
#define LOGO_LABEL_FONT_SIZE 45 #define LOGO_LABEL_FONT_SIZE 45
#define VERSION_X (LOGO_X + 250) #define TEXT_Y 57
#define LOGO_IMG_W 50
#define LOGO_IMG_H 50
#define LOGO_IMG_PAD 8
#define LOGO_TEXT_X (LOGO_X + LOGO_IMG_W + LOGO_IMG_PAD)
#define VERSION_X (LOGO_TEXT_X + 185)
#define VERSION_Y (LOGO_Y - 40) #define VERSION_Y (LOGO_Y - 40)
#define VERSION_FONT_SIZE 15 #define VERSION_FONT_SIZE 15
extern "C" {
extern const u8 hoc_rgba[];
extern const u32 hoc_rgba_size;
}
std::string getVersionString() { std::string getVersionString() {
char buf[0x100] = ""; char buf[0x100] = "";
Result rc = hocclkIpcGetVersionString(buf, sizeof(buf)); Result rc = hocclkIpcGetVersionString(buf, sizeof(buf));
@@ -48,35 +68,28 @@ std::string getVersionString() {
return std::string(buf); return std::string(buf);
} }
static constexpr tsl::Color dynamicLogoRGB1 = tsl::Color(0, 15, 3, 15); static constexpr tsl::Color dynamicLogoRGB1 = tsl::Color(7, 15, 15, 15);
static constexpr tsl::Color dynamicLogoRGB2 = tsl::Color(0, 8, 1, 15); static constexpr tsl::Color dynamicLogoRGB2 = tsl::Color(2, 8, 11, 15);
static constexpr tsl::Color STATIC_GREEN = tsl::Color(0, 15, 0, 15); static constexpr tsl::Color STATIC_TEAL = tsl::Color(7, 15, 15, 15);
const std::string name = "Horizon OC Gaea"; const std::string name = " Horizon OC";
static s32 drawDynamicUltraText( static s32 drawDynamicUltraText(tsl::gfx::Renderer *renderer, s32 startX, s32 y, u32 fontSize, const tsl::Color &staticColor,
tsl::gfx::Renderer* renderer, bool useNotificationMethod = false) {
s32 startX,
s32 y,
u32 fontSize,
const tsl::Color& staticColor,
bool useNotificationMethod = false)
{
static constexpr double cycleDuration = 1.6; static constexpr double cycleDuration = 1.6;
s32 currentX = startX; s32 currentX = startX;
const u64 currentTime_ns = armTicksToNs(armGetSystemTick()); const u64 currentTime_ns = armTicksToNs(armGetSystemTick());
const double timeNow = static_cast<double>(currentTime_ns) / 1e9; const double timeNow = static_cast<double>(currentTime_ns) / 1e9;
const double timeBase = fmod(timeNow, cycleDuration);
const double waveScale = 2.0 * M_PI / cycleDuration; const double waveScale = 2.0 * M_PI / cycleDuration;
for (size_t i = 0; i < name.size(); i++) for (size_t i = 0; i < name.size(); i++) {
{
char letter = name[i]; char letter = name[i];
if (letter == '\0') break; if (letter == '\0')
break;
double phase = waveScale * (timeBase + i * 0.12); double phase = waveScale * (timeNow + i * 0.12);
double raw = cos(phase); double raw = cos(phase);
double n = (raw + 1.0) * 0.5; double n = (raw + 1.0) * 0.5;
@@ -86,15 +99,9 @@ static s32 drawDynamicUltraText(
double glow = (cos(phase * 1.5) + 1.0) * 0.5; double glow = (cos(phase * 1.5) + 1.0) * 0.5;
double brightness = 0.75 + glow * 0.25; double brightness = 0.75 + glow * 0.25;
u8 r = static_cast<u8>( u8 r = static_cast<u8>(((int)dynamicLogoRGB1.r + ((int)dynamicLogoRGB2.r - (int)dynamicLogoRGB1.r) * blend) * brightness);
(dynamicLogoRGB1.r + (dynamicLogoRGB2.r - dynamicLogoRGB1.r) * blend) * brightness u8 g = static_cast<u8>(((int)dynamicLogoRGB1.g + ((int)dynamicLogoRGB2.g - (int)dynamicLogoRGB1.g) * blend) * brightness);
); u8 b = static_cast<u8>(((int)dynamicLogoRGB1.b + ((int)dynamicLogoRGB2.b - (int)dynamicLogoRGB1.b) * blend) * brightness);
u8 g = static_cast<u8>(
(dynamicLogoRGB1.g + (dynamicLogoRGB2.g - dynamicLogoRGB1.g) * blend) * brightness
);
u8 b = static_cast<u8>(
(dynamicLogoRGB1.b + (dynamicLogoRGB2.b - dynamicLogoRGB1.b) * blend) * brightness
);
r = std::clamp<u8>(r, 0, 15); r = std::clamp<u8>(r, 0, 15);
g = std::clamp<u8>(g, 0, 15); g = std::clamp<u8>(g, 0, 15);
@@ -120,25 +127,34 @@ static s32 drawDynamicUltraText(
return currentX; return currentX;
} }
void BaseGui::preDraw(tsl::gfx::Renderer* renderer) { void BaseGui::preDraw(tsl::gfx::Renderer *renderer) {
drawDynamicUltraText( renderer->drawBitmap(LOGO_X, LOGO_Y_REAL - LOGO_LABEL_FONT_SIZE, LOGO_IMG_W, LOGO_IMG_H, hoc_rgba);
renderer,
LOGO_X, drawDynamicUltraText(renderer, LOGO_TEXT_X, TEXT_Y, LOGO_LABEL_FONT_SIZE, STATIC_TEAL, false);
LOGO_Y,
LOGO_LABEL_FONT_SIZE, static const std::string versionStr = "Version " + getVersionString() + " \"Gaea\"";
STATIC_GREEN, static constexpr tsl::Color versionColor(9, 9, 9, 15);
false static constexpr s32 vx = LOGO_TEXT_X + 15;
); static constexpr s32 vy = TEXT_Y + 18;
static constexpr s32 fs = 15;
static constexpr s32 skew = 3;
static constexpr s32 passes = 25;
for (s32 i = 0; i < passes; i++) {
s32 sliceY = (vy - fs) + i * fs / passes;
s32 sliceH = fs / passes + 1;
s32 xOff = skew - (skew * i / (passes - 1));
renderer->enableScissoring(0, sliceY, tsl::cfg::FramebufferWidth, sliceH);
renderer->drawString(versionStr.c_str(), false, vx + xOff, vy, fs, versionColor);
renderer->disableScissoring();
}
} }
tsl::elm::Element* BaseGui::createUI() tsl::elm::Element *BaseGui::createUI() {
{ BaseFrame *rootFrame = new BaseFrame(this, this->headerHeight());
BaseFrame* rootFrame = new BaseFrame(this);
rootFrame->setContent(this->baseUI()); rootFrame->setContent(this->baseUI());
return rootFrame; return rootFrame;
} }
void BaseGui::update() void BaseGui::update() {
{
this->refresh(); this->refresh();
} }

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,30 +24,36 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#pragma once #pragma once
#include <tesla.hpp>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm> #include <algorithm>
#include <fstream>
#include <string>
#include <tesla.hpp>
#include <vector>
#include "../style.h"
#include "../../ipc.h" #include "../../ipc.h"
#include "../elements/base_frame.h"
#include "../style.h"
class BaseGui : public tsl::Gui
{ class BaseGui : public tsl::Gui {
public: public:
BaseGui() {} BaseGui() {
~BaseGui() {} }
virtual void preDraw(tsl::gfx::Renderer* renderer); ~BaseGui() {
void update() override; }
tsl::elm::Element* createUI() override; virtual void preDraw(tsl::gfx::Renderer *renderer);
virtual tsl::elm::Element* baseUI() = 0; void update() override;
virtual void refresh() {} tsl::elm::Element *createUI() override;
virtual tsl::elm::Element *baseUI() = 0;
virtual void refresh() {
}
virtual u16 headerHeight() const {
return HOC_HEADER_HEIGHT;
}
private: private:
}; };
extern std::string getVersionString(); extern std::string getVersionString();

View File

@@ -24,21 +24,24 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#include "../format.h"
#include "base_menu_gui.h" #include "base_menu_gui.h"
#include "fatal_gui.h" #include "fatal_gui.h"
#include "../format.h"
#define TOP_Y_OFFSET 15
// Cache hardware model to avoid repeated syscalls // Cache hardware model to avoid repeated syscalls
BaseMenuGui::BaseMenuGui() : tempColors{ tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), } BaseMenuGui::BaseMenuGui()
{ : tempColors{
tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0),
} {
tsl::initializeThemeVars(); tsl::initializeThemeVars();
this->context = nullptr; this->context = nullptr;
this->lastContextUpdate = 0; this->lastContextUpdate = 0;
this->listElement = nullptr; this->listElement = nullptr;
// Pre-cache hardware model during initialization // Pre-cache hardware model during initialization
IsAula(); IsAula();
IsMariko(); IsMariko();
@@ -49,20 +52,19 @@ BaseMenuGui::BaseMenuGui() : tempColors{ tsl::Color(0), tsl::Color(0), tsl::Colo
} }
BaseMenuGui::~BaseMenuGui() { BaseMenuGui::~BaseMenuGui() {
delete this->context; // delete handles nullptr automatically delete this->context; // delete handles nullptr automatically
} }
// Fast preDraw - just renders pre-computed strings // Fast preDraw - just renders pre-computed strings
void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) { void BaseMenuGui::preDraw(tsl::gfx::Renderer *renderer) {
BaseGui::preDraw(renderer); BaseGui::preDraw(renderer);
if(!this->context) [[unlikely]] return;
// All constants pre-calculated and cached // All constants pre-calculated and cached
const char* labels[] = { const char *labels[] = { "App ID", "Profile", "CPU", "GPU", "MEM", "SoC", "Board",
"App ID", "Profile", "CPU", "GPU", "MEM", "SoC", "Board", "Skin", "Now", "Avg", "BAT", "PMIC", "Fan", IsAula() ? "OLED" : "LCD", "FPS", "RES" "Skin", "Now", "Avg", "BAT", "PMIC", "Fan", IsAula() || this->context->isUsingRetroSuper ? "OLED" : "LCD",
}; "FPS", "RES" };
static constexpr u32 dataPositions[6] = {63-3+3, 200-1, 344-1-3, 200-1, 342-1, 321-1}; static constexpr u32 dataPositions[6] = { 63 - 3 + 3, 200 - 1, 344 - 1 - 3, 200 - 1, 342 - 1, 321 - 1 };
static u32 labelWidths[10]; static u32 labelWidths[10];
static bool positionsInitialized = false; static bool positionsInitialized = false;
@@ -73,14 +75,23 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
} }
positionsInitialized = true; positionsInitialized = true;
} }
static u32 positions[10] = {24-1, 310-labelWidths[1], 24-1, 192-labelWidths[3], 332-labelWidths[4], 24-1, 192 - labelWidths[6], 332-labelWidths[7], 192 - labelWidths[8], 332-labelWidths[9]}; static u32 positions[10] = { 24 - 1,
310 - labelWidths[1],
24 - 1,
192 - labelWidths[3],
332 - labelWidths[4],
24 - 1,
192 - labelWidths[6],
332 - labelWidths[7],
192 - labelWidths[8],
332 - labelWidths[9] };
static u32 maxProfileValueWidth = renderer->getTextDimensions("USB Charger", false, SMALL_TEXT_SIZE).first; // longest word static u32 maxProfileValueWidth = renderer->getTextDimensions("USB Charger", false, SMALL_TEXT_SIZE).first; // longest word
u32 y = 91; u32 y = 91 + TOP_Y_OFFSET;
// === TOP SECTION === // === TOP SECTION ===
renderer->drawRoundedRect(14, 70-1, 420, 30+2, 12.0f, renderer->aWithOpacity(tsl::tableBGColor)); renderer->drawRoundedRect(14, 70 - 1 + TOP_Y_OFFSET, 420, 30 + 2, 12.0f, renderer->aWithOpacity(tsl::tableBGColor));
// App ID - use pre-formatted string // App ID - use pre-formatted string
renderer->drawString(labels[0], false, positions[0], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); renderer->drawString(labels[0], false, positions[0], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
@@ -90,10 +101,10 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
renderer->drawString(labels[1], false, 423 - maxProfileValueWidth - labelWidths[1] - 9, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); renderer->drawString(labels[1], false, 423 - maxProfileValueWidth - labelWidths[1] - 9, y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(displayStrings[1], false, 423 - maxProfileValueWidth, y, SMALL_TEXT_SIZE, tsl::infoTextColor); renderer->drawString(displayStrings[1], false, 423 - maxProfileValueWidth, y, SMALL_TEXT_SIZE, tsl::infoTextColor);
y += 38; // Direct assignment instead of += 38 y += 38; // Direct assignment instead of += 38
// === MAIN DATA SECTION === // === MAIN DATA SECTION ===
renderer->drawRoundedRect(14, 106, 420, 156, 10.0f, renderer->aWithOpacity(tsl::tableBGColor)); renderer->drawRoundedRect(14, 106 + TOP_Y_OFFSET, 420, 156, 10.0f, renderer->aWithOpacity(tsl::tableBGColor));
// === FREQUENCY SECTION === // === FREQUENCY SECTION ===
// Labels first (better cache locality) // Labels first (better cache locality)
@@ -105,8 +116,7 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
renderer->drawString(displayStrings[3], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU renderer->drawString(displayStrings[3], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU
renderer->drawString(displayStrings[4], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // MEM renderer->drawString(displayStrings[4], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // MEM
y += 20; // Direct assignment (129 + 20) y += 20; // Direct assignment (129 + 20)
renderer->drawString(displayStrings[5], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU real renderer->drawString(displayStrings[5], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU real
renderer->drawString(displayStrings[6], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU real renderer->drawString(displayStrings[6], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU real
@@ -118,19 +128,20 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
// === REAL FREQUENCIES === // === REAL FREQUENCIES ===
y += 20; // Direct assignment (149 + 20) y += 20; // Direct assignment (149 + 20)
// === VOLTAGES === // === VOLTAGES ===
renderer->drawString(displayStrings[8], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU voltage renderer->drawString(displayStrings[8], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU voltage
renderer->drawString(displayStrings[9], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU voltage renderer->drawString(displayStrings[9], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU voltage
renderer->drawStringWithColoredSections(displayStrings[10], false, {""}, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor, tsl::separatorColor); renderer->drawStringWithColoredSections(displayStrings[10], false, { "" }, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor,
tsl::separatorColor);
renderer->drawString(displayStrings[19], false, positions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU Usage renderer->drawString(displayStrings[19], false, positions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU Usage
renderer->drawString(displayStrings[17], false, positions[3], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU Usage renderer->drawString(displayStrings[17], false, positions[3], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU Usage
renderer->drawString(displayStrings[18], false, positions[4], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // RAM Usage renderer->drawString(displayStrings[18], false, positions[4], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // RAM Usage
y += 22; // Direct assignment (169 + 22) y += 22; // Direct assignment (169 + 22)
// === TEMPERATURE SECTION === // === TEMPERATURE SECTION ===
// Labels // Labels
@@ -140,59 +151,57 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
// Temperatures with color - use pre-computed colors // Temperatures with color - use pre-computed colors
renderer->drawString(displayStrings[11], false, dataPositions[0] - 1, y, SMALL_TEXT_SIZE, tempColors[HocClkThermalSensor_SOC]); // SOC renderer->drawString(displayStrings[11], false, dataPositions[0] - 1, y, SMALL_TEXT_SIZE, tempColors[HocClkThermalSensor_SOC]); // SOC
renderer->drawString(displayStrings[12], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[HocClkThermalSensor_PCB]); // PCB renderer->drawString(displayStrings[12], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[HocClkThermalSensor_PCB]); // PCB
renderer->drawString(displayStrings[13], false, dataPositions[2], y, SMALL_TEXT_SIZE, tempColors[HocClkThermalSensor_Skin]); // Skin renderer->drawString(displayStrings[13], false, dataPositions[2], y, SMALL_TEXT_SIZE, tempColors[HocClkThermalSensor_Skin]); // Skin
y += 20; // Direct assignment (191 + 20) y += 20; // Direct assignment (191 + 20)
renderer->drawString(displayStrings[14], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // SOC voltage renderer->drawString(displayStrings[14], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // SOC voltage
// Power labels and values // Power labels and values
renderer->drawString(labels[8], false, positions[8]-1, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); renderer->drawString(labels[8], false, positions[8] - 1, y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(labels[9], false, positions[9], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); renderer->drawString(labels[9], false, positions[9], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(displayStrings[15], false, dataPositions[3], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Power now renderer->drawString(displayStrings[15], false, dataPositions[3], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Power now
renderer->drawString(displayStrings[16], false, dataPositions[4], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Power avg renderer->drawString(displayStrings[16], false, dataPositions[4], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Power avg
y+=20; y += 20;
renderer->drawString(labels[10], false, positions[2], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); renderer->drawString(labels[10], false, positions[2], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(displayStrings[20], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[HocClkThermalSensor_Battery]); // Battery renderer->drawString(displayStrings[20], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[HocClkThermalSensor_Battery]); // Battery
renderer->drawString(labels[12], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // fan label renderer->drawString(labels[12], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // fan label
renderer->drawString(displayStrings[24], false, dataPositions[1] + 5, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // fan speed renderer->drawString(displayStrings[24], false, dataPositions[1] + 5, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // fan speed
renderer->drawString(labels[13], false, positions[4] + 4, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // disp label renderer->drawString(labels[13], false, positions[4] + 4, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // disp label
renderer->drawString(displayStrings[25], false, dataPositions[2] + 6, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp freq renderer->drawString(displayStrings[25], false, dataPositions[2] + 6, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp freq
y+=20; y += 20;
renderer->drawString(displayStrings[21], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat voltage renderer->drawString(displayStrings[21], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat voltage
renderer->drawString(displayStrings[23], false, positions[2] - 2, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat Age renderer->drawString(displayStrings[23], false, positions[2] - 2, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat Age
if(this->context->isSaltyNXInstalled) { if (this->context->isSaltyNXInstalled) {
renderer->drawString(labels[15], false, positions[3] + 7, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // RES label renderer->drawString(labels[15], false, positions[3] + 7, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // RES label
renderer->drawString(displayStrings[27], false, dataPositions[1] + 5, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // RES renderer->drawString(displayStrings[27], false, dataPositions[1] + 5, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // RES
renderer->drawString(labels[14], false, positions[4] + 9, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // FPS label
renderer->drawString(displayStrings[26], false, dataPositions[2] + 6, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // FPS
renderer->drawString(labels[14], false, positions[4] + 9, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // FPS label
renderer->drawString(displayStrings[26], false, dataPositions[2] + 6, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // FPS
} }
y+=20; y += 20;
} }
// Optimized refresh - now does all the string formatting once per second // Optimized refresh - now does all the string formatting once per second
void BaseMenuGui::refresh() void BaseMenuGui::refresh() {
{
const u64 ticks = armGetSystemTick(); const u64 ticks = armGetSystemTick();
// Use cached comparison - 1 billion nanoseconds // Use cached comparison - 1 billion nanoseconds
if (armTicksToNs(ticks - this->lastContextUpdate) <= 1000000000UL) [[likely]] { if (armTicksToNs(ticks - this->lastContextUpdate) <= 1000000000UL) [[likely]] {
return; // Early exit for most calls return; // Early exit for most calls
} }
this->lastContextUpdate = ticks; this->lastContextUpdate = ticks;
@@ -223,22 +232,22 @@ void BaseMenuGui::refresh()
strcpy(displayStrings[1], hocclkFormatProfile(context->profile, true)); strcpy(displayStrings[1], hocclkFormatProfile(context->profile, true));
// Current frequencies // Current frequencies
u32 hz = context->freqs[HocClkModule_CPU]; // CPU u32 hz = context->freqs[HocClkModule_CPU]; // CPU
sprintf(displayStrings[2], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); sprintf(displayStrings[2], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->freqs[HocClkModule_GPU]; // GPU hz = context->freqs[HocClkModule_GPU]; // GPU
sprintf(displayStrings[3], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); sprintf(displayStrings[3], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->freqs[HocClkModule_MEM]; // MEM hz = context->freqs[HocClkModule_MEM]; // MEM
std::uint32_t unit = configList.values[HocClkConfigValue_RamDisplayUnit]; std::uint32_t unit = configList.values[HocClkConfigValue_RamDisplayUnit];
std::uint32_t mhz = hz / 1000000U; std::uint32_t mhz = hz / 1000000U;
std::uint32_t mts = mhz * 2; std::uint32_t mts = mhz * 2;
std::uint32_t tenth = (hz / 100000U) % 10U; std::uint32_t tenth = (hz / 100000U) % 10U;
if(unit == RamDisplayUnit_MTs) if (unit == RamDisplayUnit_MTs)
sprintf(displayStrings[4], "%u MT/s", mts); sprintf(displayStrings[4], "%u MT/s", mts);
else if(unit == RamDisplayUnit_MHz) else if (unit == RamDisplayUnit_MHz)
sprintf(displayStrings[4], "%u.%u MHz", mhz, tenth); sprintf(displayStrings[4], "%u.%u MHz", mhz, tenth);
else if(unit == RamDisplayUnit_MHzMTs) { else if (unit == RamDisplayUnit_MHzMTs) {
hz = context->realFreqs[HocClkModule_MEM]; hz = context->realFreqs[HocClkModule_MEM];
mhz = hz / 1000000U; mhz = hz / 1000000U;
tenth = (hz / 100000U) % 10U; tenth = (hz / 100000U) % 10U;
@@ -246,18 +255,18 @@ void BaseMenuGui::refresh()
} }
// Real frequencies // Real frequencies
hz = context->realFreqs[HocClkModule_CPU]; // CPU hz = context->realFreqs[HocClkModule_CPU]; // CPU
sprintf(displayStrings[5], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); sprintf(displayStrings[5], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->realFreqs[HocClkModule_GPU]; // GPU hz = context->realFreqs[HocClkModule_GPU]; // GPU
sprintf(displayStrings[6], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); sprintf(displayStrings[6], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->realFreqs[HocClkModule_MEM]; // MEM hz = context->realFreqs[HocClkModule_MEM]; // MEM
unit = configList.values[HocClkConfigValue_RamDisplayUnit]; unit = configList.values[HocClkConfigValue_RamDisplayUnit];
mhz = hz / 1000000U; mhz = hz / 1000000U;
mts = mhz * 2; mts = mhz * 2;
tenth = (hz / 100000U) % 10U; tenth = (hz / 100000U) % 10U;
if(unit == RamDisplayUnit_MTs || unit == RamDisplayUnit_MHzMTs) if (unit == RamDisplayUnit_MTs || unit == RamDisplayUnit_MHzMTs)
sprintf(displayStrings[7], "%u MT/s", mts); sprintf(displayStrings[7], "%u MT/s", mts);
else else
sprintf(displayStrings[7], "%u.%u MHz", mhz, tenth); sprintf(displayStrings[7], "%u.%u MHz", mhz, tenth);
@@ -266,12 +275,14 @@ void BaseMenuGui::refresh()
sprintf(displayStrings[8], "%.1f mV", context->voltages[HocClkVoltage_CPU] / 1000.0); sprintf(displayStrings[8], "%.1f mV", context->voltages[HocClkVoltage_CPU] / 1000.0);
sprintf(displayStrings[9], "%.1f mV", context->voltages[HocClkVoltage_GPU] / 1000.0); sprintf(displayStrings[9], "%.1f mV", context->voltages[HocClkVoltage_GPU] / 1000.0);
switch(configList.values[HocClkConfigValue_RAMVoltDisplayMode]) { switch (configList.values[HocClkConfigValue_RAMVoltDisplayMode]) {
case RamDisplayMode_VDD2: case RamDisplayMode_VDD2:
sprintf(displayStrings[10], "%u.%u mV", context->voltages[HocClkVoltage_EMCVDD2] / 1000U, (context->voltages[HocClkVoltage_EMCVDD2] % 1000U) / 100U); sprintf(displayStrings[10], "%u.%u mV", context->voltages[HocClkVoltage_EMCVDD2] / 1000U,
(context->voltages[HocClkVoltage_EMCVDD2] % 1000U) / 100U);
break; break;
case RamDisplayMode_VDDQ: case RamDisplayMode_VDDQ:
sprintf(displayStrings[10], "%u.%u mV", context->voltages[HocClkVoltage_EMCVDDQ] / 1000U, (context->voltages[HocClkVoltage_EMCVDDQ] % 1000U) / 100U); sprintf(displayStrings[10], "%u.%u mV", context->voltages[HocClkVoltage_EMCVDDQ] / 1000U,
(context->voltages[HocClkVoltage_EMCVDDQ] % 1000U) / 100U);
break; break;
default: default:
strcpy(displayStrings[10], "N/A"); strcpy(displayStrings[10], "N/A");
@@ -279,15 +290,15 @@ void BaseMenuGui::refresh()
} }
// Temperatures and pre-compute colors // Temperatures and pre-compute colors
u32 millis = context->temps[HocClkThermalSensor_SOC]; // SOC u32 millis = context->temps[HocClkThermalSensor_SOC]; // SOC
sprintf(displayStrings[11], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); sprintf(displayStrings[11], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[HocClkThermalSensor_SOC] = tsl::GradientColor(millis * 0.001f); tempColors[HocClkThermalSensor_SOC] = tsl::GradientColor(millis * 0.001f);
millis = context->temps[HocClkThermalSensor_PCB]; // PCB millis = context->temps[HocClkThermalSensor_PCB]; // PCB
sprintf(displayStrings[12], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); sprintf(displayStrings[12], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[HocClkThermalSensor_PCB] = tsl::GradientColor(millis * 0.001f); tempColors[HocClkThermalSensor_PCB] = tsl::GradientColor(millis * 0.001f);
millis = context->temps[HocClkThermalSensor_Skin]; // Skin millis = context->temps[HocClkThermalSensor_Skin]; // Skin
sprintf(displayStrings[13], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); sprintf(displayStrings[13], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[HocClkThermalSensor_Skin] = tsl::GradientColor(millis * 0.001f); tempColors[HocClkThermalSensor_Skin] = tsl::GradientColor(millis * 0.001f);
@@ -295,26 +306,26 @@ void BaseMenuGui::refresh()
sprintf(displayStrings[14], "%u mV", context->voltages[HocClkVoltage_SOC] / 1000U); sprintf(displayStrings[14], "%u mV", context->voltages[HocClkVoltage_SOC] / 1000U);
// Power // Power
sprintf(displayStrings[15], "%d mW", context->power[0]); // Now sprintf(displayStrings[15], "%d mW", context->power[0]); // Now
sprintf(displayStrings[16], "%d mW", context->power[1]); // Avg sprintf(displayStrings[16], "%d mW", context->power[1]); // Avg
sprintf(displayStrings[17], "%u%%", context->partLoad[HocClkPartLoad_GPU] / 10); sprintf(displayStrings[17], "%u%%", context->partLoad[HocClkPartLoad_GPU] / 10);
sprintf(displayStrings[18], "%u%%", context->partLoad[HocClkPartLoad_EMC] / 10); sprintf(displayStrings[18], "%u%%", context->partLoad[HocClkPartLoad_EMC] / 10);
sprintf(displayStrings[19], "%u%%", context->partLoad[HocClkPartLoad_CPUMax] / 10); sprintf(displayStrings[19], "%u%%", context->partLoad[HocClkPartLoad_CPUMax] / 10);
millis = context->temps[HocClkThermalSensor_Battery]; // Battery millis = context->temps[HocClkThermalSensor_Battery]; // Battery
sprintf(displayStrings[20], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); sprintf(displayStrings[20], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[HocClkThermalSensor_Battery] = tsl::GradientColor(millis * 0.001f); tempColors[HocClkThermalSensor_Battery] = tsl::GradientColor(millis * 0.001f);
sprintf(displayStrings[21], "%d mV", context->voltages[HocClkVoltage_Battery]); // BAT AVG sprintf(displayStrings[21], "%d mV", context->voltages[HocClkVoltage_Battery]); // BAT AVG
sprintf(displayStrings[23], "%u%%", context->partLoad[HocClkPartLoad_BAT] / 1000); sprintf(displayStrings[23], "%u%%", context->partLoad[HocClkPartLoad_BAT] / 1000);
sprintf(displayStrings[24], "%u%%", context->partLoad[HocClkPartLoad_FAN]); sprintf(displayStrings[24], "%u%%", context->partLoad[HocClkPartLoad_FAN]);
sprintf(displayStrings[25], "%u Hz", context->realFreqs[HocClkModule_Display]); sprintf(displayStrings[25], "%u Hz", context->realFreqs[HocClkModule_Display]);
if(this->context->isSaltyNXInstalled) { if (this->context->isSaltyNXInstalled) {
if(context->fps == 254) { if (context->fps == 254) {
strcpy(displayStrings[26], "N/A"); strcpy(displayStrings[26], "N/A");
} else { } else {
memset(displayStrings[26], 0, sizeof(displayStrings[26])); memset(displayStrings[26], 0, sizeof(displayStrings[26]));
@@ -322,8 +333,8 @@ void BaseMenuGui::refresh()
} }
} }
if(this->context->isSaltyNXInstalled) { if (this->context->isSaltyNXInstalled) {
if(context->resolutionHeight == 0) { if (context->resolutionHeight == 0) {
strcpy(displayStrings[27], "N/A"); strcpy(displayStrings[27], "N/A");
} else { } else {
memset(displayStrings[27], 0, sizeof(displayStrings[27])); memset(displayStrings[27], 0, sizeof(displayStrings[27]));
@@ -342,13 +353,10 @@ void BaseMenuGui::refresh()
millis = context->temps[HocClkThermalSensor_MEM]; millis = context->temps[HocClkThermalSensor_MEM];
sprintf(displayStrings[30], "%u.%u", millis / 1000U, (millis % 1000U) / 100U); sprintf(displayStrings[30], "%u.%u", millis / 1000U, (millis % 1000U) / 100U);
tempColors[HocClkThermalSensor_MEM] = tsl::GradientColor(millis * 0.001f); tempColors[HocClkThermalSensor_MEM] = tsl::GradientColor(millis * 0.001f);
} }
tsl::elm::Element* BaseMenuGui::baseUI() tsl::elm::Element *BaseMenuGui::baseUI() {
{ auto *list = new tsl::elm::List();
auto* list = new tsl::elm::List();
list->addItem(new tsl::elm::CustomDrawer([](tsl::gfx::Renderer*, s32, s32, s32, s32) {}), 35); // add a bit of space
this->listElement = list; this->listElement = list;
this->listUI(); this->listUI();

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,68 +24,66 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#pragma once #pragma once
#include "../../ipc.h" #include "../../ipc.h"
#include "base_gui.h" #include "base_gui.h"
class BaseMenuGui : public BaseGui class BaseMenuGui : public BaseGui {
{
protected: protected:
public: public:
// u8 dockedHighestAllowedRefreshRate = 60; // u8 dockedHighestAllowedRefreshRate = 60;
HocClkContext* context; HocClkContext *context;
std::uint64_t lastContextUpdate; std::uint64_t lastContextUpdate;
HocClkConfigValueList configList; HocClkConfigValueList configList;
bool g_hardwareModelCached = false; bool g_hardwareModelCached = false;
bool g_isMariko = false; bool g_isMariko = false;
bool g_isAula = false; bool g_isAula = false;
bool g_isHoag = false; bool g_isHoag = false;
SetSysProductModel HWmodel = SetSysProductModel_Invalid; SetSysProductModel HWmodel = SetSysProductModel_Invalid;
bool IsAula() {
if (!g_hardwareModelCached) {
setsysGetProductModel(&HWmodel);
g_hardwareModelCached = true;
}
g_isAula = (HWmodel == SetSysProductModel_Aula);
return g_isAula;
}
bool IsHoag() {
if (!g_hardwareModelCached) {
setsysGetProductModel(&HWmodel);
g_hardwareModelCached = true;
}
g_isHoag = (HWmodel == SetSysProductModel_Hoag);
return g_isHoag;
}
bool IsMariko() {
if (!g_hardwareModelCached) {
setsysGetProductModel(&HWmodel);
g_hardwareModelCached = true;
}
g_isMariko = (HWmodel == SetSysProductModel_Iowa ||
HWmodel == SetSysProductModel_Hoag ||
HWmodel == SetSysProductModel_Calcio ||
HWmodel == SetSysProductModel_Aula);
return g_isMariko; bool IsAula() {
if (!g_hardwareModelCached) {
setsysGetProductModel(&HWmodel);
g_hardwareModelCached = true;
} }
g_isAula = (HWmodel == SetSysProductModel_Aula);
return g_isAula;
}
bool IsHoag() {
if (!g_hardwareModelCached) {
setsysGetProductModel(&HWmodel);
g_hardwareModelCached = true;
}
g_isHoag = (HWmodel == SetSysProductModel_Hoag);
return g_isHoag;
}
bool IsMariko() {
if (!g_hardwareModelCached) {
setsysGetProductModel(&HWmodel);
g_hardwareModelCached = true;
}
g_isMariko = (HWmodel == SetSysProductModel_Iowa || HWmodel == SetSysProductModel_Hoag || HWmodel == SetSysProductModel_Calcio ||
HWmodel == SetSysProductModel_Aula);
bool IsErista() { return g_isMariko;
return !IsMariko(); }
}
BaseMenuGui(); bool IsErista() {
~BaseMenuGui(); return !IsMariko();
void preDraw(tsl::gfx::Renderer* renderer) override; }
tsl::elm::List* listElement; BaseMenuGui();
tsl::elm::Element* baseUI() override; ~BaseMenuGui();
void refresh() override; void preDraw(tsl::gfx::Renderer *renderer) override;
virtual void listUI() = 0; tsl::elm::List *listElement;
tsl::elm::Element *baseUI() override;
void refresh() override;
virtual void listUI() = 0;
u16 headerHeight() const override {
return HOC_BOX_BOTTOM + 9;
}
private: private:
char displayStrings[48][32]; // Pre-formatted display strings char displayStrings[48][32]; // Pre-formatted display strings
tsl::Color tempColors[HocClkThermalSensor_EnumMax]; // Pre-computed temperature colors tsl::Color tempColors[HocClkThermalSensor_EnumMax]; // Pre-computed temperature colors
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,554 @@
/*
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "config_info_strings.h"
std::vector<std::string> ConfigInfoStrings(HocClkConfigValue val, bool isMariko, bool isHoag)
{
switch (val)
{
case HocClkConfigValue_PollingIntervalMs:
return {
"The interval (in milliseconds) where clocks are applied, temperatures and voltages are polled and logs are written (if enabled).",
"Higher values may cause more delay between changing a setting and it taking effect, and lower values may increase sysmodule memory usage",
"Default: 300ms"
};
case HocClkConfigValue_RamDisplayUnit:
return {
"The unit used when displaying RAM frequency values.",
"Options:",
"- MHz: Megahertz (e.g. 1600 MHz)",
"- MT/s: MegaTransfers per second (e.g. 3200 MT/s)",
"- MHz and MT/s: Display in both MHz and MT/s",
"Default: MHz"
};
case HocClkConfigValue_RAMVoltDisplayMode:
return {
"The method used to display RAM voltage values.",
"Options:",
"- VDD2 - Display VDD2 voltage",
"- VDDQ - Display VDDQ voltage",
"Default: VDD2"
};
case HocClkConfigValue_EnableExperimentalSettings:
return {
"When enabled, shows settings that are still being tested and may be unstable or not work at all.",
"Use with caution and report any issues to the developers."
};
case HocClkConfigValue_MarikoMiddleFreqs:
return {
"Allows usage of frequencies stepped by 38.4MHz instead of 76.8MHz below 1228MHz GPU clock",
"Default: OFF"
};
case HocClkConfigValue_LiveCpuUv:
return {
"Allows changing CPU undervolt settings without a reboot",
"Default: OFF"
};
case HocClkConfigValue_GPUSchedulingMethod:
return {
"Method used for GPU scheduling override",
"Options:",
"- INI: override via system_settings.ini",
"- NV Service: override via nvservices sysmodule (experimental)",
"Default: INI"
};
case HocClkConfigValue_MemoryFrequencyMeasurementMode:
return {
"How the RAM real frequency is measured",
"Options:",
"- PLL: Measure from PLLMB and PLLM (more accurate)",
"- Actmon: Measure from Actmon (less accurate)",
"Default: PLL"
};
case HocClkConfigValue_BatteryChargeCurrent:
return {
"Overrides the charge current to the battery. Use with caution!",
isHoag ? "Default: 1664 mA" : "2048 mA"
};
case HocClkConfigValue_InputCurrentLimit:
return {
"Overrides the maximum input current from the charger.",
isHoag ? "Default: 900 mA" : "1200 mA"
};
case HocClkConfigValue_AulaDisplayColorPreset:
return {
"Current display color preset. Default is Basic",
"Options:",
"- Saturated: Based on Vivid but over-saturated.",
"- Washed: Washed out colors.",
"- Basic: Real natural profile.",
"- Natural: Not actually natural.. Extra saturation.",
"- Vivid: Saturated.",
"Default: Do not override"
};
case HocClkConfigValue_CpuGovernorMinimumFreq:
return {
"The minimum frequency that the CPU governor will allow.",
"Default: 612MHz"
};
case HocClkConfigValue_OverwriteRefreshRate:
return {
"Controls the availability of display refresh rate features.",
"When enabled, allows changing the display refresh rate and using display refresh rate related features.",
"This feature conflicts with FPSLocker's feature that does the same thing.",
"Default: OFF"
};
case HocClkConfigValue_MaxDisplayClockH:
return {
"The maximum display clock frequency in handheld mode (in Hz).",
"Warning: Changing this value may cause instability or display damage.",
"Default: 60 Hz"
};
case HocClkConfigValue_DisplayVoltage:
return {
"The voltage supplied to the display panel (in mV).",
"Warning: Changing this value may cause instability.",
"Default: 1200mV"
};
case HocClkConfigValue_UncappedClocks:
if(isMariko) {
return {
"When enabled, disables clock cappings",
"Warning: Enabling this may cause damage to your device without a proper undervolt. Use with caution!",
"Clock cappings:",
"- Handheld:",
" - GPU (No UV): 614 MHz",
" - GPU (SLT): 691 MHz",
" - GPU (HiOPT): 768 MHz",
" - GPU (HiOPT - 15mV): 844 MHz",
" - GPU (High UV): 921 MHz",
"- USB Charger",
" - GPU (No UV): 844 MHz",
" - GPU (SLT): 921 MHz",
" - GPU (HiOPT): 998 MHz",
" - GPU (HiOPT - 15mV): 1075 MHz",
" - GPU (High UV): 1152 MHz",
"- PD Charger / Docked:",
" - No capping applied",
"Default: OFF"
};
} else {
return {
"When enabled, disables clock cappings",
"Warning: Enabling this may cause damage to your device without a proper undervolt. Use with caution!",
"Clock cappings:",
"- Handheld:",
" - GPU: 460 MHz",
" - CPU: 1581 MHz",
"- USB Charger",
" - GPU: 768 MHz",
"- PD Charger / Docked:",
" - No capping applied",
"Default: OFF"
};
}
case HocClkConfigValue_ThermalThrottle:
return {
"If enabled, Resets to stock clocks after the threshold is applied",
"Default: ON",
};
case HocClkConfigValue_ThermalThrottleThreshold:
return {
"The temperature threshold (in °C) for resetting to stock clocks when Thermal Throttle is enabled.",
"Default: 70°C"
};
case KipConfigValue_emcDvbShift:
return {
"Each level adds/removes 25mV from the SOC Voltage table",
"Consoles are bracketed by SoC Speedo. The brackets are as follows:",
" - Speedo 1487-1598: Bracket 0",
" - Speedo 1598-1709: Bracket 1",
" - Speedo 1709-1820: Bracket 2",
"Default: 0"
};
case KipConfigValue_marikoSocVmax:
return {
"The maximum available SOC Voltage that the DVB-adjusted table can use",
"Default: Do not override"
};
case KipConfigValue_hpMode:
return {
"When enabled, disables RAM powerdown. Helps with latency significantly",
"Default: OFF"
};
case KipConfigValue_commonEmcMemVolt:
return {
"RAM VDD2 voltage",
"Increasing this WILL NOT increase your maximum frequency, but may help with timing reduction.",
"Undervolting RAM is pointless and may hurt performance and stability",
"Default: 1175 mV"
};
case KipConfigValue_marikoEmcVddqVolt:
return {
"RAM VDDQ voltage",
"Increasing this may help, but the default value is usually good enough.",
"Undervolting RAM is pointless and may hurt performance and stability",
"Default: 600 mV"
};
case KipConfigValue_stepMode:
return {
"The step that RAM clocks take.",
"Options (with examples):",
" - 66MHz - 66 MHz step (ex. 1600, 1666, 1733, etc.)",
" - 100MHz - 100 MHz step (ex. 1600, 1700, 1800, etc.)",
" - 133MHz - 66 MHz step (ex. 1600, 1733, 1866, etc.)",
" - JEDEC:",
" - 1600, 1866, 1996, 2133, 2400, 2666, 2933 and 3200 MHz are used",
"The RAM max clock will always be available regardless of the step mode, but the intermediate frequencies will be limited by the selected step mode.",
"This setting does not affect performance and the option you choose mostly is based on your personal taste",
"33 MHz step mode is not possible due to certain limitations of Horizon OS",
"Default: 66 MHz",
};
case KipConfigValue_marikoEmcMaxClock:
return {
"The maximum RAM frequency available.",
"Higher frequencies may cause instability, so increase this gradually and test for stability.",
"Default: 2133 MHz"
};
case KipConfigValue_eristaEmcMaxClock:
return {
"The RAM frequency used in the particular slot. Higher frequencies may cause instability, so increase this gradually and test for stability.",
"Default: Disabled (1600 MHz)"
};
case KipConfigValue_t1_tRCD:
return {
"RAS-to-CAS delay",
"Default: 0"
};
case KipConfigValue_t2_tRP:
return {
"Row precharge time",
"Default: 0"
};
case KipConfigValue_t3_tRAS:
return {
"Row active time",
"Default: 0"
};
case KipConfigValue_t4_tRRD:
return {
"Row refresh time",
"Default: 0"
};
case KipConfigValue_t5_tRFC:
return {
"Refresh Cycle Time",
"Default: 0"
};
case KipConfigValue_t6_tRTW:
return {
"Read To Write (High bracket)",
"Default: 0"
};
case KipConfigValue_t7_tWTR:
return {
"Write To Read (High bracket)",
"Default: 0"
};
case KipConfigValue_t8_tREFI:
return {
"Refresh command interval",
"Default: 0"
};
case KipConfigValue_timingEmcTbreak:
return {
"Frequency where t6 and t7 break between the low and high brackets",
"Example:",
"Tbreak is set to 1866 MHz, and t6Low is set to 4 and t6High is set to 2. At frequencies below 1866 MHz, t6 will be 4, and at frequencies above 1866 MHz, t6 will be 2.",
"Default: Disabled"
};
case KipConfigValue_low_t6_tRTW:
return {
"Read To Write (Low bracket)",
"Default: 0"
};
case KipConfigValue_low_t7_tWTR:
return {
"Write To Read (Low bracket)",
"Default: 0"
};
case KipConfigValue_t2_tRP_cap:
return {
"Cap for t2 when 1333WL is used.",
"The default value is sufficient for most RAMs but some may need a lower value",
"Default: 2"
};
case KipConfigValue_t6_tRTW_fine_tune:
return {
"Fine-tunes the raw calculation of t6",
"Default: 0"
};
case KipConfigValue_t7_tWTR_fine_tune:
return {
"Fine-tunes the raw calculation of t7",
"Default: 0"
};
case KipConfigValue_write_latency_1333:
case KipConfigValue_write_latency_1600:
case KipConfigValue_write_latency_1866:
case KipConfigValue_write_latency_2133:
case KipConfigValue_read_latency_1333:
case KipConfigValue_read_latency_1600:
case KipConfigValue_read_latency_1866:
case KipConfigValue_read_latency_2133:
return {
"Latency bracket settings",
"Example:",
"If 1333 is set to 2000 MHz, 1600 set to 2500 MHz, 1866 set to 2766 MHz and 2133 set to 2933 MHz:",
"Frequencies below 2000 MHz use 1333, 2033-2500 MHz use 1600, 2533-2766 MHz use 1866 and 2800-2933 MHz use 2133. ",
"Either of these can be omitted and it will work (say you set 1333 to -, then <2000 MHz will use 1600 latency)",
"If all of these parameters are omitted the latency will automatically be calculated as follows:",
"1633-1866 MHz - 1866 WRL",
"1900+ MHz - 2133 WRL",
"These properties apply for both write and read latencies, and you can mix-and-match the brackets if necessary",
"Default: -"
};
case KipConfigValue_marikoCpuUVLow:
return {
"The CPU UV level used before tBreak",
"Default: 0"
};
case KipConfigValue_marikoCpuUVHigh:
return {
"The CPU UV level used after tBreak",
"Default: 0"
};
case KipConfigValue_tableConf:
return {
"The current UV table used. The tbreaks are as follows:",
"1581 MHz tBreak and 1683 MHz tBreak use their respective tBreaks",
"The other tables use 1581 MHz as tBreak",
"The \"Default\" table does not contain frequencies past 1963 MHz and may not undervolt correctly"
};
case KipConfigValue_marikoCpuLowVmin:
return {
"The CPU vmin used before tBreak",
"Default: 620 mV"
};
case KipConfigValue_marikoCpuHighVmin:
return {
"The CPU vmin used after tBreak",
"Default: 750 mV"
};
case KipConfigValue_marikoCpuMaxVolt:
return {
"The maximum voltage that the CPU can use",
"Change this setting with caution!",
"Default: 1120 mV"
};
case KipConfigValue_marikoCpuMaxClock:
return {
"The maximum available CPU clock",
"Default: 1963 MHz"
};
case KipConfigValue_marikoCpuBoostClock:
return {
"The clock used for the CPU in \"boost mode\"",
"Default: 1963 MHz"
};
case KipConfigValue_eristaCpuUV:
return {
"CPU undervolt level",
"Default: 0"
};
case KipConfigValue_eristaCpuUnlock:
return {
"Unlock unsafe CPU clocks",
"Default: OFF"
};
case KipConfigValue_eristaCpuVmin:
return {
"Minimum CPU voltage",
"Default: 825 mV"
};
case KipConfigValue_eristaCpuMaxVolt:
return {
"Maximum CPU voltage",
"Default: 1235 mV"
};
case HocClkConfigValue_EristaMaxCpuClock:
return {
"The maximum available CPU clock",
"Default: 1785 MHz"
};
case KipConfigValue_eristaCpuBoostClock:
return {
"The clock used for the CPU in \"boost mode\"",
"Default: 1785 MHz"
};
case HocClkConfigValue_AutoRAMCPUOverclock:
return {
"When enabled, automatically raises the CPU clock to the configured OC frequency when RAM clock meets or exceeds the threshold to meet the increased voltage requirement.",
"Default: ON"
};
case HocClkConfigValue_AutoRamCpuCpuOCFreq:
return {
"The CPU clock (in MHz) applied when Auto High RAM CPU OC is enabled and the RAM threshold is met.",
"Default: 1683 MHz"
};
case HocClkConfigValue_AutoRamCpuRamOCThreshold:
return {
"The RAM clock threshold (in MHz) at or above which the Auto High RAM CPU OC will activate.",
"Default: 2133MHz"
};
case HocClkConfigValue_OverwriteBoostMode:
return {
"If enabled, profiles can override the boost mode setting",
"Default: OFF"
};
case KipConfigValue_marikoGpuUV:
return {
"GPU undervolt level",
"Options:",
" - No Undervolt: No Undervolt, HOS default",
" - SLT Table: NVIDIA custom SLT Table",
" - HiOPT: L4T Custom HiOPT table, HOC Default",
" - HiOPT - 15mV: L4T Custom HiOPT table with a 15mV offset",
" - High UV: The highest undervolt table",
"Default: HiOPT"
};
case KipConfigValue_marikoGpuVmin:
return {
"Minimum GPU voltage",
"Note: DVFS may change this value when the RAM clock is changed if the DVFS mode is set to PCV Hijack",
"Default: 610 mV"
};
case KipConfigValue_marikoGpuVmax:
return {
"Maximum GPU voltage",
"Default: 800 mV"
};
case HocClkConfigValue_DVFSMode:
return {
"The mode used for GPU DVFS",
"Adjusts GPU vmin when RAM clock is changed due to a higher requirement",
"Options:",
"- Disabled: disabled...",
"- PCV Hijack: hijack PCV for override",
"Default: PCV Hijack"
};
case HocClkConfigValue_DVFSOffset:
return {
"The offset added/subtracted to the GPU vmin when the RAM clock is changed due to a higher requirement in PCV Hijack mode",
"Default: 0 mV (Disabled)"
};
case KipConfigValue_eristaGpuUV:
return {
"GPU undervolt level",
"Options:",
" - No Undervolt: No Undervolt...",
" - SLT Table: NVIDIA custom SLT Table",
" - HiOPT: L4T Custom HiOPT table",
"Default: No Undervolt"
};
case KipConfigValue_eristaGpuVmin:
return {
"Minimum GPU voltage",
"Default: 810 mV (812mV as erista is stepped by 6.5mV instead of 5mV)"
};
case KipConfigValue_commonGpuVoltOffset:
return {
"The offset added/subtracted to all GPU voltages marked as \"auto\"",
"Default: 0 mV (Disabled)"
};
case HocClkConfigValue_GPUScheduling:
return {
"The scheduling method used for GPU clocks",
"Options:",
"- Do Not Override: Do not override existing scheduling mode",
"- Disabled: Disables GPU scheduling, 99.7% GPU max load",
"- Enabled: Enables GPU scheduling, 96.5% GPU max load",
"Default: Do not override"
};
case KipConfigValue_marikoGpuBootVolt:
return {
"The voltage supplied to the GPU during boot and when the temperature is below 20°C (in mV).",
"Warning: Changing this value may cause instability.",
"Default: 800mV"
};
default:
return {};
}
}

View File

@@ -0,0 +1,24 @@
/*
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <string>
#include <vector>
#include "misc_gui.h"
std::vector<std::string> ConfigInfoStrings(HocClkConfigValue val, bool isMariko, bool isHoag);

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,45 +24,37 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#include "fatal_gui.h" #include "fatal_gui.h"
FatalGui::FatalGui(const std::string message, const std::string info) FatalGui::FatalGui(const std::string message, const std::string info) {
{
this->message = message; this->message = message;
this->info = info; this->info = info;
} }
void FatalGui::openWithResultCode(std::string tag, Result rc) void FatalGui::openWithResultCode(std::string tag, Result rc) {
{
char rcStr[32]; char rcStr[32];
std::string info = tag; std::string info = tag;
info.append(rcStr, snprintf(rcStr, sizeof(rcStr), "\n\n[0x%x] %04d-%04d", rc, R_MODULE(rc), R_DESCRIPTION(rc))); info.append(rcStr, snprintf(rcStr, sizeof(rcStr), "\n\n[0x%x] %04d-%04d", rc, R_MODULE(rc), R_DESCRIPTION(rc)));
tsl::changeTo<FatalGui>( tsl::changeTo<FatalGui>("Could not connect to hoc-clk sysmodule.\n\n"
"Could not connect to hoc-clk sysmodule.\n\n" "\n"
"\n" "Please make sure everything is\n\n"
"Please make sure everything is\n\n" "correctly installed and enabled.",
"correctly installed and enabled.", info);
info
);
} }
tsl::elm::Element* FatalGui::baseUI() tsl::elm::Element *FatalGui::baseUI() {
{ tsl::elm::CustomDrawer *drawer = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) {
tsl::elm::CustomDrawer* drawer = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer* renderer, u16 x, u16 y, u16 w, u16 h) {
renderer->drawString("\uE150", false, 40, 210, 40, TEXT_COLOR); renderer->drawString("\uE150", false, 40, 210, 40, TEXT_COLOR);
renderer->drawString("Fatal error", false, 100, 210, 30, TEXT_COLOR); renderer->drawString("Fatal error", false, 100, 210, 30, TEXT_COLOR);
std::uint32_t txtY = 255; std::uint32_t txtY = 255;
if(!this->message.empty()) if (!this->message.empty()) {
{
txtY += renderer->drawString(this->message.c_str(), false, 40, txtY, 23, TEXT_COLOR).second; txtY += renderer->drawString(this->message.c_str(), false, 40, txtY, 23, TEXT_COLOR).second;
txtY += 55; txtY += 55;
} }
if(!this->info.empty()) if (!this->info.empty()) {
{
renderer->drawString(this->info.c_str(), false, 40, txtY, 18, DESC_COLOR); renderer->drawString(this->info.c_str(), false, 40, txtY, 18, DESC_COLOR);
} }
}); });
@@ -70,11 +62,10 @@ tsl::elm::Element* FatalGui::baseUI()
return drawer; return drawer;
} }
bool FatalGui::handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) bool FatalGui::handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft,
{ HidAnalogStickState joyStickPosRight) {
if((keysDown & HidNpadButton_A) == HidNpadButton_A || (keysDown & HidNpadButton_B) == HidNpadButton_B) if ((keysDown & HidNpadButton_A) == HidNpadButton_A || (keysDown & HidNpadButton_B) == HidNpadButton_B) {
{ while (tsl::Overlay::get()->getCurrentGui() != nullptr) {
while(tsl::Overlay::get()->getCurrentGui() != nullptr) {
tsl::goBack(); tsl::goBack();
} }
return true; return true;

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,23 +24,23 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#pragma once #pragma once
#include <list> #include <list>
#include "base_gui.h" #include "base_gui.h"
class FatalGui : public BaseGui class FatalGui : public BaseGui {
{
protected: protected:
std::string message; std::string message;
std::string info; std::string info;
public: public:
FatalGui(const std::string message, const std::string info); FatalGui(const std::string message, const std::string info);
~FatalGui() {} ~FatalGui() {
tsl::elm::Element* baseUI() override; }
bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight); tsl::elm::Element *baseUI() override;
static void openWithResultCode(std::string tag, Result rc); bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft,
HidAnalogStickState joyStickPosRight);
static void openWithResultCode(std::string tag, Result rc);
}; };

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,20 +24,13 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#include "freq_choice_gui.h"
#include "../format.h" #include "../format.h"
#include "fatal_gui.h" #include "fatal_gui.h"
#include "freq_choice_gui.h"
#include "ult_ext.h"
FreqChoiceGui::FreqChoiceGui(std::uint32_t selectedHz, FreqChoiceGui::FreqChoiceGui(std::uint32_t selectedHz, std::uint32_t *hzList, std::uint32_t hzCount, HocClkModule module, FreqChoiceListener listener,
std::uint32_t* hzList, bool checkMax, std::map<uint32_t, std::string> labels) {
std::uint32_t hzCount,
HocClkModule module,
FreqChoiceListener listener,
bool checkMax,
std::map<uint32_t, std::string> labels)
{
this->selectedHz = selectedHz; this->selectedHz = selectedHz;
this->hzList = hzList; this->hzList = hzList;
this->hzCount = hzCount; this->hzCount = hzCount;
@@ -45,18 +38,16 @@ FreqChoiceGui::FreqChoiceGui(std::uint32_t selectedHz,
this->listener = listener; this->listener = listener;
this->checkMax = checkMax; this->checkMax = checkMax;
this->labels = labels; this->labels = labels;
this->configList = new HocClkConfigValueList {}; this->configList = new HocClkConfigValueList{};
} }
FreqChoiceGui::~FreqChoiceGui() FreqChoiceGui::~FreqChoiceGui() {
{
delete this->configList; delete this->configList;
} }
tsl::elm::ListItem* FreqChoiceGui::createFreqListItem(std::uint32_t hz, bool selected, int safety) tsl::elm::ListItem *FreqChoiceGui::createFreqListItem(std::uint32_t hz, bool selected, int safety) {
{
std::string text; std::string text;
if(module == HocClkModule_MEM) if (module == HocClkModule_MEM)
text = formatListFreqHzMem(hz, (RamDisplayUnit)this->configList->values[HocClkConfigValue_RamDisplayUnit]); text = formatListFreqHzMem(hz, (RamDisplayUnit)this->configList->values[HocClkConfigValue_RamDisplayUnit]);
else else
text = formatListFreqHz(hz); text = formatListFreqHz(hz);
@@ -67,35 +58,32 @@ tsl::elm::ListItem* FreqChoiceGui::createFreqListItem(std::uint32_t hz, bool sel
rightText = it->second; rightText = it->second;
if (selected) if (selected)
const_cast<std::string&>(rightText) = "\uE14B"; const_cast<std::string &>(rightText) = "\uE14B";
tsl::elm::ListItem* listItem = tsl::elm::ListItem *listItem = new tsl::elm::ListItem(text, rightText, false);
new tsl::elm::ListItem(text, rightText, false);
switch (safety) switch (safety) {
{ case 0:
case 0: listItem->setTextColor(tsl::Color(255, 255, 255, 255));
listItem->setTextColor(tsl::Color(255, 255, 255, 255)); listItem->setValueColor(tsl::Color(255, 255, 255, 255));
listItem->setValueColor(tsl::Color(255, 255, 255, 255)); break;
break; case 1:
case 1: listItem->setTextColor(tsl::Color(255, 165, 0, 255));
listItem->setTextColor(tsl::Color(255, 165, 0, 255)); listItem->setValueColor(tsl::Color(255, 165, 0, 255));
listItem->setValueColor(tsl::Color(255, 165, 0, 255)); break;
break; case 2:
case 2: listItem->setTextColor(tsl::Color(255, 0, 0, 255));
listItem->setTextColor(tsl::Color(255, 0, 0, 255)); listItem->setValueColor(tsl::Color(255, 0, 0, 255));
listItem->setValueColor(tsl::Color(255, 0, 0, 255)); break;
break;
} }
// Make annotation grey // Make annotation grey
if (!rightText.empty() && !selected) if (!rightText.empty() && !selected)
listItem->setValueColor(tsl::Color(180, 180, 180, 255)); listItem->setValueColor(tsl::Color(180, 180, 180, 255));
else if(selected) else if (selected)
listItem->setValueColor(tsl::infoTextColor); listItem->setValueColor(tsl::infoTextColor);
listItem->setClickListener([this, hz](u64 keys) listItem->setClickListener([this, hz](u64 keys) {
{
if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) { if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) {
if (this->listener(hz)) { if (this->listener(hz)) {
tsl::goBack(); tsl::goBack();
@@ -108,8 +96,7 @@ tsl::elm::ListItem* FreqChoiceGui::createFreqListItem(std::uint32_t hz, bool sel
return listItem; return listItem;
} }
void FreqChoiceGui::listUI() void FreqChoiceGui::listUI() {
{
hocclkIpcGetConfigValues(this->configList); hocclkIpcGetConfigValues(this->configList);
// Header based on CPU/GPU/MEM module // Header based on CPU/GPU/MEM module
@@ -117,11 +104,9 @@ void FreqChoiceGui::listUI()
this->listElement->addItem(new tsl::elm::CategoryHeader(moduleName)); this->listElement->addItem(new tsl::elm::CategoryHeader(moduleName));
// Default option // Default option
this->listElement->addItem( this->listElement->addItem(this->createFreqListItem(0, this->selectedHz == 0, 0));
this->createFreqListItem(0, this->selectedHz == 0, 0));
for (std::uint32_t i = 0; i < this->hzCount; i++) for (std::uint32_t i = 0; i < this->hzCount; i++) {
{
std::uint32_t hz = this->hzList[i]; std::uint32_t hz = this->hzList[i];
uint32_t mhz = hz / 1000000; uint32_t mhz = hz / 1000000;
@@ -159,23 +144,14 @@ void FreqChoiceGui::listUI()
uint32_t danger_cpu; uint32_t danger_cpu;
uint32_t danger_gpu; uint32_t danger_gpu;
if (IsMariko()) if (IsMariko()) {
{
unsafe_cpu = this->configList->values[KipConfigValue_marikoCpuUVHigh] ? 2398 : 1964; unsafe_cpu = this->configList->values[KipConfigValue_marikoCpuUVHigh] ? 2398 : 1964;
if(this->configList->values[KipConfigValue_marikoGpuUV] == 0) { unsafe_gpu = 1229;
unsafe_gpu = 1076;
} else if (this->configList->values[KipConfigValue_marikoGpuUV] == 1) {
unsafe_gpu = 1153;
} else {
unsafe_gpu = 1229;
}
danger_cpu = this->configList->values[KipConfigValue_marikoCpuUVHigh] ? 2500 : 2398; danger_cpu = this->configList->values[KipConfigValue_marikoCpuUVHigh] ? 2500 : 2398;
danger_gpu = 1306; danger_gpu = 1306;
} } else {
else
{
unsafe_cpu = this->configList->values[KipConfigValue_eristaCpuUV] ? 2092 : 1786; unsafe_cpu = this->configList->values[KipConfigValue_eristaCpuUV] ? 2092 : 1786;
if(this->configList->values[KipConfigValue_eristaGpuUV] == 0) { if (this->configList->values[KipConfigValue_eristaGpuUV] == GPUUVLevel_NoUV) {
unsafe_gpu = 922; unsafe_gpu = 922;
} else { } else {
unsafe_gpu = 961; unsafe_gpu = 961;
@@ -207,16 +183,9 @@ void FreqChoiceGui::listUI()
} else if (moduleName == "mem") { } else if (moduleName == "mem") {
safety = 0; safety = 0;
} }
this->listElement->addItem( this->listElement->addItem(this->createFreqListItem(hz, (mhz == this->selectedHz / 1000000), safety));
this->createFreqListItem(
hz,
(mhz == this->selectedHz / 1000000),
safety
)
);
} }
this->listElement->jumpToItem("", ""); this->listElement->jumpToItem("", "");

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,22 +24,21 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#pragma once #pragma once
#include <list>
#include <functional> #include <functional>
#include <list>
#include <map> #include <map>
#include "base_menu_gui.h" #include "base_menu_gui.h"
using FreqChoiceListener = std::function<bool(std::uint32_t hz)>; using FreqChoiceListener = std::function<bool(std::uint32_t hz)>;
class FreqChoiceGui : public BaseMenuGui class FreqChoiceGui : public BaseMenuGui {
{ protected:
protected: HocClkConfigValueList *configList;
HocClkConfigValueList* configList;
std::uint32_t selectedHz; std::uint32_t selectedHz;
std::uint32_t* hzList; std::uint32_t *hzList;
std::uint32_t hzCount; std::uint32_t hzCount;
HocClkModule module; HocClkModule module;
FreqChoiceListener listener; FreqChoiceListener listener;
@@ -47,16 +46,11 @@ protected:
std::map<uint32_t, std::string> labels; std::map<uint32_t, std::string> labels;
tsl::elm::ListItem* createFreqListItem(std::uint32_t hz, bool selected, int safety); tsl::elm::ListItem *createFreqListItem(std::uint32_t hz, bool selected, int safety);
public: public:
FreqChoiceGui(std::uint32_t selectedHz, FreqChoiceGui(std::uint32_t selectedHz, std::uint32_t *hzList, std::uint32_t hzCount, HocClkModule module, FreqChoiceListener listener,
std::uint32_t* hzList, bool checkMax = true, std::map<uint32_t, std::string> labels = {});
std::uint32_t hzCount,
HocClkModule module,
FreqChoiceListener listener,
bool checkMax = true,
std::map<uint32_t, std::string> labels = {});
~FreqChoiceGui(); ~FreqChoiceGui();

View File

@@ -16,6 +16,7 @@
* *
*/ */
#include "ult_ext.h"
#include "../format.h" #include "../format.h"
#include "fatal_gui.h" #include "fatal_gui.h"
#include "global_override_gui.h" #include "global_override_gui.h"

View File

@@ -13,9 +13,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -25,50 +25,33 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#pragma once #pragma once
#include <string>
#include "../../ipc.h" #include "../../ipc.h"
#include "base_menu_gui.h" #include "base_menu_gui.h"
#include "freq_choice_gui.h" #include "freq_choice_gui.h"
#include <string>
#include "value_choice_gui.h" #include "value_choice_gui.h"
class GlobalOverrideGui : public BaseMenuGui class GlobalOverrideGui : public BaseMenuGui {
{
protected: protected:
std::map<HocClkModule, std::tuple<std::string, std::uint32_t, int>> customFormatModules; std::map<HocClkModule, std::tuple<std::string, std::uint32_t, int>> customFormatModules;
tsl::elm::ListItem* listItems[HocClkModule_EnumMax]; tsl::elm::ListItem *listItems[HocClkModule_EnumMax];
std::uint32_t listHz[HocClkModule_EnumMax]; std::uint32_t listHz[HocClkModule_EnumMax];
void openFreqChoiceGui(HocClkModule module); void openFreqChoiceGui(HocClkModule module);
void addGovernorSection(); void addGovernorSection();
void addModuleListItem(HocClkModule module); void addModuleListItem(HocClkModule module);
void addModuleToggleItem(HocClkModule module); void addModuleToggleItem(HocClkModule module);
void openValueChoiceGui( void openValueChoiceGui(tsl::elm::ListItem *listItem, std::uint32_t currentValue, const ValueRange &range, const std::string &categoryName,
tsl::elm::ListItem* listItem, ValueChoiceListener listener, const ValueThresholds &thresholds, bool enableThresholds,
std::uint32_t currentValue, const std::map<std::uint32_t, std::string> &labels, const std::vector<NamedValue> &namedValues, bool showDefaultValue);
const ValueRange& range, void addModuleListItemValue(HocClkModule module, const std::string &categoryName, std::uint32_t min, std::uint32_t max, std::uint32_t step,
const std::string& categoryName, const std::string &suffix, std::uint32_t divisor, int decimalPlaces, ValueThresholds thresholds = {},
ValueChoiceListener listener, const std::vector<NamedValue> &namedValues = {}, bool showDefaultValue = true);
const ValueThresholds& thresholds,
bool enableThresholds,
const std::map<std::uint32_t, std::string>& labels,
const std::vector<NamedValue>& namedValues,
bool showDefaultValue
);
void addModuleListItemValue(
HocClkModule module,
const std::string& categoryName,
std::uint32_t min,
std::uint32_t max,
std::uint32_t step,
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces,
ValueThresholds thresholds = {},
const std::vector<NamedValue>& namedValues = {},
bool showDefaultValue = true
);
public: public:
GlobalOverrideGui(); GlobalOverrideGui();
~GlobalOverrideGui() {} ~GlobalOverrideGui() {
void listUI() override; }
void refresh() override; void listUI() override;
void setModuleCustomFormat(HocClkModule module, const std::string& suffix, std::uint32_t divisor, int decimalPlaces); void refresh() override;
void setModuleCustomFormat(HocClkModule module, const std::string &suffix, std::uint32_t divisor, int decimalPlaces);
}; };

View File

@@ -0,0 +1,86 @@
/*
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include <sstream>
#include "info_gui.h"
#include "ult_ext.h"
InfoGui::InfoGui(std::string title, std::vector<std::string> strings) : m_title(std::move(title)), m_strings(std::move(strings)) {
}
static constexpr s32 TEXT_SIZE = 16;
static constexpr s32 LINE_H = 22;
static constexpr s32 PARA_GAP = 10;
static constexpr s32 MARGIN_L = 20;
static constexpr s32 MARGIN_R = 35;
static std::vector<std::string> wrapText(const std::string &text, s32 maxWidth) {
constexpr float CHAR_W = 10.0f;
// Preserve leading whitespace as an indent prefix for wrapped continuation lines.
std::string indent;
for (char c : text) {
if (c == ' ')
indent += ' ';
else
break;
}
std::vector<std::string> lines;
std::istringstream ss(text);
std::string word, line = indent; // seed with indent so first word inherits it
bool first = true;
while (ss >> word) {
std::string candidate = (first && !indent.empty()) ? indent + word : line.empty() ? word : line + " " + word;
first = false;
if (static_cast<s32>(candidate.size() * CHAR_W) <= maxWidth)
line = std::move(candidate);
else {
if (!line.empty() && line != indent)
lines.push_back(line);
line = indent + word;
}
}
if (!line.empty() && line != indent)
lines.push_back(line);
if (lines.empty())
lines.emplace_back("");
return lines;
}
void InfoGui::listUI() {
this->listElement->addItem(new tsl::elm::CategoryHeader(m_title));
const s32 maxWidth = tsl::cfg::FramebufferWidth - MARGIN_L - MARGIN_R;
for (const auto &para : m_strings) {
for (const auto &lineText : wrapText(para, maxWidth)) {
auto *d = new FocusableDrawer([lineText](tsl::gfx::Renderer *r, s32 x, s32 y, s32 w, s32 h) {
r->drawString((lineText + "\n").c_str(), false, x + MARGIN_L, y + LINE_H - 5, TEXT_SIZE, tsl::style::color::ColorText);
});
d->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, LINE_H);
this->listElement->addItem(d, LINE_H);
}
// paragraph gap
auto *gap = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *, s32, s32, s32, s32) {});
gap->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, PARA_GAP);
this->listElement->addItem(gap, PARA_GAP);
}
}

View File

@@ -0,0 +1,33 @@
/*
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <string>
#include <vector>
#include "base_menu_gui.h"
class InfoGui : public BaseMenuGui {
public:
InfoGui(std::string title, std::vector<std::string> strings);
~InfoGui() = default;
void listUI() override;
private:
std::string m_title;
std::vector<std::string> m_strings;
};

View File

@@ -12,122 +12,73 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#include <map>
#include <cstdint> #include <cstdint>
#include <map>
#include <string> #include <string>
std::map<uint32_t, std::string> cpu_freq_label_m = { std::map<uint32_t, std::string> cpu_freq_label_m = {
{612000000, "Sleep Mode"}, { 612000000, "Sleep Mode" }, { 1020000000, "Stock" }, { 1224000000, "Dev OC" }, { 1785000000, "Boost Mode" },
{1020000000, "Stock"}, { 1963000000, "Safe Max" }, { 2397000000, "Unsafe Max" }, { 2703000000, "Absolute Max" },
{1224000000, "Dev OC"},
{1785000000, "Boost Mode"},
{1963000000, "Safe Max"},
{2397000000, "Unsafe Max"},
{2703000000, "Absolute Max"},
}; };
std::map<uint32_t, std::string> cpu_freq_label_m_uv = { std::map<uint32_t, std::string> cpu_freq_label_m_uv = {
{612000000, "Sleep Mode"}, { 612000000, "Sleep Mode" }, { 1020000000, "Stock" }, { 1224000000, "Dev OC" }, { 1785000000, "Boost Mode" },
{1020000000, "Stock"}, { 2397000000, "Safe Max" }, { 2499000000, "Unsafe Max" }, { 2703000000, "Absolute Max" },
{1224000000, "Dev OC"},
{1785000000, "Boost Mode"},
{2397000000, "Safe Max"},
{2499000000, "Unsafe Max"},
{2703000000, "Absolute Max"},
}; };
std::map<uint32_t, std::string> cpu_freq_label_e = { std::map<uint32_t, std::string> cpu_freq_label_e = {
{612000000, "Sleep Mode"}, { 612000000, "Sleep Mode" }, { 1020000000, "Stock" }, { 1224000000, "Dev OC" },
{1020000000, "Stock"}, { 1785000000, "Safe Max" }, { 2091000000, "Unsafe Max" }, { 2397000000, "Absolute Max" },
{1224000000, "Dev OC"},
{1785000000, "Safe Max"},
{2091000000, "Unsafe Max"},
{2397000000, "Absolute Max"},
}; };
std::map<uint32_t, std::string> cpu_freq_label_e_uv = { std::map<uint32_t, std::string> cpu_freq_label_e_uv = {
{612000000, "Sleep Mode"}, { 612000000, "Sleep Mode" }, { 1020000000, "Stock" }, { 1224000000, "Dev OC" }, { 1785000000, "Boost Mode" },
{1020000000, "Stock"}, { 2091000000, "Safe Max" }, { 2193000000, "Unsafe Max" }, { 2397000000, "Absolute Max" },
{1224000000, "Dev OC"},
{1785000000, "Boost Mode"},
{2091000000, "Safe Max"},
{2193000000, "Unsafe Max"},
{2397000000, "Absolute Max"},
}; };
std::map<uint32_t, std::string> gpu_freq_label_e = { std::map<uint32_t, std::string> gpu_freq_label_e = {
{76800000, "Boost Mode"}, { 76800000, "Boost Mode" }, { 307200000, "Handheld" }, { 345600000, "Handheld" }, { 384000000, "Handheld" },
{307200000, "Handheld"}, { 422400000, "Handheld" }, { 460800000, "Handheld Safe Max" }, { 768000000, "Docked" }, { 921600000, "Safe Max" },
{345600000, "Handheld"}, { 960000000, "Unsafe Max" }, { 1075200000, "Absolute Max" },
{384000000, "Handheld"},
{422400000, "Handheld"},
{460800000, "Handheld Safe Max"},
{768000000, "Docked"},
{921600000, "Safe Max"},
{960000000, "Unsafe Max"},
{1075200000, "Absolute Max"},
}; };
std::map<uint32_t, std::string> gpu_freq_label_e_uv = { std::map<uint32_t, std::string> gpu_freq_label_e_uv = {
{76800000, "Boost Mode"}, { 76800000, "Boost Mode" }, { 307200000, "Handheld" }, { 345600000, "Handheld" },
{307200000, "Handheld"}, { 384000000, "Handheld" }, { 422400000, "Handheld" }, { 460800000, "Handheld Safe Max" },
{345600000, "Handheld"}, { 768000000, "Docked" }, { 960000000, "Safe Max" }, { 1075200000, "Absolute Max" },
{384000000, "Handheld"},
{422400000, "Handheld"},
{460800000, "Handheld Safe Max"},
{768000000, "Docked"},
{960000000, "Safe Max"},
{1075200000, "Absolute Max"},
}; };
std::map<uint32_t, std::string> gpu_freq_label_m = { std::map<uint32_t, std::string> gpu_freq_label_m = {
{76800000, "Boost Mode"}, { 76800000, "Boost Mode" }, { 307200000, "Handheld" }, { 345600000, "Handheld" }, { 384000000, "Handheld" }, { 422400000, "Handheld" },
{307200000, "Handheld"}, { 460800000, "Handheld" }, { 614400000, "Handheld Safe Max" }, { 768000000, "Docked" }, { 998400000, "Safe Max" },
{384000000, "Handheld"},
{460800000, "Handheld"},
{614400000, "Handheld Safe Max"},
{768000000, "Docked"},
{1075200000, "Safe Max"},
{1305600000, "Unsafe Max"},
{1536000000, "Absolute Max"},
}; };
std::map<uint32_t, std::string> gpu_freq_label_m_slt = { std::map<uint32_t, std::string> gpu_freq_label_m_slt = {
{76800000, "Boost Mode"}, { 76800000, "Boost Mode" }, { 307200000, "Handheld" }, { 345600000, "Handheld" }, { 384000000, "Handheld" },
{307200000, "Handheld"}, { 422400000, "Handheld" }, { 460800000, "Handheld" }, { 614400000, "Handheld Safe Max" }, { 768000000, "Docked" },
{384000000, "Handheld"}, { 1075200000, "Safe Max" }, { 1305600000, "Unsafe Max" }, { 1536000000, "Absolute Max" },
{460800000, "Handheld"},
{614400000, "Handheld Safe Max"},
{768000000, "Docked"},
{1152200000, "Safe Max"},
{1305600000, "Unsafe Max"},
{1536000000, "Absolute Max"},
}; };
std::map<uint32_t, std::string> gpu_freq_label_m_hiopt = { std::map<uint32_t, std::string> gpu_freq_label_m_hiopt = {
{76800000, "Boost Mode"}, { 76800000, "Boost Mode" }, { 307200000, "Handheld" }, { 345600000, "Handheld" }, { 384000000, "Handheld" },
{307200000, "Handheld"}, { 422400000, "Handheld" }, { 460800000, "Handheld" }, { 614400000, "Handheld Safe Max" }, { 768000000, "Docked" },
{384000000, "Handheld"}, { 1152000000, "Safe Max" }, { 1305600000, "Unsafe Max" }, { 1536000000, "Absolute Max" },
{460800000, "Handheld"},
{614400000, "Handheld Safe Max"},
{768000000, "Docked"},
{1228800000, "Safe Max"},
{1305600000, "Unsafe Max"},
{1536000000, "Absolute Max"},
}; };
std::map<uint32_t, std::string>* marikoUV[3] { std::map<uint32_t, std::string> gpu_freq_label_m_highuv = {
&gpu_freq_label_m, { 76800000, "Boost Mode" }, { 307200000, "Handheld" }, { 384000000, "Handheld" },
&gpu_freq_label_m_slt, { 460800000, "Handheld" }, { 614400000, "Handheld Safe Max" }, { 768000000, "Docked" },
&gpu_freq_label_m_hiopt, { 1228800000, "Safe Max" }, { 1305600000, "Unsafe Max" }, { 1536000000, "Absolute Max" },
}; };
std::map<uint32_t, std::string> *marikoUV[5]{
&gpu_freq_label_m, &gpu_freq_label_m_slt, &gpu_freq_label_m_hiopt, &gpu_freq_label_m_hiopt, &gpu_freq_label_m_highuv,
};
std::map<uint32_t, std::string>* eristaUV[3] { std::map<uint32_t, std::string> *eristaUV[3]{
&gpu_freq_label_e, &gpu_freq_label_e,
&gpu_freq_label_e_uv, &gpu_freq_label_e_uv,
&gpu_freq_label_e_uv, &gpu_freq_label_e_uv,

View File

@@ -27,8 +27,10 @@ extern std::map<uint32_t, std::string> cpu_freq_label_e_uv;
extern std::map<uint32_t, std::string> gpu_freq_label_m; extern std::map<uint32_t, std::string> gpu_freq_label_m;
extern std::map<uint32_t, std::string> gpu_freq_label_m_slt; extern std::map<uint32_t, std::string> gpu_freq_label_m_slt;
extern std::map<uint32_t, std::string> gpu_freq_label_m_hiopt; extern std::map<uint32_t, std::string> gpu_freq_label_m_hiopt;
extern std::map<uint32_t, std::string> gpu_freq_label_m_highuv;
extern std::map<uint32_t, std::string> gpu_freq_label_e; extern std::map<uint32_t, std::string> gpu_freq_label_e;
extern std::map<uint32_t, std::string> gpu_freq_label_e_uv; extern std::map<uint32_t, std::string> gpu_freq_label_e_uv;
extern std::map<uint32_t, std::string>* marikoUV[3]; extern std::map<uint32_t, std::string>* marikoUV[5];
extern std::map<uint32_t, std::string>* eristaUV[3]; extern std::map<uint32_t, std::string>* eristaUV[3];

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,17 +24,23 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#include "main_gui.h"
#include "fatal_gui.h"
#include "app_profile_gui.h"
#include "global_override_gui.h"
#include "misc_gui.h"
#include "about_gui.h" #include "about_gui.h"
#include "app_profile_gui.h"
#include "fatal_gui.h"
#include "global_override_gui.h"
#include "main_gui.h"
#include "misc_gui.h"
#include "ult_ext.h"
void MainGui::listUI()
{ tsl::elm::Element *MainGui::baseUI() {
auto *list = new BoxClippedList();
this->listElement = list;
this->listUI();
return list;
}
void MainGui::listUI() {
// this->enabledToggle = new tsl::elm::ToggleListItem("Enable", false); // this->enabledToggle = new tsl::elm::ToggleListItem("Enable", false);
// enabledToggle->setStateChangedListener([this](bool state) { // enabledToggle->setStateChangedListener([this](bool state) {
// Result rc = hocclkIpcSetEnabled(state); // Result rc = hocclkIpcSetEnabled(state);
@@ -48,10 +54,9 @@ void MainGui::listUI()
// }); // });
// this->listElement->addItem(this->enabledToggle); // this->listElement->addItem(this->enabledToggle);
tsl::elm::ListItem* appProfileItem = new tsl::elm::ListItem("Edit App Profile"); tsl::elm::ListItem *appProfileItem = new tsl::elm::ListItem("Edit App Profile");
appProfileItem->setClickListener([this](u64 keys) { appProfileItem->setClickListener([this](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A && this->context) if ((keys & HidNpadButton_A) == HidNpadButton_A && this->context) {
{
AppProfileGui::changeTo(this->context->applicationId); AppProfileGui::changeTo(this->context->applicationId);
return true; return true;
} }
@@ -60,11 +65,9 @@ void MainGui::listUI()
}); });
this->listElement->addItem(appProfileItem); this->listElement->addItem(appProfileItem);
tsl::elm::ListItem *globalProfileItem = new tsl::elm::ListItem("Edit Global Profile");
tsl::elm::ListItem* globalProfileItem = new tsl::elm::ListItem("Edit Global Profile");
globalProfileItem->setClickListener([this](u64 keys) { globalProfileItem->setClickListener([this](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A && this->context) if ((keys & HidNpadButton_A) == HidNpadButton_A && this->context) {
{
AppProfileGui::changeTo(HOCCLK_GLOBAL_PROFILE_TID); AppProfileGui::changeTo(HOCCLK_GLOBAL_PROFILE_TID);
return true; return true;
} }
@@ -73,10 +76,9 @@ void MainGui::listUI()
}); });
this->listElement->addItem(globalProfileItem); this->listElement->addItem(globalProfileItem);
tsl::elm::ListItem* globalOverrideItem = new tsl::elm::ListItem("Temporary Overrides"); tsl::elm::ListItem *globalOverrideItem = new tsl::elm::ListItem("Temporary Overrides");
globalOverrideItem->setClickListener([this](u64 keys) { globalOverrideItem->setClickListener([this](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A && this->context) if ((keys & HidNpadButton_A) == HidNpadButton_A && this->context) {
{
tsl::changeTo<GlobalOverrideGui>(); tsl::changeTo<GlobalOverrideGui>();
return true; return true;
} }
@@ -85,12 +87,11 @@ void MainGui::listUI()
}); });
this->listElement->addItem(globalOverrideItem); this->listElement->addItem(globalOverrideItem);
//this->listElement->addItem(new tsl::elm::CategoryHeader("Misc")); // this->listElement->addItem(new tsl::elm::CategoryHeader("Misc"));
tsl::elm::ListItem* miscItem = new tsl::elm::ListItem("Settings"); tsl::elm::ListItem *miscItem = new tsl::elm::ListItem("Settings");
miscItem->setClickListener([this](u64 keys) { miscItem->setClickListener([this](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A && this->context) if ((keys & HidNpadButton_A) == HidNpadButton_A && this->context) {
{
tsl::changeTo<MiscGui>(); tsl::changeTo<MiscGui>();
return true; return true;
} }
@@ -99,10 +100,9 @@ void MainGui::listUI()
}); });
this->listElement->addItem(miscItem); this->listElement->addItem(miscItem);
tsl::elm::ListItem* aboutItem = new tsl::elm::ListItem("About"); tsl::elm::ListItem *aboutItem = new tsl::elm::ListItem("About");
aboutItem->setClickListener([this](u64 keys) { aboutItem->setClickListener([this](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A && this->context) if ((keys & HidNpadButton_A) == HidNpadButton_A && this->context) {
{
tsl::changeTo<AboutGui>(); tsl::changeTo<AboutGui>();
return true; return true;
} }
@@ -110,14 +110,12 @@ void MainGui::listUI()
return false; return false;
}); });
this->listElement->addItem(aboutItem); this->listElement->addItem(aboutItem);
} }
void MainGui::refresh() void MainGui::refresh() {
{
BaseMenuGui::refresh(); BaseMenuGui::refresh();
//if(this->context) // if(this->context)
//{ //{
// this->enabledToggle->setState(this->context->enabled); // this->enabledToggle->setState(this->context->enabled);
//} // }
} }

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,16 +24,20 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#pragma once #pragma once
#include "base_menu_gui.h" #include "base_menu_gui.h"
class MainGui : public BaseMenuGui class MainGui : public BaseMenuGui {
{
public: public:
MainGui() {} MainGui() {
~MainGui() {} }
void listUI() override; ~MainGui() {
void refresh() override; }
tsl::elm::Element *baseUI() override;
void listUI() override;
void refresh() override;
u16 headerHeight() const override {
return HOC_HEADER_HEIGHT - 25;
}
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -16,60 +16,51 @@
* *
*/ */
#pragma once #pragma once
#include "../../ipc.h"
#include "base_menu_gui.h"
#include <set> #include <set>
#include <unordered_map>
#include <string> #include <string>
#include <vector> #include <vector>
#include "../../ipc.h"
#include "base_menu_gui.h"
#include "freq_choice_gui.h" #include "freq_choice_gui.h"
#include "info_gui.h"
#include "value_choice_gui.h" #include "value_choice_gui.h"
class MiscGui : public BaseMenuGui #include <initializer_list>
{ #include <unordered_map>
public: class MiscGui : public BaseMenuGui {
public:
MiscGui(); MiscGui();
~MiscGui(); ~MiscGui();
void listUI() override; void listUI() override;
void refresh() override; void refresh() override;
protected: protected:
HocClkConfigValueList* configList; HocClkConfigValueList *configList;
std::map<HocClkConfigValue, tsl::elm::ListItem*> configButtons; std::map<HocClkConfigValue, tsl::elm::ListItem *> configButtons;
std::map<HocClkConfigValue, ValueRange> configRanges; std::map<HocClkConfigValue, ValueRange> configRanges;
std::map<HocClkConfigValue, std::vector<NamedValue>> configNamedValues; std::map<HocClkConfigValue, std::vector<NamedValue>> configNamedValues;
std::map<HocClkConfigValue, tsl::elm::ToggleListItem*> configToggles; std::map<HocClkConfigValue, tsl::elm::ToggleListItem *> configToggles;
std::map<HocClkConfigValue, std::tuple<tsl::elm::TrackBar*, tsl::elm::ListItem*, std::vector<uint64_t>>> configTrackbars; std::map<HocClkConfigValue, std::tuple<tsl::elm::TrackBar *, tsl::elm::ListItem *, std::vector<uint64_t>>> configTrackbars;
std::set<HocClkConfigValue> configButtonSKeys; std::set<HocClkConfigValue> configButtonSKeys;
std::map<HocClkConfigValue, std::string> configButtonSSubtext; std::map<HocClkConfigValue, std::string> configButtonSSubtext;
std::set<HocClkConfigValue> emcClockConfigs; std::set<HocClkConfigValue> emcClockConfigs;
void addConfigToggle(HocClkConfigValue configVal, const char* altName, bool kip = false);
void addConfigButton(HocClkConfigValue configVal,
const char* altName,
const ValueRange& range,
const std::string& categoryName,
const ValueThresholds* thresholds,
const std::map<uint32_t, std::string>& labels = {},
const std::vector<NamedValue>& namedValues = {},
bool showDefaultValue = true,
bool kip = false);
void addConfigButtonS(HocClkConfigValue configVal, void addConfigToggle(HocClkConfigValue configVal, const char *altName, bool kip = false);
const char* altName, void addConfigTrackbar(HocClkConfigValue configVal, const char *altName, const ValueRange &range, bool kip = true);
const ValueRange& range, void addMappedConfigTrackbar(HocClkConfigValue configVal, const char *altName, std::vector<u32> vals, std::initializer_list<std::string> names,
const std::string& categoryName, bool kip = true);
const ValueThresholds* thresholds, void addConfigButton(HocClkConfigValue configVal, const char *altName, const ValueRange &range, const std::string &categoryName,
const std::map<uint32_t, std::string>& labels = {}, const ValueThresholds *thresholds, const std::map<uint32_t, std::string> &labels = {},
const std::vector<NamedValue>& namedValues = {}, const std::vector<NamedValue> &namedValues = {}, bool showDefaultValue = true, bool kip = false);
bool showDefaultValue = true,
const char* subText = nullptr, void addConfigButtonS(HocClkConfigValue configVal, const char *altName, const ValueRange &range, const std::string &categoryName,
bool kip = false); const ValueThresholds *thresholds, const std::map<uint32_t, std::string> &labels = {},
void addFreqButton(HocClkConfigValue configVal, const std::vector<NamedValue> &namedValues = {}, bool showDefaultValue = true, const char *subText = nullptr,
const char* altName, bool kip = false);
HocClkModule module, void addFreqButton(HocClkConfigValue configVal, const char *altName, HocClkModule module, const std::map<uint32_t, std::string> &labels = {});
const std::map<uint32_t, std::string>& labels = {});
void updateConfigToggles(); void updateConfigToggles();
tsl::elm::ToggleListItem* enabledToggle; tsl::elm::ToggleListItem *enabledToggle;
u8 frameCounter = 60; u8 frameCounter = 60;
}; bool shouldSaveKip = false;
};

View File

@@ -12,40 +12,62 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#pragma once #pragma once
#include <tesla.hpp> #include <tesla.hpp>
#include "../elements/base_frame.h"
class TopAnchoredList : public tsl::elm::List {
public:
TopAnchoredList() {
m_hasSetInitialFocusHack = true;
}
};
class BoxClippedList : public tsl::elm::List {
public:
void draw(tsl::gfx::Renderer *renderer) override {
renderer->enableScissoring(0, HOC_BOX_BOTTOM, tsl::cfg::FramebufferWidth, tsl::cfg::FramebufferHeight - HOC_BOX_BOTTOM);
tsl::elm::List::draw(renderer);
renderer->disableScissoring();
}
};
class CompactCategoryHeader : public tsl::elm::CategoryHeader {
public:
CompactCategoryHeader(const std::string &text) : tsl::elm::CategoryHeader(text) {
}
void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight) override {
this->setBoundaries(this->getX(), this->getY(), this->getWidth(), 33);
}
};
class ImageElement : public tsl::elm::ListItem { class ImageElement : public tsl::elm::ListItem {
private: private:
const uint8_t* imgData; const uint8_t *imgData;
uint32_t imgWidth, imgHeight; uint32_t imgWidth, imgHeight;
bool visible; bool visible;
public: public:
ImageElement(const uint8_t* data, uint32_t w, uint32_t h) ImageElement(const uint8_t *data, uint32_t w, uint32_t h) : tsl::elm::ListItem(""), imgData(data), imgWidth(w), imgHeight(h), visible(true) {
: tsl::elm::ListItem(""), imgData(data), imgWidth(w), imgHeight(h), visible(true) {} }
void setVisible(bool v) { void setVisible(bool v) {
visible = v; visible = v;
} }
virtual void draw(tsl::gfx::Renderer *renderer) override { virtual void draw(tsl::gfx::Renderer *renderer) override {
if (!visible) return; if (!visible)
return;
// Draw image centered horizontally // Draw image centered horizontally
u16 centerX = this->getX() + (this->getWidth() - imgWidth) / 2; u16 centerX = this->getX() + (this->getWidth() - imgWidth) / 2;
renderer->drawBitmap( renderer->drawBitmap(centerX, this->getY() + 10, imgWidth, imgHeight, imgData);
centerX,
this->getY() + 10,
imgWidth,
imgHeight,
imgData
);
} }
virtual void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight) override { virtual void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight) override {
if (!visible) { if (!visible) {
// Take up no space when hidden // Take up no space when hidden
@@ -55,37 +77,38 @@ public:
tsl::elm::ListItem::layout(parentX, parentY, parentWidth, parentHeight); tsl::elm::ListItem::layout(parentX, parentY, parentWidth, parentHeight);
} }
} }
virtual void drawHighlight(tsl::gfx::Renderer *renderer) override { virtual void drawHighlight(tsl::gfx::Renderer *renderer) override {
// Do nothing - no highlight // Do nothing - no highlight
} }
virtual bool onClick(u64 keys) override { virtual bool onClick(u64 keys) override {
return false; // Non-clickable return false; // Non-clickable
} }
virtual Element* requestFocus(Element *oldFocus, tsl::FocusDirection direction) override { virtual Element *requestFocus(Element *oldFocus, tsl::FocusDirection direction) override {
return nullptr; // Make it non-focusable return nullptr; // Make it non-focusable
} }
}; };
class HideableCategoryHeader : public tsl::elm::CategoryHeader { class HideableCategoryHeader : public tsl::elm::CategoryHeader {
private: private:
bool visible; bool visible;
public: public:
HideableCategoryHeader(const std::string& title) HideableCategoryHeader(const std::string &title) : tsl::elm::CategoryHeader(title), visible(true) {
: tsl::elm::CategoryHeader(title), visible(true) {} }
void setVisible(bool v) { void setVisible(bool v) {
visible = v; visible = v;
} }
virtual void draw(tsl::gfx::Renderer *renderer) override { virtual void draw(tsl::gfx::Renderer *renderer) override {
if (!visible) return; if (!visible)
return;
tsl::elm::CategoryHeader::draw(renderer); tsl::elm::CategoryHeader::draw(renderer);
} }
virtual void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight) override { virtual void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight) override {
if (!visible) { if (!visible) {
this->setBoundaries(parentX, parentY, 0, 0); this->setBoundaries(parentX, parentY, 0, 0);
@@ -95,23 +118,35 @@ public:
} }
}; };
class FocusableDrawer : public tsl::elm::CustomDrawer {
public:
template <typename... Args> FocusableDrawer(Args &&...args) : tsl::elm::CustomDrawer(std::forward<Args>(args)...) {
m_isItem = true;
}
Element *requestFocus(Element *, tsl::FocusDirection) override {
return this;
}
void drawHighlight(tsl::gfx::Renderer *) override {
}
};
class HideableCustomDrawer : public tsl::elm::Element { class HideableCustomDrawer : public tsl::elm::Element {
private: private:
bool visible; bool visible;
u32 height; u32 height;
public: public:
HideableCustomDrawer(u32 h) HideableCustomDrawer(u32 h) : Element(), visible(true), height(h) {
: Element(), visible(true), height(h) {} }
void setVisible(bool v) { void setVisible(bool v) {
visible = v; visible = v;
} }
virtual void draw(tsl::gfx::Renderer *renderer) override { virtual void draw(tsl::gfx::Renderer *renderer) override {
// Empty drawer - just for spacing // Empty drawer - just for spacing
} }
virtual void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight) override { virtual void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight) override {
if (!visible) { if (!visible) {
this->setBoundaries(parentX, parentY, 0, 0); this->setBoundaries(parentX, parentY, 0, 0);
@@ -119,8 +154,8 @@ public:
this->setBoundaries(parentX, parentY, parentWidth, height); this->setBoundaries(parentX, parentY, parentWidth, height);
} }
} }
virtual Element* requestFocus(Element *oldFocus, tsl::FocusDirection direction) override { virtual Element *requestFocus(Element *oldFocus, tsl::FocusDirection direction) override {
return nullptr; return nullptr;
} }
}; };

View File

@@ -16,43 +16,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#include "value_choice_gui.h" #include <iomanip>
#include <sstream>
#include "../format.h" #include "../format.h"
#include "fatal_gui.h" #include "fatal_gui.h"
#include <sstream> #include "ult_ext.h"
#include <iomanip> #include "value_choice_gui.h"
ValueChoiceGui::ValueChoiceGui(std::uint32_t selectedValue, ValueChoiceGui::ValueChoiceGui(std::uint32_t selectedValue, const ValueRange &range, const std::string &categoryName, ValueChoiceListener listener,
const ValueRange& range, const ValueThresholds &thresholds, bool enableThresholds, std::map<std::uint32_t, std::string> labels,
const std::string& categoryName, std::vector<NamedValue> namedValues, bool showDefaultValue, bool showDNO)
ValueChoiceListener listener, : selectedValue(selectedValue), range(range), categoryName(categoryName), listener(listener), thresholds(thresholds),
const ValueThresholds& thresholds, enableThresholds(enableThresholds), labels(labels), namedValues(namedValues), showDefaultValue(showDefaultValue), showDNO(showDNO) {
bool enableThresholds,
std::map<std::uint32_t, std::string> labels,
std::vector<NamedValue> namedValues,
bool showDefaultValue,
bool showDNO)
: selectedValue(selectedValue),
range(range),
categoryName(categoryName),
listener(listener),
thresholds(thresholds),
enableThresholds(enableThresholds),
labels(labels),
namedValues(namedValues),
showDefaultValue(showDefaultValue),
showDNO(showDNO)
{
} }
ValueChoiceGui::~ValueChoiceGui() ValueChoiceGui::~ValueChoiceGui() {
{
} }
std::string ValueChoiceGui::formatValue(std::uint32_t value) std::string ValueChoiceGui::formatValue(std::uint32_t value) {
{
std::ostringstream oss; std::ostringstream oss;
if(showDefaultValue) { if (showDefaultValue) {
if (value == 0) { if (value == 0) {
return this->showDNO ? FREQ_DEFAULT_TEXT : VALUE_DEFAULT_TEXT; return this->showDNO ? FREQ_DEFAULT_TEXT : VALUE_DEFAULT_TEXT;
} }
@@ -65,12 +49,11 @@ std::string ValueChoiceGui::formatValue(std::uint32_t value)
return oss.str(); return oss.str();
} }
int ValueChoiceGui::getSafetyLevel(std::uint32_t value) int ValueChoiceGui::getSafetyLevel(std::uint32_t value) {
{ if (thresholds.warning == 0 && thresholds.danger == 0) {
if(thresholds.warning == 0 && thresholds.danger == 0) {
return 0; return 0;
} }
if (value > thresholds.danger) { if (value > thresholds.danger) {
return 2; return 2;
} }
@@ -80,8 +63,7 @@ int ValueChoiceGui::getSafetyLevel(std::uint32_t value)
return 0; return 0;
} }
tsl::elm::ListItem* ValueChoiceGui::createValueListItem(std::uint32_t value, bool selected, int safety) tsl::elm::ListItem *ValueChoiceGui::createValueListItem(std::uint32_t value, bool selected, int safety) {
{
std::string text = formatValue(value); std::string text = formatValue(value);
std::string rightText = ""; std::string rightText = "";
@@ -91,34 +73,32 @@ tsl::elm::ListItem* ValueChoiceGui::createValueListItem(std::uint32_t value, boo
} }
if (selected) { if (selected) {
const_cast<std::string&>(rightText) = "\uE14B"; const_cast<std::string &>(rightText) = "\uE14B";
} }
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(text, rightText, false); tsl::elm::ListItem *listItem = new tsl::elm::ListItem(text, rightText, false);
switch (safety) switch (safety) {
{ case 0:
case 0: listItem->setTextColor(tsl::Color(255, 255, 255, 255));
listItem->setTextColor(tsl::Color(255, 255, 255, 255)); listItem->setValueColor(tsl::Color(255, 255, 255, 255));
listItem->setValueColor(tsl::Color(255, 255, 255, 255)); break;
break; case 1:
case 1: listItem->setTextColor(tsl::Color(255, 165, 0, 255));
listItem->setTextColor(tsl::Color(255, 165, 0, 255)); listItem->setValueColor(tsl::Color(255, 165, 0, 255));
listItem->setValueColor(tsl::Color(255, 165, 0, 255)); break;
break; case 2:
case 2: listItem->setTextColor(tsl::Color(255, 0, 0, 255));
listItem->setTextColor(tsl::Color(255, 0, 0, 255)); listItem->setValueColor(tsl::Color(255, 0, 0, 255));
listItem->setValueColor(tsl::Color(255, 0, 0, 255)); break;
break;
} }
// Make annotation grey // Make annotation grey
if (!rightText.empty() && !selected) if (!rightText.empty() && !selected)
listItem->setValueColor(tsl::Color(180, 180, 180, 255)); listItem->setValueColor(tsl::Color(180, 180, 180, 255));
else if(selected) else if (selected)
listItem->setValueColor(tsl::infoTextColor); listItem->setValueColor(tsl::infoTextColor);
listItem->setClickListener([this, value](u64 keys) listItem->setClickListener([this, value](u64 keys) {
{
if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) { if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) {
if (this->listener(value)) { if (this->listener(value)) {
tsl::goBack(); tsl::goBack();
@@ -130,37 +110,34 @@ tsl::elm::ListItem* ValueChoiceGui::createValueListItem(std::uint32_t value, boo
return listItem; return listItem;
} }
tsl::elm::ListItem* ValueChoiceGui::createNamedValueListItem(const NamedValue& namedValue, bool selected, int safety) tsl::elm::ListItem *ValueChoiceGui::createNamedValueListItem(const NamedValue &namedValue, bool selected, int safety) {
{
std::string text = namedValue.name; std::string text = namedValue.name;
if (selected) { if (selected) {
const_cast<std::string&>(namedValue.rightText) = "\uE14B"; const_cast<std::string &>(namedValue.rightText) = "\uE14B";
} }
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(text, namedValue.rightText, false); tsl::elm::ListItem *listItem = new tsl::elm::ListItem(text, namedValue.rightText, false);
switch (safety) switch (safety) {
{ case 0:
case 0: listItem->setTextColor(tsl::Color(255, 255, 255, 255));
listItem->setTextColor(tsl::Color(255, 255, 255, 255)); listItem->setValueColor(tsl::Color(255, 255, 255, 255));
listItem->setValueColor(tsl::Color(255, 255, 255, 255)); break;
break; case 1:
case 1: listItem->setTextColor(tsl::Color(255, 165, 0, 255));
listItem->setTextColor(tsl::Color(255, 165, 0, 255)); listItem->setValueColor(tsl::Color(255, 165, 0, 255));
listItem->setValueColor(tsl::Color(255, 165, 0, 255)); break;
break; case 2:
case 2: listItem->setTextColor(tsl::Color(255, 0, 0, 255));
listItem->setTextColor(tsl::Color(255, 0, 0, 255)); listItem->setValueColor(tsl::Color(255, 0, 0, 255));
listItem->setValueColor(tsl::Color(255, 0, 0, 255)); break;
break;
} }
if (!namedValue.rightText.empty() && !selected) if (!namedValue.rightText.empty() && !selected)
listItem->setValueColor(tsl::Color(180, 180, 180, 255)); listItem->setValueColor(tsl::Color(180, 180, 180, 255));
else if(selected) else if (selected)
listItem->setValueColor(tsl::infoTextColor); listItem->setValueColor(tsl::infoTextColor);
listItem->setClickListener([this, value = namedValue.value](u64 keys) listItem->setClickListener([this, value = namedValue.value](u64 keys) {
{
if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) { if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) {
if (this->listener(value)) { if (this->listener(value)) {
tsl::goBack(); tsl::goBack();
@@ -172,8 +149,7 @@ tsl::elm::ListItem* ValueChoiceGui::createNamedValueListItem(const NamedValue& n
return listItem; return listItem;
} }
void ValueChoiceGui::listUI() void ValueChoiceGui::listUI() {
{
if (!categoryName.empty()) { if (!categoryName.empty()) {
this->listElement->addItem(new tsl::elm::CategoryHeader(categoryName)); this->listElement->addItem(new tsl::elm::CategoryHeader(categoryName));
} }
@@ -181,20 +157,19 @@ void ValueChoiceGui::listUI()
if (showDefaultValue) { if (showDefaultValue) {
this->listElement->addItem(this->createValueListItem(0, this->selectedValue == 0, 0)); this->listElement->addItem(this->createValueListItem(0, this->selectedValue == 0, 0));
} }
for (const auto& namedValue : namedValues) { for (const auto &namedValue : namedValues) {
int safety = enableThresholds ? getSafetyLevel(namedValue.value) : 0; int safety = enableThresholds ? getSafetyLevel(namedValue.value) : 0;
bool selected = (namedValue.value == this->selectedValue); bool selected = (namedValue.value == this->selectedValue);
this->listElement->addItem(this->createNamedValueListItem(namedValue, selected, safety)); this->listElement->addItem(this->createNamedValueListItem(namedValue, selected, safety));
} }
if (namedValues.empty()) { if (namedValues.empty()) {
for (std::uint32_t value = range.min; value <= range.max; value += range.step) for (std::uint32_t value = range.min; value <= range.max; value += range.step) {
{
int safety = getSafetyLevel(value); int safety = getSafetyLevel(value);
bool selected = (value == this->selectedValue); bool selected = (value == this->selectedValue);
this->listElement->addItem(this->createValueListItem(value, selected, safety)); this->listElement->addItem(this->createValueListItem(value, selected, safety));
} }
} }
this->listElement->jumpToItem("", "\uE14B"); this->listElement->jumpToItem("", "\uE14B");
} }

View File

@@ -17,11 +17,12 @@
* *
*/ */
#pragma once #pragma once
#include <list>
#include <functional> #include <functional>
#include <string> #include <list>
#include <map> #include <map>
#include <string>
#include <vector> #include <vector>
#include "base_menu_gui.h" #include "base_menu_gui.h"
using ValueChoiceListener = std::function<bool(std::uint32_t value)>; using ValueChoiceListener = std::function<bool(std::uint32_t value)>;
@@ -34,33 +35,32 @@ struct ValueRange {
std::string suffix; std::string suffix;
std::uint32_t divisor; std::uint32_t divisor;
int decimalPlaces; int decimalPlaces;
ValueRange() ValueRange() : min(0), max(0), step(1), suffix(""), divisor(1), decimalPlaces(0) {
: min(0), max(0), step(1), suffix(""), divisor(1), decimalPlaces(0) {} }
ValueRange(std::uint32_t min, std::uint32_t max, std::uint32_t step, ValueRange(std::uint32_t min, std::uint32_t max, std::uint32_t step, const std::string &suffix = "", std::uint32_t divisor = 1,
const std::string& suffix = "", std::uint32_t divisor = 1, int decimalPlaces = 0) int decimalPlaces = 0)
: min(min), max(max), step(step), suffix(suffix), : min(min), max(max), step(step), suffix(suffix), divisor(divisor), decimalPlaces(decimalPlaces) {
divisor(divisor), decimalPlaces(decimalPlaces) {} }
}; };
struct ValueThresholds { struct ValueThresholds {
std::uint32_t warning; std::uint32_t warning;
std::uint32_t danger; std::uint32_t danger;
ValueThresholds(std::uint32_t warning = 0, std::uint32_t danger = 0) ValueThresholds(std::uint32_t warning = 0, std::uint32_t danger = 0) : warning(warning), danger(danger) {
: warning(warning), danger(danger) {} }
}; };
struct NamedValue { struct NamedValue {
std::string name; std::string name;
std::uint32_t value; std::uint32_t value;
std::string rightText; std::string rightText;
NamedValue(const std::string& name, std::uint32_t value, const std::string& rightText = "") NamedValue(const std::string &name, std::uint32_t value, const std::string &rightText = "") : name(name), value(value), rightText(rightText) {
: name(name), value(value), rightText(rightText) {} }
}; };
class ValueChoiceGui : public BaseMenuGui class ValueChoiceGui : public BaseMenuGui {
{ protected:
protected:
std::uint32_t selectedValue; std::uint32_t selectedValue;
ValueRange range; ValueRange range;
std::string categoryName; std::string categoryName;
@@ -68,47 +68,37 @@ protected:
ValueThresholds thresholds; ValueThresholds thresholds;
bool enableThresholds; bool enableThresholds;
std::map<std::uint32_t, std::string> labels; std::map<std::uint32_t, std::string> labels;
std::vector<NamedValue> namedValues; std::vector<NamedValue> namedValues;
bool showDefaultValue = true; bool showDefaultValue = true;
bool showDNO = false; bool showDNO = false;
tsl::elm::ListItem* createValueListItem(std::uint32_t value, bool selected, int safety); tsl::elm::ListItem *createValueListItem(std::uint32_t value, bool selected, int safety);
tsl::elm::ListItem* createNamedValueListItem(const NamedValue& namedValue, bool selected, int safety); tsl::elm::ListItem *createNamedValueListItem(const NamedValue &namedValue, bool selected, int safety);
std::string formatValue(std::uint32_t value); std::string formatValue(std::uint32_t value);
int getSafetyLevel(std::uint32_t value); int getSafetyLevel(std::uint32_t value);
public: public:
ValueChoiceGui(std::uint32_t selectedValue, ValueChoiceGui(std::uint32_t selectedValue, const ValueRange &range, const std::string &categoryName, ValueChoiceListener listener,
const ValueRange& range, const ValueThresholds &thresholds = ValueThresholds(), bool enableThresholds = false,
const std::string& categoryName, std::map<std::uint32_t, std::string> labels = {}, std::vector<NamedValue> namedValues = {}, bool showDefaultValue = true,
ValueChoiceListener listener,
const ValueThresholds& thresholds = ValueThresholds(),
bool enableThresholds = false,
std::map<std::uint32_t, std::string> labels = {},
std::vector<NamedValue> namedValues = {},
bool showDefaultValue = true,
bool showDNO = false); bool showDNO = false);
~ValueChoiceGui(); ~ValueChoiceGui();
void addNamedValue(const std::string& name, std::uint32_t value, const std::string& rightText = "") void addNamedValue(const std::string &name, std::uint32_t value, const std::string &rightText = "") {
{
namedValues.emplace_back(name, value, rightText); namedValues.emplace_back(name, value, rightText);
} }
void addNamedValues(const std::vector<NamedValue>& values) void addNamedValues(const std::vector<NamedValue> &values) {
{
namedValues.insert(namedValues.end(), values.begin(), values.end()); namedValues.insert(namedValues.end(), values.begin(), values.end());
} }
void clearNamedValues() void clearNamedValues() {
{
namedValues.clear(); namedValues.clear();
} }
void setShowDefaultValue(bool show) void setShowDefaultValue(bool show) {
{
showDefaultValue = show; showDefaultValue = show;
} }
void listUI() override; void listUI() override;
}; };

View File

@@ -12,9 +12,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net> * <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
@@ -24,7 +24,6 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#pragma once #pragma once
#include <tesla.hpp> #include <tesla.hpp>

View File

@@ -22,21 +22,20 @@ CONFIG_DIR := horizon-oc
BUILD := build BUILD := build
OUTDIR := out OUTDIR := out
RESOURCES := res RESOURCES := res
SOURCES := src src/nx/ipc ../common/src src/board SOURCES := src src/hos src/i2c src/ipc src/board src/display src/tsensor src/mgr src/file src/soc src/mapping src/pwr src/util
DATA := data DATA := data
INCLUDES := ../common/include INCLUDES := ../common/include src/hos src/soc src/i2c src/util src/pwr src/ipc
EXEFS_SRC := exefs_src EXEFS_SRC := exefs_src
LIBNAMES := minIni nxExt LIBNAMES := minIni
# major minor patch
#--------------------------------------------------------------------------------- TARGET_VERSION := 2.4.0
# version control constants KIP_VERSION := 240
#--------------------------------------------------------------------------------- CUST_REV := 4
TARGET_VERSION := $(shell git describe --dirty --always --tags)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
DEFINES := -DDISABLE_IPC -DTARGET="\"$(TARGET)\"" -DTARGET_VERSION="\"$(TARGET_VERSION)\"" -DCONFIG_DIR="\"$(CONFIG_DIR)\"" DEFINES := -DDISABLE_IPC -DKIP_VERSION=$(KIP_VERSION) -DCUST_REV=$(CUST_REV) -DTARGET="\"$(TARGET)\"" -DTARGET_VERSION="\"$(TARGET_VERSION)\"" -DCONFIG_DIR="\"$(CONFIG_DIR)\""
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE

View File

@@ -1,13 +0,0 @@
# Editor files
*.swp
*~
# Objects
*.o
*.a
*.so
# Lib
lib
release
debug

View File

@@ -1,132 +0,0 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
endif
include $(DEVKITPRO)/libnx/switch_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
SOURCES := src
DATA := data
INCLUDES := include
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIC -ftls-model=local-exec
CFLAGS := -g -Wall -Werror \
-ffunction-sections \
-fdata-sections \
$(ARCH) \
$(BUILD_CFLAGS)
CFLAGS += $(INCLUDE) -std=gnu11
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(LIBNX)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
.PHONY: clean all lib/lib$(TARGET).a lib/lib$(TARGET)d.a
#---------------------------------------------------------------------------------
all: lib/lib$(TARGET).a lib/lib$(TARGET)d.a
lib:
@[ -d $@ ] || mkdir -p $@
release:
@[ -d $@ ] || mkdir -p $@
debug:
@[ -d $@ ] || mkdir -p $@
lib/lib$(TARGET).a : lib release $(SOURCES) $(INCLUDES)
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
BUILD_CFLAGS="-DNDEBUG=1 -O2" \
DEPSDIR=$(CURDIR)/release \
--no-print-directory -C release \
-f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr release debug lib
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT) : $(OFILES)
$(OFILES_SRC) : $(HFILES)
#---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@@ -1,36 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/* --------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
* 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
* --------------------------------------------------------------------------
*/
#pragma once
#include "nxExt/apm_ext.h"
#include "nxExt/i2c.h"
#include "nxExt/t210.h"
#include "nxExt/max17050.h"
#include "nxExt/tmp451.h"
#include "nxExt/ipc_server.h"
#include "nxExt/cpp/lockable_mutex.h"

View File

@@ -3,7 +3,7 @@
"title_id": "0x00FF0000636C6BFF", "title_id": "0x00FF0000636C6BFF",
"title_id_range_min": "0x00FF0000636C6BFF", "title_id_range_min": "0x00FF0000636C6BFF",
"title_id_range_max": "0x00FF0000636C6BFF", "title_id_range_max": "0x00FF0000636C6BFF",
"main_thread_stack_size": "0x0000F000", "main_thread_stack_size": "0x0000C000",
"main_thread_priority": 16, "main_thread_priority": 16,
"default_cpu_id": 3, "default_cpu_id": 3,
"process_category": 1, "process_category": 1,
@@ -31,6 +31,14 @@
"highest_cpu_id": 3 "highest_cpu_id": 3
} }
}, { }, {
"type": "map",
"value": {
"address": "0x70000000",
"is_ro": false,
"size": "0x00001000",
"is_io": true
}
}, {
"type": "map", "type": "map",
"value": { "value": {
"address": "0x60006000", "address": "0x60006000",

View File

@@ -24,66 +24,86 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#include <nxExt.h> #include <battery.h>
#include <hocclk.h> #include <hocclk.h>
#include <switch.h> #include <i2c.h>
#include <max17050.h>
#include <notification.h>
#include <pwm.h> #include <pwm.h>
#include <registers.h> #include <registers.h>
#include <battery.h> #include <switch.h>
#include "display_refresh_rate.hpp" #include <t210.h>
#include <rgltr.h> #include <tmp451.h>
#include <notification.h>
#include "../display/display_refresh_rate.hpp"
#include "../file/file_utils.hpp"
#include "../hos/apm_ext.h"
#include "../hos/integrations.hpp"
#include "../hos/rgltr.h"
#include "../tsensor/aotag.hpp"
#include "../tsensor/soctherm.hpp"
#include "board.hpp" #include "board.hpp"
#include "board_fuse.hpp" #include "board_fuse.hpp"
#include "board_load.hpp" #include "board_load.hpp"
#include "board_volt.hpp"
#include "board_misc.hpp" #include "board_misc.hpp"
#include "../soctherm.hpp" #include "board_volt.hpp"
#include "../integrations.hpp" #include <ipc_server.h>
#include "../file_utils.hpp" #include <lockable_mutex.h>
namespace board { namespace board {
u64 clkVirtAddr, dsiVirtAddr; u64 clkVirtAddr, dsiVirtAddr, apbVirtAddr, fuseVirtAddr;
HocClkSocType gSocType; HocClkSocType gSocType;
u8 gDramID; u8 gDramID;
HocClkConsoleType gConsoleType = HocClkConsoleType_Iowa; HocClkConsoleType gConsoleType = HocClkConsoleType_Icosa;
FuseData fuseData; FuseData fuseData;
u8 speedoBracket; u8 speedoBracket;
PwmChannelSession iCon; PwmChannelSession iCon;
u32 fd = 0, fd2 = 0; u32 fd = 0, fd2 = 0;
#define PMC_BASE 0x7000E400
#define APB_MISC_GP_HIDREV 0x804
#define GP_HIDREV_MAJOR_T210 0x1
#define GP_HIDREV_MAJOR_T210B01 0x2
#define APB_BASE 0x70000000
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
#define FUSE_OFFSET 0x800
void FetchHardwareInfos() { void FetchHardwareInfos() {
ReadFuses(fuseData); ReadFuses(fuseData, fuseVirtAddr);
SetGpuBracket(fuseData.gpuSpeedo, speedoBracket); SetGpuBracket(fuseData.gpuSpeedo, speedoBracket);
u64 sku = 0, dramID = 0; u32 hidrev = *(u32 *)(apbVirtAddr + APB_MISC_GP_HIDREV);
Result rc = splInitialize(); if (((hidrev >> 4) & 0xF) >= GP_HIDREV_MAJOR_T210B01) {
ASSERT_RESULT_OK(rc, "splInitialize"); gSocType = HocClkSocType_Mariko;
} else {
rc = splGetConfig(SplConfigItem_HardwareType, &sku); gSocType = HocClkSocType_Erista;
ASSERT_RESULT_OK(rc, "splGetConfig");
rc = splGetConfig(SplConfigItem_DramId, &dramID);
ASSERT_RESULT_OK(rc, "splGetConfig");
gDramID = dramID;
splExit();
switch(sku) {
case 2 ... 5:
gSocType = HocClkSocType_Mariko;
break;
default:
gSocType = HocClkSocType_Erista;
} }
u32 odm4 = *(u32 *)(fuseVirtAddr + FUSE_OFFSET + FUSE_RESERVED_ODMX(4));
if (gSocType == HocClkSocType_Mariko) { if (gSocType == HocClkSocType_Mariko) {
CacheGpuVoltTable(); switch ((odm4 & 0xF0000) >> 16) {
case 2:
gConsoleType = HocClkConsoleType_Hoag;
break;
case 4:
gConsoleType = HocClkConsoleType_Aula;
break;
case 1:
default:
gConsoleType = HocClkConsoleType_Iowa;
}
} else {
gConsoleType = HocClkConsoleType_Icosa;
} }
gConsoleType = static_cast<HocClkConsoleType>(sku); gDramID = (odm4 & 0xF8) >> 3;
// Get extended dram id info.
if (gSocType == HocClkSocType_Mariko) {
gDramID |= (odm4 & 0x7000) >> 7;
}
} }
/* TODO: Check for config */ /* TODO: Check for config */
@@ -104,7 +124,7 @@ namespace board {
rc = psmInitialize(); rc = psmInitialize();
ASSERT_RESULT_OK(rc, "psmInitialize"); ASSERT_RESULT_OK(rc, "psmInitialize");
if(HOSSVC_HAS_TC) { if (HOSSVC_HAS_TC) {
rc = tcInitialize(); rc = tcInitialize();
ASSERT_RESULT_OK(rc, "tcInitialize"); ASSERT_RESULT_OK(rc, "tcInitialize");
} }
@@ -115,6 +135,26 @@ namespace board {
rc = tmp451Initialize(); rc = tmp451Initialize();
ASSERT_RESULT_OK(rc, "tmp451Initialize"); ASSERT_RESULT_OK(rc, "tmp451Initialize");
rc = pmdmntInitialize();
ASSERT_RESULT_OK(rc, "pmdmntInitialize");
rc = rgltrInitialize();
ASSERT_RESULT_OK(rc, "rgltrInitialize");
rc = QueryMemoryMapping(&clkVirtAddr, 0x60006000, 0x1000);
ASSERT_RESULT_OK(rc, "QueryMemoryMapping (clk)");
rc = QueryMemoryMapping(&dsiVirtAddr, 0x54300000, 0x40000);
ASSERT_RESULT_OK(rc, "QueryMemoryMapping (dsi)");
rc = QueryMemoryMapping(&apbVirtAddr, 0x70000000, 0x1000);
ASSERT_RESULT_OK(rc, "QueryMemoryMapping (apb)");
rc = QueryMemoryMapping(&fuseVirtAddr, 0x7000F000, 0x1000);
ASSERT_RESULT_OK(rc, "QueryMemoryMapping (fuse)");
FetchHardwareInfos();
Result nvCheck = 1; Result nvCheck = 1;
if (R_SUCCEEDED(nvInitialize())) { if (R_SUCCEEDED(nvInitialize())) {
nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
@@ -127,36 +167,37 @@ namespace board {
} }
} }
rc = rgltrInitialize();
ASSERT_RESULT_OK(rc, "rgltrInitialize");
rc = pmdmntInitialize();
ASSERT_RESULT_OK(rc, "pmdmntInitialize");
StartLoad(nvCheck, fd); StartLoad(nvCheck, fd);
batteryInfoInitialize(); batteryInfoInitialize();
FetchHardwareInfos();
soctherm::Initialize(); tsensor::InitializeSoctherm(); // SOCTHERM must be init before AOTAG
// PMC exosphere check
SecmonArgs args = {};
args.X[0] = 0xF0000002;
args.X[1] = PMC_BASE;
svcCallSecureMonitor(&args);
if (args.X[1] != PMC_BASE) { // if param 1 is identical read failed
tsensor::InitializeAotag(GetSocType() == HocClkSocType_Mariko);
}
Result pwmCheck = 1; Result pwmCheck = 1;
if (hosversionAtLeast(6,0,0) && R_SUCCEEDED(pwmInitialize())) { if (hosversionAtLeast(6, 0, 0) && R_SUCCEEDED(pwmInitialize())) {
pwmCheck = pwmOpenSession2(&iCon, 0x3D000001); pwmCheck = pwmOpenSession2(&iCon, 0x3D000001);
} }
StartMiscThread(pwmCheck, &iCon); StartMiscThread(pwmCheck, &iCon);
rc = QueryMemoryMapping(&clkVirtAddr, 0x60006000, 0x1000); display::DisplayRefreshConfig cfg = { .clkVirtAddr = clkVirtAddr,
ASSERT_RESULT_OK(rc, "QueryMemoryMapping (clk)"); .dsiVirtAddr = dsiVirtAddr,
.isLite = (GetConsoleType() == HocClkConsoleType_Hoag),
rc = QueryMemoryMapping(&dsiVirtAddr, 0x54300000, 0x40000); .isRetroSUPER = integrations::GetRETROSuperStatus() };
ASSERT_RESULT_OK(rc, "QueryMemoryMapping (dsi)");
display::DisplayRefreshConfig cfg = {.clkVirtAddr = clkVirtAddr, .dsiVirtAddr = dsiVirtAddr, .isLite = (GetConsoleType() == HocClkConsoleType_Hoag), .isRetroSUPER = integrations::GetRETROSuperStatus()};
display::Initialize(&cfg); display::Initialize(&cfg);
CacheDfllData(); CacheDfllData();
CacheGpuVoltTable();
} }
void Exit() { void Exit() {
@@ -168,13 +209,14 @@ namespace board {
apmExtExit(); apmExtExit();
psmExit(); psmExit();
rgltrExit();
if (HOSSVC_HAS_TC) { if (HOSSVC_HAS_TC) {
tcExit(); tcExit();
} }
max17050Exit(); max17050Exit();
tmp451Exit(); tmp451Exit();
display::Shutdown();
ExitLoad(); ExitLoad();
@@ -182,10 +224,8 @@ namespace board {
pwmChannelSessionClose(&iCon); pwmChannelSessionClose(&iCon);
pwmExit(); pwmExit();
rgltrExit();
batteryInfoExit(); batteryInfoExit();
pmdmntExit(); pmdmntExit();
display::Shutdown();
nvExit(); nvExit();
} }
@@ -207,8 +247,8 @@ namespace board {
args.X[1] = MC_REGISTER_BASE + MC_EMEM_CFG_0; args.X[1] = MC_REGISTER_BASE + MC_EMEM_CFG_0;
svcCallSecureMonitor(&args); svcCallSecureMonitor(&args);
if (args.X[1] == (MC_REGISTER_BASE + MC_EMEM_CFG_0)) { // if param 1 is identical read failed if (args.X[1] == (MC_REGISTER_BASE + MC_EMEM_CFG_0)) { // if param 1 is identical read failed
notification::writeNotification("Horizon OC\nSecmon read failed!\n This may be a hardware issue!"); notification::writeNotification("Horizon OC\nSecmon-Lesen fehlgeschlagen!\nDies könnte ein Hardwareproblem sein!");
return false; return false;
} }
@@ -234,4 +274,4 @@ namespace board {
return false; /* stub for now. */ return false; /* stub for now. */
} }
} } // namespace board

Some files were not shown because too many files have changed in this diff Show More