329 Commits
1.2.0 ... 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
souldbminersmwc
7d30c4d384 bump version 2026-04-21 19:38:32 -04:00
souldbminersmwc
883b4fc3f4 hocclk: fix pointer dereference 2026-04-21 19:35:05 -04:00
Lightos1
530588a818 bump version 2026-04-21 21:29:18 +02:00
Lightos1
a6402bd5d5 update startPtr AFTER PrepareMtcMemoryRegion 2026-04-21 21:28:18 +02:00
Lightos1
cd3d29ce88 I'm a fucking idiot... remove debug code 2026-04-21 09:58:11 +02:00
souldbminersmwc
192b70dae4 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-04-20 19:19:44 -04:00
souldbminersmwc
aaa9f90794 hocclk: console specific changes 2026-04-20 19:19:40 -04:00
Lightos1
d5e38b0eb3 Update SECURITY.md 2026-04-20 21:44:44 +02:00
Lightos1
3704d46136 set default step mode to 66MHz 2026-04-20 21:30:02 +02:00
Lightos1
b374117c37 properly fix time stuff - thanks masa! 2026-04-20 20:14:29 +02:00
Lightos1
c9c5d08919 add updated spanish translation by tdrr 2026-04-20 19:57:24 +02:00
Lightos1
c963dd8369 fix auto latency according to spec 2026-04-20 15:18:14 +02:00
Lightos1
7fc9682de0 use max freq in jedec mode regardless of it being jedec or not 2026-04-20 15:06:14 +02:00
Lightos1
0c555f34c3 remove (failing) cust rev check 2026-04-20 14:54:37 +02:00
Lightos1
fb37d5f0e7 reduce context size 2026-04-20 14:37:36 +02:00
Lightos1
a7619c39d2 set read/write latency to 1600 cause it's only used on erista 2026-04-20 07:31:52 +02:00
souldbminersmwc
55b97156ce hocclk: improve kip logging and add failsafe 2026-04-19 19:16:51 -04:00
souldbminersmwc
37ad65e768 final hoc 2.0.0 changes 2026-04-19 19:15:10 -04:00
souldbminersmwc
3b4877b287 update submodules 2026-04-19 15:38:07 -04:00
Lightos1
01d79aab30 fix off by one 2026-04-19 19:57:58 +02:00
Lightos1
3bb7b4cbd5 change colors 2026-04-19 19:17:36 +02:00
Lightos1
9c16f8b2b8 fix typo 2026-04-19 16:12:57 +02:00
Lightos1
78112547b6 prevent switch from combusting into 4 billion volts :D 2026-04-19 15:47:46 +02:00
Lightos1
3c7a42b033 formating 2026-04-19 15:13:35 +02:00
Lightos1
203587523a change result 2026-04-19 15:13:19 +02:00
Lightos1
07d0824c55 Merge pull request #66 from Horizon-OC/mrf-but-no-z-with-z
mrf
2026-04-19 15:07:02 +02:00
Lightos1
f1eab00ce1 revert custom and pcv to default settings 2026-04-19 14:51:15 +02:00
Lightos1
6a851d4095 nso start check, timing tbreak and some horrendous ui code 2026-04-18 23:00:21 +02:00
Lightos1
822e9f2817 add t2 trp cap 2026-04-18 19:02:07 +02:00
Lightos1
55b3a4230c Remove useless comments, yes I cannot be bothered to write ui code myself :D; fuck ui 2026-04-18 16:31:49 +02:00
Lightos1
be61b9df0e add sloppy configurator: todo fix crap 2026-04-18 16:30:24 +02:00
Lightos1
6c8d429c64 add missing configs 2026-04-18 12:21:42 +02:00
Lightos1
aa95f526b8 add mrf latency stuff to configs 2026-04-18 12:19:55 +02:00
Lightos1
638ddb499c add jedec mode 2026-04-18 11:52:06 +02:00
Lightos1
c95b6fde88 assign all mtc tables 2026-04-17 23:40:17 +02:00
Lightos1
2dd726723e add latency switching 2026-04-17 20:26:32 +02:00
Lightos1
119f49a3a4 fix freq list generation and dvb 2026-04-17 16:36:12 +02:00
Lightos1
51f935c252 initial mrf implementation with some bugs to fix 2026-04-16 20:51:26 +02:00
Lightos1
e1003520eb Revert "initial mrf implementation with some bugs to fix"
This reverts commit 819913ffd9.
2026-04-16 20:49:58 +02:00
Lightos1
3b5185df8d Reapply "Partial workflow fixes? (#63)"
This reverts commit 26c1dd1f99.
2026-04-16 20:49:42 +02:00
Lightos1
26c1dd1f99 Revert "Partial workflow fixes? (#63)"
This reverts commit 923bd0c0ba.
2026-04-16 20:49:11 +02:00
Lightos1
819913ffd9 initial mrf implementation with some bugs to fix 2026-04-16 20:48:22 +02:00
Lightos1
923bd0c0ba Partial workflow fixes? (#63)
* Update build.yml

* Update build.yml

* Update build.yml
2026-04-13 16:53:25 +02:00
Lightos1
185e5bcf31 Update build.yml 2026-04-13 15:52:20 +02:00
souldbminersmwc
d1ef905ac5 hocmon: real temps fixes 2026-04-12 20:56:39 -04:00
souldbminersmwc
fad9b5be50 hocmon: fix vdd2/vddq flip and full/mini mode 2026-04-12 20:06:23 -04:00
souldbminersmwc
c6424403b3 hocmon: partially add ram bw 2026-04-12 17:43:45 -04:00
souldbminersmwc
2b23498285 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-04-12 16:53:01 -04:00
souldbminersmwc
c7db7a7632 hocclk: fix compilation 2026-04-12 16:51:52 -04:00
Lightos1
985ecdc980 add fatal handler payload 2026-04-12 22:04:19 +02:00
Lightos1
e1d75f0084 add oc_log files 2026-04-12 22:00:45 +02:00
souldbminersmwc
f276ca0187 hocclk: rename mem display unit to ram display unit 2026-04-11 21:05:28 -04:00
souldbminersmwc
ae39b1b1bd hocclk: fix MT/s display on 1600mhz 2026-04-11 21:03:31 -04:00
souldbminersmwc
9321aed1d1 bump version 2026-04-11 20:58:22 -04:00
souldbminersmwc
756c44ba82 hocclk: fix compile errors 2026-04-11 20:57:28 -04:00
souldbminersmwc
037f011c9b hocclk: peak emc bw and mem display unit option
also correct bw reading to keep it accurate
2026-04-11 20:56:35 -04:00
souldbminersmwc
d2a46e1202 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-04-11 19:08:19 -04:00
souldbminersmwc
976f133c97 add MT/S to mem profiles 2026-04-11 19:08:12 -04:00
Lightos1
accdf6dc34 fix Z - thanks masa! 2026-04-12 01:05:11 +02:00
souldbminersmwc
b417099a4a hocclk: add RAM bandwidth monitor 2026-04-11 19:00:22 -04:00
souldbminersmwc
b7440a38a5 hocclk: reduce memory usage for real this time 2026-04-11 18:25:30 -04:00
souldbminersmwc
6369382de1 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-04-11 17:59:20 -04:00
souldbminersmwc
65db0b4989 hocclk: 800mV minimum display voltage 2026-04-11 17:59:18 -04:00
Lightos1
19b29b97e1 separate pcv.hpp into erista/mariko files 2026-04-10 17:45:32 +02:00
Lightos1
ec230e35d0 make this pretty 2026-04-09 11:33:44 +02:00
Lightos1
5942cfd68d ldr: refactor asm 2026-04-09 11:32:00 +02:00
souldbminersmwc
66d0109a9a hocclk: autosave kip and reduce uv3 to 675 2026-04-08 19:15:26 -04:00
souldbminersmwc
6334603f9e hocclk: undo alignment
this doesnt help at all, it makes it less aligned
2026-04-08 17:51:20 -04:00
souldbminersmwc
5d12c1721a hocclk: reorganize about section 2026-04-08 17:49:00 -04:00
Lightos1
7e42394894 fix GpuClkOsLimit name 2026-04-08 22:17:28 +02:00
Lightos1
07dd65eebf move GpuClkOsLimit to common 2026-04-08 22:15:52 +02:00
Lightos1
ca8bb25660 add GpuOsLimit verification to mariko; erista will be pushed once verified 2026-04-08 21:30:36 +02:00
souldbminersmwc
90e53b52b2 hocclk: refactoring and ram pll measurement 2026-04-07 19:48:17 -04:00
Lightos1
c6cd863526 Bump ams version 2026-04-07 19:45:16 +02:00
Lightos1
24eb3b1208 recover alignment improvement commit changes 2026-04-07 19:32:37 +02:00
Lightos1
9a6282af9c bump version 2026-04-07 19:20:52 +02:00
Lightos1
5de030c4e9 rename globals 2026-04-06 23:23:04 +02:00
souldbminersmwc
dc63dfdca2 hocclk: add support for FW <10.0.0 2026-04-06 16:52:18 -04:00
souldbminersmwc
803a838b35 Update Utils.hpp 2026-04-06 16:10:02 -04:00
souldbminersmwc
5b284db5ae hocmon: lower default font size 2026-04-06 16:09:59 -04:00
souldbminersmwc
861ee85289 Merge branch 'main' of https://github.com/Horizon-OC/Horizon-OC 2026-04-06 15:57:12 -04:00
souldbminersmwc
521e3c22dd hocclk: reduce ram usage and add display undervolt 2026-04-06 15:57:10 -04:00
Lightos1
78798a1cce actually fix cpu max 2026-04-06 12:58:54 +02:00
Lightos1
44d417fb89 fix cpu max clock, remove below 1963 caps on mariko 2026-04-06 12:56:06 +02:00
Lightos1
8faaaa58d9 mini: fix garbage temp reading 2026-04-04 12:15:09 +02:00
Lightos1
df0969ba6f update readme 2026-04-04 11:59:10 +02:00
Lightos1
646f8b8d69 update readme 2026-04-04 11:58:44 +02:00
Lightos1
456684152a more accurate Italian translation by miki 2026-04-04 11:56:10 +02:00
souldbminersmwc
a606a878ee hocclk: fix lightos z 2026-04-03 20:02:36 -04:00
247 changed files with 20556 additions and 15576 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

@@ -54,6 +54,9 @@ jobs:
echo $SHORT_SHA > dist/.commit echo $SHORT_SHA > dist/.commit
echo $GITHUB_SHA >> dist/.commit echo $GITHUB_SHA >> dist/.commit
- name: Clone Libnx
run: git clone https://github.com/switchbrew/libnx.git
- name: Clone Atmosphere - name: Clone Atmosphere
run: git clone --depth=1 --single-branch https://github.com/Atmosphere-NX/Atmosphere.git atmosphere -b $(cat ams_ver.txt) run: git clone --depth=1 --single-branch https://github.com/Atmosphere-NX/Atmosphere.git atmosphere -b $(cat ams_ver.txt)
@@ -82,13 +85,22 @@ jobs:
ccache --set-config=compiler_check=content ccache --set-config=compiler_check=content
ccache --zero-stats ccache --zero-stats
- name: Build Libnx
shell: bash
run: |
export CC="ccache aarch64-none-elf-gcc"
export CXX="ccache aarch64-none-elf-g++"
pushd libnx
make -j$(($(nproc) * 4)) install CXX="ccache aarch64-none-elf-g++" CC="ccache aarch64-none-elf-gcc"
popd
- name: Build hoc-clk sysmodule and overlay - name: Build hoc-clk sysmodule and overlay
shell: bash shell: bash
run: | run: |
export CC="ccache aarch64-none-elf-gcc" export CC="ccache aarch64-none-elf-gcc"
export CXX="ccache aarch64-none-elf-g++" export CXX="ccache aarch64-none-elf-g++"
ROOT_DIR="$GITHUB_WORKSPACE/Source/sys-clk" ROOT_DIR="$GITHUB_WORKSPACE/Source/hoc-clk"
DIST_DIR="$ROOT_DIR/dist" DIST_DIR="$ROOT_DIR/dist"
mkdir -p "$DIST_DIR" mkdir -p "$DIST_DIR"
@@ -101,13 +113,14 @@ jobs:
echo "TITLE_ID: $TITLE_ID" echo "TITLE_ID: $TITLE_ID"
pushd "$ROOT_DIR/sysmodule" pushd "$ROOT_DIR/sysmodule"
git config --global --add safe.directory "$GITHUB_WORKSPACE"
make -j$(($(nproc) * 2)) CXX="ccache aarch64-none-elf-g++" CC="ccache aarch64-none-elf-gcc" make -j$(($(nproc) * 2)) CXX="ccache aarch64-none-elf-g++" CC="ccache aarch64-none-elf-gcc"
popd popd
mkdir -p "$DIST_DIR/atmosphere/contents/$TITLE_ID/flags" mkdir -p "$DIST_DIR/atmosphere/contents/$TITLE_ID/flags"
cp -vf \ cp -vf \
"$ROOT_DIR/sysmodule/out/horizon-oc.nsp" \ "$ROOT_DIR/sysmodule/out/hoc-clk.nsp" \
"$DIST_DIR/atmosphere/contents/$TITLE_ID/exefs.nsp" "$DIST_DIR/atmosphere/contents/$TITLE_ID/exefs.nsp"
: >"$DIST_DIR/atmosphere/contents/$TITLE_ID/flags/boot2.flag" : >"$DIST_DIR/atmosphere/contents/$TITLE_ID/flags/boot2.flag"

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,29 +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** - Italian translations * **Samybigio2011, Miki** - Italian translations
* **angelblaster** - Korean 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

@@ -4,8 +4,9 @@
| Version | Supported | | Version | Supported |
| ------- | ------------------ | | ------- | ------------------ |
| 1.x | :white_check_mark: | | 2.x.x | :white_check_mark: |
| 0.x | Not supported | | 1.x.x | Not supported |
| 0.x.x | Not supported |
## Reporting a Vulnerability ## Reporting a Vulnerability

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

@@ -31,93 +31,100 @@
namespace ams::ldr::hoc { namespace ams::ldr::hoc {
volatile CustomizeTable C = { volatile CustomizeTable C = {
/* Disables RAM powerdown */ /* Disables RAM powerdown */
.hpMode = DISABLED, .hpMode = DISABLED,
.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,
.marikoEmcMaxClock = 1866000, /* 1866MHz @ 1866tWRL is guaranteed to work on all Mariko units */ /* Available: 66MHz step rate, 100MHz step rate, 133MHz step rate and jedec. */
.marikoEmcVddqVolt = 600000, /* Micron: 600mV, other manafacturers: 640mV */ /* Jedec freqs are 1333MHz, 1600MHz, 1866MHz, 2133MHz, 2400MHz, 2666MHz, 2933MHz, 3200MHz. */
.emcDvbShift = 0, .stepMode = StepMode_66MHz,
// Primary .marikoEmcMaxClock = 2133000, /* 1866MHz @ 1866tWRL is guaranteed to work on all Mariko units */
.t1_tRCD = 0, .marikoEmcVddqVolt = 600000,
.t2_tRP = 0,
.t3_tRAS = 0,
// Secondary
.t4_tRRD = 0,
.t5_tRFC = 0,
.t6_tRTW = 0,
.t7_tWTR = 0,
.t8_tREFI = 0,
/* You can mix and match different latencies if needed */ .emcDvbShift = 0,
/* .marikoSocVmax = 0, /* 0 = stock limits (1450 - 1597 is 1050mV, 1598-1708 is 1025mV, 1709+ is 1000mV). */
* Read:
* 2133RL = 40
* 1866RL = 36
* 1600RL = 32
* 1331RL = 28
* Write:
* 2133WL = 18
* 1866WL = 16
* 1600WL = 14
* 1331WL = 12
*/
.mem_burst_read_latency = RL_1866, /* Primary. */
.mem_burst_write_latency = WL_1866, .t1_tRCD = 0,
.t2_tRP = 0,
.t3_tRAS = 0,
/* Secondary. */
.t4_tRRD = 0,
.t5_tRFC = 0,
.t6_tRTW = 0,
.t7_tWTR = 0,
.t8_tREFI = 0,
.eristaCpuUV = 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. */
.eristaCpuVmin = 800, /* This is a lazy workaround until I find the issue... */
.t2_tRP_cap = 2,
/* Frequency where non low timings gets used. */
.timingEmcTbreak = DISABLED,
.low_t6_tRTW = 0,
.low_t7_tWTR = 0,
.readLatency = {
/* 1333 */ 0,
/* 1600 */ 0,
/* 1866 */ 0,
/* 2133 */ 0,
},
.writeLatency = {
/* 1333 */ 0,
/* 1600 */ 0,
/* 1866 */ 0,
/* 2133 */ 0,
},
.eristaCpuUV = 0,
.eristaCpuVmin = 800,
.eristaCpuMaxVolt = 1200, .eristaCpuMaxVolt = 1200,
/* Unlocks up to 2295 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 */
.marikoCpuMaxVolt = 1120,
/* Supported values: 1963000, 2091000, 2193000, 2295000, 2397000, 2499000, 2601000, 2703000. */ /* 1120mV is NVIDIA rating */
/* 1963000 is official rating of T214/Mariko, fully safe. */ .marikoCpuMaxVolt = 1120,
/* Supported values: 1963500, 2091000, 2193000, 2295000, 2397000, 2499000, 2601000, 2703000. */
/* 1963500 is official rating of T214/Mariko, fully safe. */
/* 2091000-2295000 is a slight OC which should work on all units, but no guarantees. */ /* 2091000-2295000 is a slight OC which should work on all units, but no guarantees. */
/* 2397000 is the max safe OC for most average units with tuned undervolt. */ /* 2397000 is the max safe OC for most average units with tuned undervolt. */
/* 2499000 should be used with caution. */ /* 2499000 should be used with caution. */
/* 2601000 exceeds pmic limit on most consoles. */ /* 2601000 exceeds pmic limit on most consoles. */
/* 2703000 is potentially dangerous and not advised. */ /* 2703000 is potentially dangerous and not advised. */
.marikoCpuMaxClock = 1963000, .marikoCpuMaxClock = 1963500,
.eristaCpuBoostClock = 1785000, // Default boost clock .eristaCpuBoostClock = 1785000, /* Default boost clock */
.marikoCpuBoostClock = 1963000, // 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 */,
@@ -220,7 +227,7 @@ volatile CustomizeTable C = {
{ 1683000, { 1168000, }, { 5100873, -279186, 4747, } }, { 1683000, { 1168000, }, { 5100873, -279186, 4747, } },
{ 1785000, { 1225000, }, { 5100873, -279186, 4747, } }, { 1785000, { 1225000, }, { 5100873, -279186, 4747, } },
{ 1887000, { 1225000, }, { 5100873, -279186, 4747, } }, { 1887000, { 1225000, }, { 5100873, -279186, 4747, } },
{ 1963500, { 1227500, }, { 5100873, -279186, 4747, } }, { 1989000, { 1227500, }, { 5100873, -279186, 4747, } },
{ 2091000, { 1227500, }, { 5100873, -279186, 4747, } }, { 2091000, { 1227500, }, { 5100873, -279186, 4747, } },
{ 2193000, { 1227500, }, { 5100873, -279186, 4747, } }, { 2193000, { 1227500, }, { 5100873, -279186, 4747, } },
{ 2295000, { 1256250, }, { 5100873, -279186, 4747, } }, { 2295000, { 1256250, }, { 5100873, -279186, 4747, } },
@@ -450,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, } },
@@ -464,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, } },
@@ -485,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,34 +20,27 @@
#pragma once #pragma once
#define CUST_REV 1 #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,
}; };
/* enum StepMode: u32 {
* Read: StepMode_66MHz = 0,
* 2133RL = 40 StepMode_100MHz = 1,
* 1866RL = 36 StepMode_Jedec = 2,
* 1600RL = 32 StepMode_133MHz = 3,
* 1331RL = 28 };
* Write:
* 2133WL = 18
* 1866WL = 16
* 1600WL = 14
* 1331WL = 12
*/
enum ReadLatency: u32 { enum ReadLatency: u32 {
RL_2133 = 40, RL_2133 = 40,
@@ -68,23 +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;
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;
@@ -95,8 +86,14 @@ typedef struct CustomizeTable {
u32 t7_tWTR; u32 t7_tWTR;
u32 t8_tREFI; u32 t8_tREFI;
u32 mem_burst_read_latency; u32 t2_tRP_cap;
u32 mem_burst_write_latency;
u32 timingEmcTbreak;
u32 low_t6_tRTW;
u32 low_t7_tWTR;
u32 readLatency[4];
u32 writeLatency[4];
u32 eristaCpuUV; u32 eristaCpuUV;
u32 eristaCpuVmin; u32 eristaCpuVmin;
@@ -119,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];
@@ -149,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 "../oc_common.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

@@ -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 "../oc_common.hpp" #include <stratosphere.hpp>
#include "../mtc_timing_value.hpp" #include "../mtc_timing_value.hpp"
#include "timing_tables.hpp" #include "timing_tables.hpp"
@@ -26,8 +26,72 @@ namespace ams::ldr::hoc::pcv::mariko {
return; return;
} }
/* Fallback. */ /* > 3200 */
rext = 0x1A; rext = 0x1E;
}
void SwitchLatency(volatile u32 &latency, u32 index, u32 latencyStep) {
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 <= 1862'400) { /* 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() { void CalculateMrw2() {
@@ -56,11 +120,84 @@ 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)));
} }
void CalculateTimings() { void CalculateTimings(double tCK_avg, u32 freq) {
RL = RL_1331;
WL = WL_1331;
HandleLatency(freq);
GetRext(); GetRext();
/* 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... */
u32 tRPpbIndex = C.t2_tRP;
if (WL == WL_1331) {
tRPpbIndex = MIN(C.t2_tRP_cap, C.t2_tRP);
}
tRCD = tRCD_values[C.t1_tRCD];
tRPpb = tRP_values[tRPpbIndex];
tRAS = tRAS_values[C.t3_tRAS];
tRRD = tRRD_values[C.t4_tRRD];
tRFCpb = tRFC_values[C.t5_tRFC];
u32 tRTW = C.t6_tRTW;
u32 tWTR = 10 - tWTR_values[C.t7_tWTR];
if (freq < C.timingEmcTbreak) {
tRTW = C.low_t6_tRTW;
tWTR = 10 - tWTR_values[C.low_t7_tWTR];
}
s32 finetRTW = C.fineTune_t6_tRTW;
s32 finetWTR = C.fineTune_t7_tWTR;
tRC = tRAS + tRPpb;
tRFCab = tRFCpb * 2;
tXSR = static_cast<double>(tRFCab + 7.5);
tFAW = static_cast<u32>(tRRD * 4.0);
tRPab = tRPpb + 3;
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;
tRTM = FLOOR((10.0 + RL) + (3.502 / tCK_avg)) + FLOOR(7.489 / tCK_avg);
tRATM = CEIL((tRTM - 10.0) + (RL * 0.426));
rdv = RL + FLOOR((5.105 / tCK_avg) + 17.017);
qpop = rdv - 14;
quse_width = CEIL(((4.897 / tCK_avg) - FLOOR(2.538 / tCK_avg)) + 3.782);
quse = FLOOR(RL + ((5.082 / tCK_avg) + FLOOR(2.560 / tCK_avg))) - CEIL(4.820 / tCK_avg);
einput_duration = FLOOR(9.936 / tCK_avg) + 5.0 + quse_width;
einput = quse - CEIL(9.928 / tCK_avg);
u32 qrst_duration = FLOOR(8.399 - tCK_avg);
u32 qrstLow = MAX(static_cast<s32>(einput - qrst_duration - 2), static_cast<s32>(0));
qrst = PACK_U32(qrst_duration, qrstLow);
ibdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(1, quse - qrst_duration - 2.0);
qsafe = (einput_duration + 3) + MAX(MIN(qrstLow * rdv, qrst_duration + qrst_duration), einput);
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));
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;
tWTM = CEIL(WL + ((7.570 / tCK_avg) + 8.753));
tWATM = (tWTM + (FLOOR(WL / 0.816) * 2.0)) - 4.0;
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)));
tCLKSTOP = FLOOR(MIN(8.488 / tCK_avg, 23.0)) + 8.0;
u32 tMMRI = tRCD + (tCK_avg * 3);
pdex2mrr = tMMRI + 10;
CalculateMrw2(); CalculateMrw2();
} }

View File

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

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 {
@@ -111,60 +118,54 @@ namespace ams::ldr::hoc {
const std::array<u32, 10> tWTR_values = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; const std::array<u32, 10> tWTR_values = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
const std::array<u32, 6> tREFpb_values = { 3900, 5850, 7800, 11700, 15600, 99999 }; const std::array<u32, 6> tREFpb_values = { 3900, 5850, 7800, 11700, 15600, 99999 };
const double tCK_avg = 1000'000.0 / C.marikoEmcMaxClock; inline u32 tRCD;
inline u32 tRPpb;
inline u32 tRAS;
inline double tRRD;
inline u32 tRFCpb;
const u32 tRCD = tRCD_values[C.t1_tRCD]; inline u32 tRC;
const u32 tRPpb = tRP_values[C.t2_tRP]; inline u32 tRFCab;
const u32 tRAS = tRAS_values[C.t3_tRAS]; inline double tXSR;
const double tRRD = tRRD_values[C.t4_tRRD]; inline u32 tFAW;
const u32 tRFCpb = tRFC_values[C.t5_tRFC]; inline double tRPab;
const u32 tWTR = 10 - tWTR_values[C.t7_tWTR];
const s32 finetRTW = C.fineTune_t6_tRTW;
const s32 finetWTR = C.fineTune_t7_tWTR;
const u32 tRC = tRAS + tRPpb; inline u32 RL;
const u32 tRFCab = tRFCpb * 2; inline u32 WL;
const double tXSR = static_cast<double>(tRFCab + 7.5);
const u32 tFAW = static_cast<u32>(tRRD * 4.0);
const double tRPab = tRPpb + 3;
const u32 tR2P = CEIL((RL * 0.426) - 2.0); inline u32 tR2P;
const u32 tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL - (C.t6_tRTW * 3) + finetRTW; inline u32 tR2W;
const u32 tRTM = FLOOR((10.0 + RL) + (3.502 / tCK_avg)) + FLOOR(7.489 / tCK_avg); inline u32 tRTM;
const u32 tRATM = CEIL((tRTM - 10.0) + (RL * 0.426)); inline u32 tRATM;
inline u32 rext; inline u32 rext;
const u32 rdv = RL + FLOOR((5.105 / tCK_avg) + 17.017); inline u32 rdv;
const u32 qpop = rdv - 14; inline u32 qpop;
const u32 quse_width = CEIL(((4.897 / tCK_avg) - FLOOR(2.538 / tCK_avg)) + 3.782); inline u32 quse_width;
const u32 quse = FLOOR(RL + ((5.082 / tCK_avg) + FLOOR(2.560 / tCK_avg))) - CEIL(4.820 / tCK_avg); inline u32 quse;
const u32 einput_duration = FLOOR(9.936 / tCK_avg) + 5.0 + quse_width; inline u32 einput_duration;
const u32 einput = quse - CEIL(9.928 / tCK_avg); inline u32 einput;
const u32 qrst_duration = FLOOR(8.399 - tCK_avg); inline u32 qrst;
const u32 qrstLow = MAX(static_cast<s32>(einput - qrst_duration - 2), static_cast<s32>(0)); inline u32 ibdly;
const u32 qrst = PACK_U32(qrst_duration, qrstLow); inline u32 qsafe;
const u32 ibdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(1, quse - qrst_duration - 2.0);
const u32 qsafe = (einput_duration + 3) + MAX(MIN(qrstLow * rdv, qrst_duration + qrst_duration), einput);
const u32 tW2P = (CEIL(WL * 1.7303) * 2) - 5;
const u32 tWTPDEN = CEIL(((1.803 / tCK_avg) + MAX(RL + (2.694 / tCK_avg), static_cast<double>(tW2P))) + (BL / 2));
const u32 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;
const u32 tWTM = CEIL(WL + ((7.570 / tCK_avg) + 8.753));
const u32 tWATM = (tWTM + (FLOOR(WL / 0.816) * 2.0)) - 4.0;
const u32 wdv = WL; inline u32 tW2P;
const u32 wsv = WL - 2; inline u32 tWTPDEN;
const u32 wev = 0xA + (WL - 14); inline u32 tW2R;
inline u32 tWTM;
inline u32 tWATM;
const u32 obdlyHigh = 3 / FLOOR(MIN(static_cast<double>(2), tCK_avg * (WL - 7))); inline u32 wdv;
const u32 obdlyLow = MAX(WL - FLOOR((126.0 / CEIL(tCK_avg + 8.601))), 0.0); inline u32 wsv;
const u32 obdly = PACK_U32_NIBBLE_HIGH_BYTE_LOW(obdlyHigh, obdlyLow); inline u32 wev;
const u32 pdex2rw = CEIL((CEIL(12.335 - tCK_avg) + (7.430 / tCK_avg) - CEIL(tCK_avg * 11.361))); inline u32 obdly;
const u32 tCLKSTOP = FLOOR(MIN(8.488 / tCK_avg, 23.0)) + 8.0; inline u32 pdex2rw;
const double tMMRI = tRCD + (tCK_avg * 3); inline u32 tCLKSTOP;
const double pdex2mrr = tMMRI + 10; /* Do this properly? */
inline u32 pdex2mrr;
inline u8 mrw2; inline u8 mrw2;
} }

View File

@@ -18,17 +18,17 @@
#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"
#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)); \
*(offset) = value; *(offset) = value;
@@ -50,6 +50,9 @@ namespace ams::ldr {
R_DEFINE_ERROR_RESULT(UninitializedPatcher, 1013); R_DEFINE_ERROR_RESULT(UninitializedPatcher, 1013);
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(InvalidSocVoltPattern, 1017);
R_DEFINE_ERROR_RESULT(InvalidSocVoltLimit, 1018);
} }
namespace ams::ldr::hoc { namespace ams::ldr::hoc {
@@ -63,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

@@ -0,0 +1,132 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
*
* 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/>.
*/
/* See https://github.com/lulle2007200/emuMMC/blob/internal-emummc/source/ */
#include "oc_common.hpp"
#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING)
#include "fatal_handler_bin.h"
#endif
namespace ams::ldr::hoc {
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC 0x32454641
#define ATMOSPHERE_IRAM_PAYLOAD_BASE 0x40010000
#define ATMOSPHERE_FATAL_ERROR_ADDR 0x4003E000
_Alignas(4096) u8 working_buf[4096];
void SmcRebootToIramPayload() {
SecmonArgs args;
args.X[0] = 0xC3000401;
args.X[1] = 65001;
args.X[2] = 0;
args.X[3] = 2;
svcCallSecureMonitor(&args);
}
Result SmcCopyToIram(uintptr_t dest, const void *src, u32 size) {
SecmonArgs args;
args.X[0] = 0xF0000201;
args.X[1] = (u64)src;
args.X[2] = (u64)dest;
args.X[3] = size;
args.X[4] = 1;
svcCallSecureMonitor(&args);
Result rc = 0;
if (args.X[0] != 0) {
rc = (26u | ((u32)args.X[0] << 9u));
}
return rc;
}
Result SmcCopyFromIram(void *dest, uintptr_t src, u32 size) {
SecmonArgs args;
args.X[0] = 0xF0000201;
args.X[1] = (u64)dest;
args.X[2] = (u64)src;
args.X[3] = size;
args.X[4] = 0;
svcCallSecureMonitor(&args);
Result rc = 0;
if (args.X[0] != 0) {
rc = (26u | ((u32)args.X[0] << 9u));
}
return rc;
}
struct log_ctx_t {
u32 magic;
u32 sz;
u32 start;
u32 end;
char buf[];
};
#define IRAM_LOG_CTX_ADDR 0x4003C000
#define IRAM_LOG_MAX_SZ 4096
#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING)
void Log(const char *data, ...) {
static const u32 max_log_sz = sizeof(working_buf) - sizeof(log_ctx_t);
static bool initDone = false;
log_ctx_t *log_ctx = (log_ctx_t*)working_buf;
R_DISCARD(SmcCopyFromIram(working_buf, IRAM_LOG_CTX_ADDR, sizeof(working_buf)));
if (!initDone) {
initDone = true;
log_ctx->buf[0] = '\0';
log_ctx->magic = 0xaabbccdd;
log_ctx->start = 0;
log_ctx->end = 0;
}
va_list args;
va_start(args, data);
s32 res = vsnprintf(log_ctx->buf + log_ctx->end, max_log_sz - log_ctx->end, data, args);
va_end(args);
if (res < 0 || res >= (static_cast<s32>(max_log_sz - log_ctx->end))) {
R_DISCARD(SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf)));
return;
}
log_ctx->end += res;
R_DISCARD(SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf)));
}
#endif
#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING)
void ViewLog() {
if (spl::GetSocType() == spl::SocType_Mariko) {
return;
}
constexpr size_t PageSize = 4096;
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));
R_DISCARD(SmcCopyToIram(ATMOSPHERE_IRAM_PAYLOAD_BASE + ofs, &working_buf, std::min(fatal_handler_bin_size - ofs, PageSize)));
}
SmcRebootToIramPayload();
while(true){}
}
#endif
}

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) Atmosphère-NX * Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
* *
* 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
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -14,12 +15,13 @@
* 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__ EmcAccessTable2 /* See https://github.com/lulle2007200/emuMMC/blob/internal-emummc/source/ */
#define __ACCESS_TABLE_ADDRESS__ MemoryRegionPhysicalDeviceExternalMemoryController2.GetAddress()
#define __ACCESS_TABLE_INC__ "secmon_emc_access_table_data.inc"
#include "secmon_define_access_table.inc" #pragma once
#undef __ACCESS_TABLE_INC__ namespace ams::ldr::hoc {
#undef __ACCESS_TABLE_ADDRESS__
#undef __ACCESS_TABLE_NAME__ void Log(const char *data, ...);
void ViewLog();
}

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,48 +134,51 @@ 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);
if (isMariko) if (isMariko) {
mariko::Patch(mapped_nso, nso_size); mariko::Patch(mapped_nso, nso_size);
else } else {
erista::Patch(mapped_nso, nso_size); erista::Patch(mapped_nso, nso_size);
#endif }
} }
} }

View File

@@ -22,244 +22,11 @@
#include "../oc_common.hpp" #include "../oc_common.hpp"
#include "pcv_common.hpp" #include "pcv_common.hpp"
#include "pcv_erista.hpp"
#include "pcv_mariko.hpp"
namespace ams::ldr::hoc::pcv { namespace ams::ldr::hoc::pcv {
namespace mariko {
constexpr cvb_entry_t CpuCvbTableDefault[] = {
{ 204000, { 721589, -12695, 27 }, { } },
{ 306000, { 747134, -14195, 27 }, { } },
{ 408000, { 776324, -15705, 27 }, { } },
{ 510000, { 809160, -17205, 27 }, { } },
{ 612000, { 845641, -18715, 27 }, { } },
{ 714000, { 885768, -20215, 27 }, { } },
{ 816000, { 929540, -21725, 27 }, { } },
{ 918000, { 976958, -23225, 27 }, { } },
{ 1020000, { 1028021, -24725, 27 }, { 1120000 } },
{ 1122000, { 1082730, -26235, 27 }, { 1120000 } },
{ 1224000, { 1141084, -27735, 27 }, { 1120000 } },
{ 1326000, { 1203084, -29245, 27 }, { 1120000 } },
{ 1428000, { 1268729, -30745, 27 }, { 1120000 } },
{ 1581000, { 1374032, -33005, 27 }, { 1120000 } },
{ 1683000, { 1448791, -34505, 27 }, { 1120000 } },
{ 1785000, { 1527196, -36015, 27 }, { 1120000 } },
{ 1887000, { 1609246, -37515, 27 }, { 1120000 } },
{ 1963500, { 1675751, -38635, 27 }, { 1120000 } },
{ },
};
constexpr u32 CpuClkOfficial = 1963'500;
constexpr u32 CpuVoltOfficial = 1120;
constexpr u32 CpuVminOfficial = 620;
static const u32 cpuVoltagePatchValues[] = { 850, 38, 1120, 1000, 100, 1000, 0 };
static const s32 cpuVoltagePatchOffsets[] = { -2, -1, 5, 6, 7, 8, 9 };
static_assert(sizeof(cpuVoltagePatchValues) == sizeof(cpuVoltagePatchOffsets), "Invalid cpuVoltagePatch size");
static const u32 cpuVoltThermalData[] = { 620, 1120, 20000, 620, 1120, 70000, 950, 1132, 0, 950, 1227, 0 };
static const u32 allowedCpuMaxFrequencies[] = { 1'963'000, 2'091'000, 2'193'000, 2'295'000, 2'397'000, 2'499'000, 2'601'000, 2'703'000, };
constexpr cvb_entry_t GpuCvbTableDefault[] = {
// GPUB01_NA_CVB_TABLE
{ 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, } },
{ },
};
constexpr u32 GpuClkPllMax = 1300'000'000;
constexpr u32 GpuClkPllLimit = 2'600'000;
constexpr u32 GpuVminOfficial = 610;
static const u32 gpuDVFSPattern[] = { 1050, 1000, 100, 1000, 10, };
static const u32 gpuVoltThermalPattern[] = { 800, 1120, 0, 610, 1120, 20000, 610, 1120, 30000, 610, 1120, 50000, 610, 1120, 70000, 610, 1120, 90000, };
static_assert(sizeof(gpuVoltThermalPattern) == 72, "Invalid gpuVoltThermalPattern");
/* GPU Max Clock asm Pattern:
*
* MOV W11, #0x1000 MOV (wide immediate) 0x1000 0xB (11)
* 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
* 0 | 1 0 | 1 0 0 1 0 1| 0 0| 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 |0 1 0 1 1
*
* MOVK W11, #0xE, LSL#16 <shift>16 0xE 0xB (11)
* 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
* 0 | 1 1 | 1 0 0 1 0 1| 0 1| 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 |0 1 0 1 1
*/
inline constexpr u32 asm_pattern[] = {0x52820000, 0x72A001C0};
inline auto asm_compare_no_rd = [](u32 ins1, u32 ins2) {
return ((ins1 ^ ins2) >> 5) == 0;
};
inline auto asm_get_rd = [](u32 ins) {
return ins & ((1 << 5) - 1);
};
inline auto asm_set_rd = [](u32 ins, u8 rd) {
return (ins & 0xFFFFFFE0) | (rd & 0x1F);
};
inline auto asm_set_imm16 = [](u32 ins, u16 imm) {
return (ins & 0xFFE0001F) | ((imm & 0xFFFF) << 5);
};
inline bool GpuMaxClockPatternFn(u32 *ptr32) {
return asm_compare_no_rd(*ptr32, asm_pattern[0]);
}
constexpr emc_dvb_dvfs_table_t EmcDvbTableDefault[] = {
{ 204000, { 637, 637, 637, } },
{ 408000, { 637, 637, 637, } },
{ 800000, { 637, 637, 637, } },
{ 1065600, { 637, 637, 637, } },
{ 1331200, { 650, 637, 637, } },
{ 1600000, { 675, 650, 637, } },
};
constexpr u32 EmcClkOSAlt = 1331'200;
constexpr u32 EmcClkPllmLimit = 2133'000'000;
constexpr u32 EmcVddqDefault = 600'000;
constexpr u32 MemVdd2Default = 1100'000;
constexpr u32 MTC_TABLE_REV = 3;
void Patch(uintptr_t mapped_nso, size_t nso_size);
}
namespace 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[] = {
// CPU_PLL_CVB_TABLE_ODN
{ 204000, {721094}, { } },
{ 306000, {754040}, { } },
{ 408000, {786986}, { } },
{ 510000, {819932}, { } },
{ 612000, {852878}, { } },
{ 714000, {885824}, { } },
{ 816000, {918770}, { } },
{ 918000, {951716}, { } },
{ 1020000, {984662}, { -2875621, 358099, -8585} },
{ 1122000, {1017608}, { -52225, 104159, -2816} },
{ 1224000, {1050554}, { 1076868, 8356, -727} },
{ 1326000, {1083500}, { 2208191, -84659, 1240} },
{ 1428000, {1116446}, { 2519460, -105063, 1611} },
{ 1581000, {1130000}, { 2889664, -122173, 1834} },
{ 1683000, {1168000}, { 5100873, -279186, 4747} },
{ 1785000, {1227500}, { 5100873, -279186, 4747} },
{ },
};
constexpr u32 CpuVoltOfficial = 1227;
constexpr u32 CpuVminOfficial = 825;
constexpr u32 CpuVoltL4T = 1257'000;
static const u32 cpuVoltDvfsPattern[] = { 1227, 1000, 100, 1000, 0 };
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_assert(sizeof(cpuVoltageThermalPattern) == 0x3c, "invalid cpuVoltageThermalPattern size");
constexpr u32 GpuClkPllLimit = 2'600'000;
constexpr u32 GpuClkPllMax = 921'600'000;
constexpr u32 GpuVminOfficial = 810;
constexpr u16 CpuMinVolts[] = { 950, 850, 825, 810 };
inline bool CpuMaxVoltPatternFn(u32* ptr32) {
u32 val = *ptr32;
return (val == 1132 || val == 1170 || val == 1227);
}
static const u32 gpuVoltDvfsPattern[] = { 810, 1150, 1000, 100, 1000, 10, };
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_assert(sizeof(gpuVoltThermalPattern) == 0x48, "invalid gpuVoltageThermalPattern size");
/* GPU Max Clock asm Pattern:
*
* MOV W11, #0x1000 MOV (wide immediate) 0x1000 0xB (11)
* 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
* 0 | 1 0 | 1 0 0 1 0 1| 0 0| 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 |0 1 0 1 1
*
* MOVK W11, #0xE, LSL#16 <shift>16 0xE 0xB (11)
* 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
* 0 | 1 1 | 1 0 0 1 0 1| 0 1| 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 |0 1 0 1 1
*/
inline constexpr u32 asm_pattern[] = {
0x52820000, 0x72A001C0
};
inline auto asm_compare_no_rd = [](u32 ins1, u32 ins2) {
return ((ins1 ^ ins2) >> 5) == 0;
};
inline auto asm_get_rd = [](u32 ins) {
return ins & ((1 << 5) - 1);
};
inline auto asm_set_rd = [](u32 ins, u8 rd) {
return (ins & 0xFFFFFFE0) | (rd & 0x1F);
};
inline auto asm_set_imm16 = [](u32 ins, u16 imm) {
return (ins & 0xFFE0001F) | ((imm & 0xFFFF) << 5);
};
inline bool GpuMaxClockPatternFn(u32 *ptr32) {
return asm_compare_no_rd(*ptr32, asm_pattern[0]);
};
constexpr cvb_entry_t GpuCvbTableDefault[] = {
// NA_FREQ_CVB_TABLE
{ 76800, {}, { 814294, 8144, -940, 808, -21583, 226, } },
{ 153600, {}, { 856185, 8144, -940, 808, -21583, 226, } },
{ 230400, {}, { 898077, 8144, -940, 808, -21583, 226, } },
{ 307200, {}, { 939968, 8144, -940, 808, -21583, 226, } },
{ 384000, {}, { 981860, 8144, -940, 808, -21583, 226, } },
{ 460800, {}, { 1023751, 8144, -940, 808, -21583, 226, } },
{ 537600, {}, { 1065642, 8144, -940, 808, -21583, 226, } },
{ 614400, {}, { 1107534, 8144, -940, 808, -21583, 226, } },
{ 691200, {}, { 1149425, 8144, -940, 808, -21583, 226, } },
{ 768000, {}, { 1191317, 8144, -940, 808, -21583, 226, } },
{ 844800, {}, { 1233208, 8144, -940, 808, -21583, 226, } },
{ 921600, {}, { 1275100, 8144, -940, 808, -21583, 226, } },
{ },
};
constexpr u32 MemVoltHOS = 1125'000;
constexpr u32 EmcClkMinFreq = 40800; /* 40.8 MHz table only exists on erista. */
constexpr u32 EmcClkPllmLimit = 1866'000'000;
constexpr u32 MTC_TABLE_REV = 7;
void Patch(uintptr_t mapped_nso, size_t nso_size);
}
inline auto MatchesPattern = [](u32 *base, const auto &offsets, const auto &values) { inline auto MatchesPattern = [](u32 *base, const auto &offsets, const auto &values) {
for (size_t i = 0; i < std::size(values); ++i) { for (size_t i = 0; i < std::size(values); ++i) {
if (*(base + offsets[i]) != values[i]) { if (*(base + offsets[i]) != values[i]) {
@@ -351,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);
@@ -402,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;
@@ -417,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;
} }
} }
@@ -428,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

@@ -0,0 +1,169 @@
/*
* Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
*
* 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 <stratosphere.hpp>
namespace ams::ldr::hoc::pcv {
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) {
return ((ins1 ^ ins2) >> 5) == 0;
};
inline auto asm_get_rd = [](u32 ins) {
return ins & ((1 << 5) - 1);
};
inline auto asm_set_rd = [](u32 ins, u8 rd) {
return (ins & 0xFFFFFFE0) | (rd & 0x1F);
};
inline auto asm_set_imm16 = [](u32 ins, u16 imm) {
return (ins & 0xFFE0001F) | ((imm & 0xFFFF) << 5);
};
inline auto AsmGetImm16 = [](u32 ins) {
return static_cast<u16>((ins >> 5) & 0xFFFF);
};
inline auto AsmCompareBrNoRd = [](u32 ins1, u32 ins2) {
constexpr u32 RegMask = ~(((1 << 5) - 1) << 5);
return ((ins1 & RegMask) ^ (ins2 & RegMask)) == 0;
};
inline auto AsmCompareAddNoImm12 = [](u32 ins1, u32 ins2) {
constexpr u32 Imm12Mask = ~(((1 << 12) - 1) << 10);
return ((ins1 & Imm12Mask) ^ (ins2 & Imm12Mask)) == 0;
};
inline auto AsmCompareAdrpNoImm = [](u32 ins1, u32 ins2) {
constexpr u32 ImmMask = ~((((1 << 2) - 1) << 29) | (((1 << 19) - 1) << 5));
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,40 +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 emc_dvb_dvfs_table_t { struct __attribute__((packed)) div_nmp {
u64 freq;
s32 volt[4] = {0};
} emc_dvb_dvfs_table_t;
typedef struct __attribute__((packed)) div_nmp {
u8 divn_shift; u8 divn_shift;
u8 divn_width; u8 divn_width;
u8 divm_shift; u8 divm_shift;
@@ -61,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;
@@ -77,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;
@@ -89,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;
@@ -115,11 +112,30 @@ 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);
constexpr u32 CpuClkOSLimit = 1785'000; 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 GpuClkOsLimit = 921'600;
constexpr u32 EmcClkOSLimit = 1600'000; constexpr u32 EmcClkOSLimit = 1600'000;
#define R_SKIP() R_SUCCEED() #define R_SKIP() R_SUCCEED()
@@ -129,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;
@@ -142,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++)) {
@@ -154,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,13 +139,15 @@ 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, asm_pattern[0]) && asm_compare_no_rd(ins2, asm_pattern[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()); R_THROW(ldr::ResultInvalidGpuFreqMaxPattern());
}
u32 max_clock; u32 max_clock;
switch (C.eristaGpuUV) { switch (C.eristaGpuUV) {
@@ -157,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(asm_pattern[0], max_clock), rd), asm_set_rd(asm_set_imm16(GpuAsmPattern[0], max_clock), rd),
asm_set_rd(asm_set_imm16(asm_pattern[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();
@@ -204,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));
@@ -233,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);
@@ -246,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);
@@ -268,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;
@@ -319,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;
@@ -348,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();
} }
@@ -444,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)) {
@@ -471,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

@@ -0,0 +1,163 @@
/*
* Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
*
* 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 "../oc_common.hpp"
#include "pcv_common.hpp"
#include "pcv_asm.hpp"
namespace ams::ldr::hoc::pcv::erista {
constexpr cvb_entry_t CpuCvbTableDefault[] = {
// CPU_PLL_CVB_TABLE_ODN
{ 204000, {721094}, { } },
{ 306000, {754040}, { } },
{ 408000, {786986}, { } },
{ 510000, {819932}, { } },
{ 612000, {852878}, { } },
{ 714000, {885824}, { } },
{ 816000, {918770}, { } },
{ 918000, {951716}, { } },
{ 1020000, {984662}, { -2875621, 358099, -8585} },
{ 1122000, {1017608}, { -52225, 104159, -2816} },
{ 1224000, {1050554}, { 1076868, 8356, -727} },
{ 1326000, {1083500}, { 2208191, -84659, 1240} },
{ 1428000, {1116446}, { 2519460, -105063, 1611} },
{ 1581000, {1130000}, { 2889664, -122173, 1834} },
{ 1683000, {1168000}, { 5100873, -279186, 4747} },
{ 1785000, {1227500}, { 5100873, -279186, 4747} },
{ },
};
constexpr u32 CpuVoltOfficial = 1227;
constexpr u32 CpuVminOfficial = 825;
constexpr u32 CpuTune0Low = 0xFFEAD0FF;
constexpr u32 CpuVoltL4T = 1257'000;
static const u32 cpuVoltDvfsPattern[] = { 1227, 1000, 100, 1000, 0 };
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_assert(sizeof(cpuVoltageThermalPattern) == 0x3c, "Invalid cpuVoltageThermalPattern size");
constexpr u32 GpuClkPllLimit = 2'600'000;
constexpr u32 GpuClkPllMax = 921'600'000;
constexpr u32 GpuVminOfficial = 810;
constexpr u16 CpuMinVolts[] = { 950, 850, 825, 810 };
static const u32 gpuVoltDvfsPattern[] = { 810, 1150, 1000, 100, 1000, 10, };
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_assert(sizeof(gpuVoltThermalPattern) == 0x48, "Invalid gpuVoltageThermalPattern size");
/* GPU Max Clock asm Pattern:
*
* MOV W11, #0x1000 MOV (wide immediate) 0x1000 0xB (11)
* 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
* 0 | 1 0 | 1 0 0 1 0 1| 0 0| 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 |0 1 0 1 1
*
* MOVK W11, #0xE, LSL#16 <shift>16 0xE 0xB (11)
* 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
* 0 | 1 1 | 1 0 0 1 0 1| 0 1| 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 |0 1 0 1 1
*/
inline constexpr u32 GpuAsmPattern[] = { 0x52820000, 0x72A001C0 };
inline bool GpuMaxClockPatternFn(u32 *ptr32) {
return asm_compare_no_rd(*ptr32, GpuAsmPattern[0]);
};
constexpr cvb_entry_t GpuCvbTableDefault[] = {
// NA_FREQ_CVB_TABLE
{ 76800, {}, { 814294, 8144, -940, 808, -21583, 226, } },
{ 153600, {}, { 856185, 8144, -940, 808, -21583, 226, } },
{ 230400, {}, { 898077, 8144, -940, 808, -21583, 226, } },
{ 307200, {}, { 939968, 8144, -940, 808, -21583, 226, } },
{ 384000, {}, { 981860, 8144, -940, 808, -21583, 226, } },
{ 460800, {}, { 1023751, 8144, -940, 808, -21583, 226, } },
{ 537600, {}, { 1065642, 8144, -940, 808, -21583, 226, } },
{ 614400, {}, { 1107534, 8144, -940, 808, -21583, 226, } },
{ 691200, {}, { 1149425, 8144, -940, 808, -21583, 226, } },
{ 768000, {}, { 1191317, 8144, -940, 808, -21583, 226, } },
{ 844800, {}, { 1233208, 8144, -940, 808, -21583, 226, } },
{ 921600, {}, { 1275100, 8144, -940, 808, -21583, 226, } },
{ },
};
constexpr u32 EmcListDefault[] = { 40800, 68000, 102000, 204000, 408000, 665600, 800000, 1065600, 1331200, 1600000, };
constexpr u32 EmcListSizeDefault = std::size(EmcListDefault);
constexpr u32 EmcListEndDefault = EmcListSizeDefault - 1;
constexpr u32 MemVoltHOS = 1125'000;
constexpr u32 EmcClkPllmLimit = 1866'000'000;
constexpr u32 MTC_TABLE_REV = 7;
constexpr u32 MtcTableCountDefault = 10;
constexpr size_t MtcFullTableSize = sizeof(EristaMtcTable) * MtcTableCountDefault;
constexpr u32 MtcFullTableCount = 3;
/* These dramids were copied from Hekate -- see /bdk/mem/sdram.h */
enum DramId {
ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0,
ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1,
ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC = 2,
ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4,
ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7,
};
enum MtcTableIndex {
T210SdevEmcDvfsTableS4gb01 = 0, /* HB-MGCH, WT:C */
T210SdevEmcDvfsTableS6gb01 = 1, /* HM-MGCH */
T210SdevEmcDvfsTableH4gb01 = 2, /* HR-NLE */
MtcTableIndex_Invalid = 3,
};
struct MtcDramIndex {
DramId dramId;
MtcTableIndex index;
};
const inline MtcDramIndex mtcIndexTable[] = {
{ ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH, T210SdevEmcDvfsTableS4gb01, },
{ ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC, T210SdevEmcDvfsTableS4gb01, },
{ 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);
}

View File

@@ -0,0 +1,304 @@
/*
* Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
*
* 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 "../oc_common.hpp"
#include "pcv_common.hpp"
#include "pcv_asm.hpp"
namespace ams::ldr::hoc::pcv::mariko {
constexpr cvb_entry_t CpuCvbTableDefault[] = {
{ 204000, { 721589, -12695, 27 }, { } },
{ 306000, { 747134, -14195, 27 }, { } },
{ 408000, { 776324, -15705, 27 }, { } },
{ 510000, { 809160, -17205, 27 }, { } },
{ 612000, { 845641, -18715, 27 }, { } },
{ 714000, { 885768, -20215, 27 }, { } },
{ 816000, { 929540, -21725, 27 }, { } },
{ 918000, { 976958, -23225, 27 }, { } },
{ 1020000, { 1028021, -24725, 27 }, { 1120000 } },
{ 1122000, { 1082730, -26235, 27 }, { 1120000 } },
{ 1224000, { 1141084, -27735, 27 }, { 1120000 } },
{ 1326000, { 1203084, -29245, 27 }, { 1120000 } },
{ 1428000, { 1268729, -30745, 27 }, { 1120000 } },
{ 1581000, { 1374032, -33005, 27 }, { 1120000 } },
{ 1683000, { 1448791, -34505, 27 }, { 1120000 } },
{ 1785000, { 1527196, -36015, 27 }, { 1120000 } },
{ 1887000, { 1609246, -37515, 27 }, { 1120000 } },
{ 1963500, { 1675751, -38635, 27 }, { 1120000 } },
{ },
};
constexpr u32 CpuClkOfficial = 1963'500;
constexpr u32 CpuVoltOfficial = 1120;
constexpr u32 CpuHighVminOfficial = 850;
constexpr u32 CpuVminOfficial = 620;
constexpr u32 CpuTune0Low = 0xFFCF;
static const u32 cpuVoltagePatchValues[] = { 850, 38, 1120, 1000, 100, 1000, 0 };
static const s32 cpuVoltagePatchOffsets[] = { -2, -1, 5, 6, 7, 8, 9 };
static_assert(sizeof(cpuVoltagePatchValues) == sizeof(cpuVoltagePatchOffsets), "Invalid cpuVoltagePatch size");
static const u32 cpuVoltThermalData[] = { 620, 1120, 20000, 620, 1120, 70000, 950, 1132, 0, 950, 1227, 0 };
static const u32 allowedCpuMaxFrequencies[] = { 1'963'500, 2'091'000, 2'193'000, 2'295'000, 2'397'000, 2'499'000, 2'601'000, 2'703'000, };
constexpr cvb_entry_t GpuCvbTableDefault[] = {
// GPUB01_NA_CVB_TABLE
{ 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, } },
{ },
};
constexpr u32 GpuClkPllMax = 1300'000'000;
constexpr u32 GpuClkPllLimit = 2'600'000;
constexpr u32 GpuVminOfficial = 610;
static const u32 gpuDVFSPattern[] = { 1050, 1000, 100, 1000, 10, };
static const u32 gpuVoltThermalPattern[] = { 800, 1120, 0, 610, 1120, 20000, 610, 1120, 30000, 610, 1120, 50000, 610, 1120, 70000, 610, 1120, 90000, };
static_assert(sizeof(gpuVoltThermalPattern) == 72, "Invalid gpuVoltThermalPattern");
/* GPU Max Clock asm Pattern:
*
* MOV W11, #0x1000 MOV (wide immediate) 0x1000 0xB (11)
* 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
* 0 | 1 0 | 1 0 0 1 0 1| 0 0| 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 |0 1 0 1 1
*
* MOVK W11, #0xE, LSL#16 <shift>16 0xE 0xB (11)
* 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
* 0 | 1 1 | 1 0 0 1 0 1| 0 1| 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 |0 1 0 1 1
*/
inline constexpr u32 GpuAsmPattern[] = { 0x52820000, 0x72A001C0 };
inline bool GpuMaxClockPatternFn(u32 *ptr32) {
return asm_compare_no_rd(*ptr32, GpuAsmPattern[0]);
}
struct DvbEntry {
u64 freq;
u32 volt[4] = {};
};
constexpr DvbEntry EmcDvbTableDefault[] = {
{ 204000, { 637, 637, 637, } },
{ 408000, { 637, 637, 637, } },
{ 800000, { 637, 637, 637, } },
{ 1065600, { 637, 637, 637, } },
{ 1331200, { 650, 637, 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 EmcListSizeDefault = std::size(EmcListDefault);
constexpr u32 EmcListEndDefault = EmcListSizeDefault - 1;
constexpr u32 EmcClkOSAlt = 1331'200;
constexpr u32 EmcClkPllmLimit = 2133'000'000;
constexpr u32 EmcVddqDefault = 600'000;
constexpr u32 MemVdd2Default = 1100'000;
constexpr u32 MTC_TABLE_REV = 3;
constexpr u32 MtcTableCountDefault = 3;
constexpr size_t MtcFullTableSize = sizeof(MarikoMtcTable) * MtcTableCountDefault;
constexpr u32 MtcFullTableCount = 17;
/* These dramids were copied from Hekate -- see /bdk/mem/sdram.h */
enum DramId : u64 {
HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3,
AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5,
IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6,
IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8,
IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9,
IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10,
IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE = 11,
HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12,
HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13,
HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14,
HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE = 15,
IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17,
IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18,
HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19,
IOWA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 20,
HOAG_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 21,
AULA_4GB_SAMSUNG_K4U6E3S4AB_MGCL = 22,
HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23,
AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24,
IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25,
HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26,
AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27,
AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28,
IOWA_4GB_HYNIX_H54G46CYRBX267 = 29,
HOAG_4GB_HYNIX_H54G46CYRBX267 = 30,
AULA_4GB_HYNIX_H54G46CYRBX267 = 31,
IOWA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 32,
HOAG_4GB_MICRON_MT53E512M32D1NP_046_WTB = 33,
AULA_4GB_MICRON_MT53E512M32D1NP_046_WTB = 34,
};
enum MtcTableIndex {
T210b0SdevEmcDvfsTableS4gb01 = 0, /* (Unused) Samsung 4Gb */
T210b0SdevEmcDvfsTableS4gb03 = 1, /* Samsung AM-MGCJ 4Gb */
T210b0SdevEmcDvfsTableS8gb03 = 2, /* (Unused) Samsung 4Gb */
T210b0SdevEmcDvfsTableH4gb03 = 3, /* Hynix NME 4Gb */
T210b0SdevEmcDvfsTableM4gb03 = 4, /* Micron WT:F 4Gb */
T210b0SdevEmcDvfsTableS4gbY01 = 5, /* (Unused) Samsung 4Gb */
T210b0SdevEmcDvfsTableS1y4gbY01 = 6, /* (Unused) Samsung 4Gb */
T210b0SdevEmcDvfsTableS1y8gbY01 = 7, /* (Unused) Samsung 4Gb */
T210b0SdevEmcDvfsTableS1y4gbX03 = 8, /* Samsung AA-MGCL 4Gb */
T210b0SdevEmcDvfsTableS1y8gbX03 = 9, /* Samsung AA-MGCL 8Gb */
T210b0SdevEmcDvfsTableS1y4gb01 = 10, /* (Unused) Samsung 4Gb */
T210b0SdevEmcDvfsTableM1y4gb01 = 11, /* Micron WT:E 4Gb */
T210b0SdevEmcDvfsTableH1y4gb01 = 12, /* Hynix NEE 4Gb */
T210b0SdevEmcDvfsTableS1y8gb04 = 13, /* Samsung AM-MGCJ 8Gb */
T210b0SdevEmcDvfsTableS1z4gb01 = 14, /* Samsung AB-MGCL 4Gb */
T210b0SdevEmcDvfsTableH1a4gb01 = 15, /* Hynix x267 4Gb */
T210b0SdevEmcDvfsTableM1a4gb01 = 16, /* Micron WT:B 8Gb */
MtcTableIndex_Invalid = 17,
};
struct MtcDramIndex {
DramId dramId;
MtcTableIndex index;
};
const inline MtcDramIndex mtcIndexTable[] = {
{ HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, },
{ AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, },
{ IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, },
{ IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ, T210b0SdevEmcDvfsTableS4gb03, },
{ IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ, T210b0SdevEmcDvfsTableS1y8gb04, },
{ IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME, T210b0SdevEmcDvfsTableH4gb03, },
{ IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTE, T210b0SdevEmcDvfsTableM1y4gb01, },
{ HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ, T210b0SdevEmcDvfsTableS4gb03, },
{ HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ, T210b0SdevEmcDvfsTableS1y8gb04, },
{ HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME, T210b0SdevEmcDvfsTableH4gb03, },
{ HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTE, T210b0SdevEmcDvfsTableM1y4gb01, },
{ IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL, T210b0SdevEmcDvfsTableS1y4gbX03, },
{ IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL, T210b0SdevEmcDvfsTableS1y8gbX03, },
{ HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL, T210b0SdevEmcDvfsTableS1y4gbX03, },
{ IOWA_4GB_SAMSUNG_K4U6E3S4AB_MGCL, T210b0SdevEmcDvfsTableS1z4gb01, },
{ HOAG_4GB_SAMSUNG_K4U6E3S4AB_MGCL, T210b0SdevEmcDvfsTableS1y8gb04, },
{ AULA_4GB_SAMSUNG_K4U6E3S4AB_MGCL, T210b0SdevEmcDvfsTableS1y8gb04, },
{ HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL, T210b0SdevEmcDvfsTableS1y8gbX03, },
{ AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL, T210b0SdevEmcDvfsTableS1y4gbX03, },
{ IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF, T210b0SdevEmcDvfsTableM4gb03, },
{ HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF, T210b0SdevEmcDvfsTableM4gb03, },
{ AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF, T210b0SdevEmcDvfsTableM4gb03, },
{ AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL, T210b0SdevEmcDvfsTableS1y8gbX03, },
{ IOWA_4GB_HYNIX_H54G46CYRBX267, T210b0SdevEmcDvfsTableH1a4gb01, },
{ HOAG_4GB_HYNIX_H54G46CYRBX267, T210b0SdevEmcDvfsTableH1a4gb01, },
{ AULA_4GB_HYNIX_H54G46CYRBX267, T210b0SdevEmcDvfsTableH1a4gb01, },
{ IOWA_4GB_MICRON_MT53E512M32D1NP_046_WTB, T210b0SdevEmcDvfsTableM1a4gb01, },
{ HOAG_4GB_MICRON_MT53E512M32D1NP_046_WTB, T210b0SdevEmcDvfsTableM1a4gb01, },
{ AULA_4GB_MICRON_MT53E512M32D1NP_046_WTB, T210b0SdevEmcDvfsTableM1a4gb01, },
};
/*
710006abfc 40 01 1f d6 br x10
*/
/*
710006ac28 a0 03 00 90 adrp x0,0x71000de000
710006ac2c 00 80 16 91 add x0=>SdevEmcDvfsTableS4gb01,x0,#0x5a0
*/
/* Br */
/*
| Z | OP | Fixed | A | M | RN | RM
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
1 1 0 1 0 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 Rn 0 0 0 0 0
Z op A M Rm
*/
/* Adrp */
/*
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
*/
/* ADD (immediate) */
/*
SF | OP | S | Fixed value | 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
*/
constexpr u32 MtcBrAsm = 0xD61F0140;
constexpr u32 MtcMovAsm = 0x52800068;
constexpr u32 MtcAdrpAsm = 0x900003A0;
constexpr u32 MtcAddAsm = 0x91168000;
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);
}

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

@@ -38,7 +38,7 @@ include $(DEVKITPRO)/libnx/switch_rules
# NACP building is skipped as well. # NACP building is skipped as well.
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
APP_TITLE := Horizon OC Monitor APP_TITLE := Horizon OC Monitor
APP_VERSION := 1.3.2+r4-hoc-r3 APP_VERSION := 1.3.2+r4-hoc-r4
TARGET := $(notdir $(CURDIR)) TARGET := $(notdir $(CURDIR))
BUILD := build BUILD := build
SOURCES := source SOURCES := source
@@ -65,6 +65,7 @@ IS_STATUS_MONITOR_DIRECTIVE := 1
CFLAGS += -DIS_STATUS_MONITOR_DIRECTIVE=$(IS_STATUS_MONITOR_DIRECTIVE) CFLAGS += -DIS_STATUS_MONITOR_DIRECTIVE=$(IS_STATUS_MONITOR_DIRECTIVE)
# Enable appearance overriding # Enable appearance overriding
export MSYS2_ARG_CONV_EXCL := -DUI_OVERRIDE_PATH
UI_OVERRIDE_PATH := /config/status-monitor/ UI_OVERRIDE_PATH := /config/status-monitor/
CFLAGS += -DUI_OVERRIDE_PATH="\"$(UI_OVERRIDE_PATH)\"" CFLAGS += -DUI_OVERRIDE_PATH="\"$(UI_OVERRIDE_PATH)\""

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;
@@ -583,8 +559,12 @@ void Misc(void*) {
realCPU_Hz = hocclkCTX.realFreqs[HocClkModule_CPU]; realCPU_Hz = hocclkCTX.realFreqs[HocClkModule_CPU];
realGPU_Hz = hocclkCTX.realFreqs[HocClkModule_GPU]; realGPU_Hz = hocclkCTX.realFreqs[HocClkModule_GPU];
realRAM_Hz = hocclkCTX.realFreqs[HocClkModule_MEM]; realRAM_Hz = hocclkCTX.realFreqs[HocClkModule_MEM];
partLoad[HocClkPartLoad_EMC] = hocclkCTX.partLoad[HocClkPartLoad_EMC]; partLoad[HocClkPartLoad_EMC] = hocclkCTX.partLoad[HocClkPartLoad_EMC];
partLoad[HocClkPartLoad_EMCCpu] = hocclkCTX.partLoad[HocClkPartLoad_EMCCpu]; partLoad[HocClkPartLoad_EMCCpu] = hocclkCTX.partLoad[HocClkPartLoad_EMCCpu];
partLoad[HocClkPartLoad_RamBWAll] = hocclkCTX.partLoad[HocClkPartLoad_RamBWAll];
partLoad[HocClkPartLoad_RamBWCpu] = hocclkCTX.partLoad[HocClkPartLoad_RamBWCpu];
partLoad[HocClkPartLoad_RamBWGpu] = hocclkCTX.partLoad[HocClkPartLoad_RamBWGpu];
partLoad[HocClkPartLoad_RamBWPeak] = hocclkCTX.partLoad[HocClkPartLoad_RamBWPeak];
realCPU_Temp = hocclkCTX.temps[HocClkThermalSensor_CPU]; realCPU_Temp = hocclkCTX.temps[HocClkThermalSensor_CPU];
realGPU_Temp = hocclkCTX.temps[HocClkThermalSensor_GPU]; realGPU_Temp = hocclkCTX.temps[HocClkThermalSensor_GPU];
realPLLX_Temp = hocclkCTX.temps[HocClkThermalSensor_PLLX]; realPLLX_Temp = hocclkCTX.temps[HocClkThermalSensor_PLLX];
@@ -595,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];
} }
} }
@@ -714,8 +697,12 @@ void Misc3(void*) {
if (R_SUCCEEDED(hocclkCheck)) { if (R_SUCCEEDED(hocclkCheck)) {
HocClkContext hocclkCTX; HocClkContext hocclkCTX;
if (R_SUCCEEDED(hocclkIpcGetCurrentContext(&hocclkCTX))) { if (R_SUCCEEDED(hocclkIpcGetCurrentContext(&hocclkCTX))) {
partLoad[HocClkPartLoad_EMC] = hocclkCTX.partLoad[HocClkPartLoad_EMC]; partLoad[HocClkPartLoad_EMC] = hocclkCTX.partLoad[HocClkPartLoad_EMC];
partLoad[HocClkPartLoad_EMCCpu] = hocclkCTX.partLoad[HocClkPartLoad_EMCCpu]; partLoad[HocClkPartLoad_EMCCpu] = hocclkCTX.partLoad[HocClkPartLoad_EMCCpu];
partLoad[HocClkPartLoad_RamBWAll] = hocclkCTX.partLoad[HocClkPartLoad_RamBWAll];
partLoad[HocClkPartLoad_RamBWCpu] = hocclkCTX.partLoad[HocClkPartLoad_RamBWCpu];
partLoad[HocClkPartLoad_RamBWGpu] = hocclkCTX.partLoad[HocClkPartLoad_RamBWGpu];
partLoad[HocClkPartLoad_RamBWPeak] = hocclkCTX.partLoad[HocClkPartLoad_RamBWPeak];
realCPU_Temp = hocclkCTX.temps[HocClkThermalSensor_CPU]; realCPU_Temp = hocclkCTX.temps[HocClkThermalSensor_CPU];
realGPU_Temp = hocclkCTX.temps[HocClkThermalSensor_GPU]; realGPU_Temp = hocclkCTX.temps[HocClkThermalSensor_GPU];
@@ -1274,6 +1261,7 @@ struct FullSettings {
bool showFPS; bool showFPS;
bool showRES; bool showRES;
bool showRDSD; bool showRDSD;
std::string ramInfoMode;
bool useDynamicColors; bool useDynamicColors;
bool disableScreenshots; bool disableScreenshots;
uint16_t separatorColor; uint16_t separatorColor;
@@ -1309,6 +1297,7 @@ struct MiniSettings {
std::string show; std::string show;
bool showpartLoad; bool showpartLoad;
bool showpartLoadCPUGPU; bool showpartLoadCPUGPU;
std::string ramInfoMode;
bool invertBatteryDisplay; bool invertBatteryDisplay;
bool disableScreenshots; bool disableScreenshots;
bool sleepExit; bool sleepExit;
@@ -1343,6 +1332,7 @@ struct MicroSettings {
uint16_t textColor; uint16_t textColor;
std::string show; std::string show;
bool showpartLoad; bool showpartLoad;
std::string ramInfoMode;
bool setPosBottom; bool setPosBottom;
bool disableScreenshots; bool disableScreenshots;
bool sleepExit; bool sleepExit;
@@ -1430,6 +1420,7 @@ ALWAYS_INLINE void GetConfigSettings(MiniSettings* settings) {
settings->show = "DTC+BAT+CPU+GPU+RAM+TMP+FPS+RES"; settings->show = "DTC+BAT+CPU+GPU+RAM+TMP+FPS+RES";
settings->showpartLoad = true; settings->showpartLoad = true;
settings->showpartLoadCPUGPU = false; settings->showpartLoadCPUGPU = false;
settings->ramInfoMode = "LOAD";
settings->invertBatteryDisplay = true; settings->invertBatteryDisplay = true;
settings->refreshRate = 1; settings->refreshRate = 1;
settings->disableScreenshots = false; settings->disableScreenshots = false;
@@ -1639,6 +1630,12 @@ ALWAYS_INLINE void GetConfigSettings(MiniSettings* settings) {
settings->showpartLoadCPUGPU = (key != "FALSE"); settings->showpartLoadCPUGPU = (key != "FALSE");
} }
// Process RAM info mode
it = section.find("ram_info_mode");
if (it != section.end()) {
settings->ramInfoMode = it->second;
}
// Invert the battery display value // Invert the battery display value
it = section.find("invert_battery_display"); it = section.find("invert_battery_display");
if (it != section.end()) { if (it != section.end()) {
@@ -1718,8 +1715,8 @@ ALWAYS_INLINE void GetConfigSettings(MicroSettings* settings) {
settings->useDTCSymbol = true; settings->useDTCSymbol = true;
settings->dtcFormat = "%H:%M:%S";//"%Y-%m-%d %I:%M:%S %p"; settings->dtcFormat = "%H:%M:%S";//"%Y-%m-%d %I:%M:%S %p";
settings->invertBatteryDisplay = false; settings->invertBatteryDisplay = false;
settings->handheldFontSize = 15; settings->handheldFontSize = 14;
settings->dockedFontSize = 15; settings->dockedFontSize = 14;
settings->alignTo = 1; // CENTER settings->alignTo = 1; // CENTER
convertStrToRGBA4444("#0009", &(settings->backgroundColor)); convertStrToRGBA4444("#0009", &(settings->backgroundColor));
convertStrToRGBA4444("#888F", &(settings->separatorColor)); convertStrToRGBA4444("#888F", &(settings->separatorColor));
@@ -1727,6 +1724,7 @@ ALWAYS_INLINE void GetConfigSettings(MicroSettings* settings) {
convertStrToRGBA4444("#FFFF", &(settings->textColor)); convertStrToRGBA4444("#FFFF", &(settings->textColor));
settings->show = "FPS+CPU+GPU+RAM+SOC+BAT+DTC"; settings->show = "FPS+CPU+GPU+RAM+SOC+BAT+DTC";
settings->showpartLoad = true; settings->showpartLoad = true;
settings->ramInfoMode = "LOAD";
settings->setPosBottom = false; settings->setPosBottom = false;
settings->disableScreenshots = false; settings->disableScreenshots = false;
settings->sleepExit = false; settings->sleepExit = false;
@@ -1926,6 +1924,12 @@ ALWAYS_INLINE void GetConfigSettings(MicroSettings* settings) {
settings->showpartLoad = (key != "FALSE"); settings->showpartLoad = (key != "FALSE");
} }
// Process RAM info mode
it = section.find("ram_info_mode");
if (it != section.end()) {
settings->ramInfoMode = it->second;
}
// Process show string // Process show string
it = section.find("show"); it = section.find("show");
if (it != section.end()) { if (it != section.end()) {
@@ -2257,6 +2261,7 @@ ALWAYS_INLINE void GetConfigSettings(FullSettings* settings) {
settings->showFPS = true; settings->showFPS = true;
settings->showRES = true; settings->showRES = true;
settings->showRDSD = true; settings->showRDSD = true;
settings->ramInfoMode = "LOAD";
settings->useDynamicColors = true; settings->useDynamicColors = true;
settings->disableScreenshots = false; settings->disableScreenshots = false;
convertStrToRGBA4444("#888F", &(settings->separatorColor)); convertStrToRGBA4444("#888F", &(settings->separatorColor));
@@ -2352,6 +2357,11 @@ ALWAYS_INLINE void GetConfigSettings(FullSettings* settings) {
settings->showRDSD = !(key == "FALSE"); settings->showRDSD = !(key == "FALSE");
} }
it = section.find("ram_info_mode");
if (it != section.end()) {
settings->ramInfoMode = it->second;
}
it = section.find("use_dynamic_colors"); it = section.find("use_dynamic_colors");
if (it != section.end()) { if (it != section.end()) {
key = it->second; key = it->second;

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

@@ -377,6 +377,21 @@ public:
}); });
list->addItem(showRDSD); list->addItem(showRDSD);
{
const std::string curRamInfoMode = getCurrentRamInfoMode("full");
auto* ramInfoModeItem = new tsl::elm::ListItem("RAM Info Mode");
ramInfoModeItem->setValue(curRamInfoMode);
ramInfoModeItem->setClickListener([this, ramInfoModeItem](u64 keys) -> bool {
if (!(keys & KEY_A)) return false;
const std::string cur = ult::parseValueFromIniSection(configIniPath, "full", "ram_info_mode");
const std::string next = cur == "Bandwidth" ? "Load" : "Bandwidth";
ult::setIniFileValue(configIniPath, "full", "ram_info_mode", next);
ramInfoModeItem->setValue(next);
return true;
});
list->addItem(ramInfoModeItem);
}
auto* dynamicColors = new tsl::elm::ToggleListItem("Use Dynamic Colors", getCurrentUseDynamicColors()); auto* dynamicColors = new tsl::elm::ToggleListItem("Use Dynamic Colors", getCurrentUseDynamicColors());
dynamicColors->setStateChangedListener([this](bool state) { dynamicColors->setStateChangedListener([this](bool state) {
ult::setIniFileValue(configIniPath, "fps-graph", "use_dynamic_colors", state ? "true" : "false"); ult::setIniFileValue(configIniPath, "fps-graph", "use_dynamic_colors", state ? "true" : "false");
@@ -417,13 +432,13 @@ public:
}); });
list->addItem(showFullCPU); list->addItem(showFullCPU);
auto* showVDDQ = new tsl::elm::ToggleListItem("VDD2", getCurrentShowVDDQ()); auto* showVDDQ = new tsl::elm::ToggleListItem("VDDQ", getCurrentShowVDDQ());
showVDDQ->setStateChangedListener([this, section](bool state) { showVDDQ->setStateChangedListener([this, section](bool state) {
ult::setIniFileValue(configIniPath, section, "show_vddq", state ? "true" : "false"); ult::setIniFileValue(configIniPath, section, "show_vddq", state ? "true" : "false");
}); });
list->addItem(showVDDQ); list->addItem(showVDDQ);
auto* showVDD2 = new tsl::elm::ToggleListItem("VDDQ", getCurrentShowVDD2()); auto* showVDD2 = new tsl::elm::ToggleListItem("VDD2", getCurrentShowVDD2());
showVDD2->setStateChangedListener([this, section](bool state) { showVDD2->setStateChangedListener([this, section](bool state) {
ult::setIniFileValue(configIniPath, section, "show_vdd2", state ? "true" : "false"); ult::setIniFileValue(configIniPath, section, "show_vdd2", state ? "true" : "false");
}); });
@@ -449,6 +464,21 @@ public:
list->addItem(partLoadCPUGPU); list->addItem(partLoadCPUGPU);
} }
if (isMiniMode || isMicroMode) {
const std::string curRamInfoMode = getCurrentRamInfoMode(section);
auto* ramInfoModeItem = new tsl::elm::ListItem("RAM Info Mode");
ramInfoModeItem->setValue(curRamInfoMode);
ramInfoModeItem->setClickListener([this, section, ramInfoModeItem](u64 keys) -> bool {
if (!(keys & KEY_A)) return false;
const std::string cur = ult::parseValueFromIniSection(configIniPath, section, "ram_info_mode");
const std::string next = cur == "Bandwidth" ? "Load" : "Bandwidth";
ult::setIniFileValue(configIniPath, section, "ram_info_mode", next);
ramInfoModeItem->setValue(next);
return true;
});
list->addItem(ramInfoModeItem);
}
if (isMiniMode || isMicroMode) { if (isMiniMode || isMicroMode) {
auto* invertBatteryDisplay = new tsl::elm::ToggleListItem("Invert Battery Display", getCurrentInvertBatteryDisplay()); auto* invertBatteryDisplay = new tsl::elm::ToggleListItem("Invert Battery Display", getCurrentInvertBatteryDisplay());
invertBatteryDisplay->setStateChangedListener([this, section](bool state) { invertBatteryDisplay->setStateChangedListener([this, section](bool state) {
@@ -616,6 +646,11 @@ private:
return value != "FALSE"; return value != "FALSE";
} }
std::string getCurrentRamInfoMode(const std::string& section) {
const std::string value = ult::parseValueFromIniSection(configIniPath, section, "ram_info_mode");
return (value == "Bandwidth") ? "Bandwidth" : "Load";
}
bool getCurrentInvertBatteryDisplay() { bool getCurrentInvertBatteryDisplay() {
const std::string section = isMiniMode ? "mini" : "micro"; const std::string section = isMiniMode ? "mini" : "micro";
std::string value = ult::parseValueFromIniSection(configIniPath, section, "invert_battery_display"); std::string value = ult::parseValueFromIniSection(configIniPath, section, "invert_battery_display");

View File

@@ -26,6 +26,11 @@ private:
char BatteryDraw_c[64] = ""; char BatteryDraw_c[64] = "";
char FPS_var_compressed_c[64] = ""; char FPS_var_compressed_c[64] = "";
char RAM_load_c[64] = ""; char RAM_load_c[64] = "";
char RAM_load2_c[64] = "";
char RAM_bw_peak_c[16] = "";
char RAM_bw_total_c[16] = "";
char RAM_bw_gpu_c[16] = "";
char RAM_bw_cpu_c[16] = "";
char Resolutions_c[64] = ""; char Resolutions_c[64] = "";
char readSpeed_c[32] = ""; char readSpeed_c[32] = "";
@@ -120,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) {
@@ -168,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) {
@@ -176,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));
@@ -208,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) {
@@ -216,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));
@@ -237,17 +242,40 @@ public:
renderer->drawString(DeltaRAM_c, false, COMMON_MARGIN + deltaOffset, height_offset, 15, (settings.textColor)); renderer->drawString(DeltaRAM_c, false, COMMON_MARGIN + deltaOffset, height_offset, 15, (settings.textColor));
} }
if (R_SUCCEEDED(hocclkCheck)) { if (R_SUCCEEDED(hocclkCheck)) {
static std::vector<std::string> partLoadColoredChars = {"CPU", "GPU"}; if (settings.ramInfoMode == "Bandwidth") {
//static auto loadLabelWidth = renderer->getTextDimensions("Load: ", false, 15).first; // Fixed column layout: labels at fixed x, values at fixed x after max label width
renderer->drawString("Load", false, COMMON_MARGIN, height_offset+15, 15, (settings.catColor2)); // Col1: Peak/GPU labels, Col2: Total/CPU labels
renderer->drawStringWithColoredSections(RAM_load_c, false, partLoadColoredChars, COMMON_MARGIN + valueOffset, height_offset+15, 15, (settings.textColor), settings.catColor2); // Values start at a fixed offset so columns don't shift with different digit counts
static const uint32_t bwLbl1W = renderer->getTextDimensions("Peak ", false, 15).first;
static const uint32_t bwLbl2W = renderer->getTextDimensions("Total ", false, 15).first;
static const uint32_t bwValW = renderer->getTextDimensions("99.9 GB/s", false, 15).first;
static const uint32_t bwGap = renderer->getTextDimensions(" ", false, 15).first;
const uint32_t xV1 = COMMON_MARGIN + bwLbl1W;
const uint32_t xL2 = xV1 + bwValW + bwGap;
const uint32_t xV2 = xL2 + bwLbl2W;
// Row 1: Peak ... Total
renderer->drawString("Peak", false, COMMON_MARGIN, height_offset+15, 15, settings.catColor2);
renderer->drawString(RAM_bw_peak_c, false, xV1, height_offset+15, 15, settings.textColor);
renderer->drawString("Total", false, xL2, height_offset+15, 15, settings.catColor2);
renderer->drawString(RAM_bw_total_c, false, xV2, height_offset+15, 15, settings.textColor);
// Row 2: GPU ... CPU
renderer->drawString("GPU", false, COMMON_MARGIN, height_offset+30, 15, settings.catColor2);
renderer->drawString(RAM_bw_gpu_c, false, xV1, height_offset+30, 15, settings.textColor);
renderer->drawString("CPU", false, xL2, height_offset+30, 15, settings.catColor2);
renderer->drawString(RAM_bw_cpu_c, false, xV2, height_offset+30, 15, settings.textColor);
} else {
static std::vector<std::string> partLoadColoredChars = {"CPU", "GPU"};
renderer->drawString("Load", false, COMMON_MARGIN, height_offset+15, 15, (settings.catColor2));
renderer->drawStringWithColoredSections(RAM_load_c, false, partLoadColoredChars, COMMON_MARGIN + valueOffset, height_offset+15, 15, (settings.textColor), settings.catColor2);
}
} }
} }
if (R_SUCCEEDED(Hinted)) { if (R_SUCCEEDED(Hinted)) {
const uint32_t ramUsageOffset = (R_SUCCEEDED(hocclkCheck) && settings.ramInfoMode == "Bandwidth") ? height_offset + 50 : height_offset + 40;
//static auto textWidth = renderer->getTextDimensions("Total \nApplication \nApplet \nSystem \nSystem Unsafe ", false, 15).first; //static auto textWidth = renderer->getTextDimensions("Total \nApplication \nApplet \nSystem \nSystem Unsafe ", false, 15).first;
renderer->drawString("Total\nApplication\nApplet\nSystem\nSystem Unsafe", false, COMMON_MARGIN, height_offset + 40, 15, (settings.catColor2)); renderer->drawString("Total\nApplication\nApplet\nSystem\nSystem Unsafe", false, COMMON_MARGIN, ramUsageOffset, 15, (settings.catColor2));
renderer->drawString(RAM_var_compressed_c, false, COMMON_MARGIN + valueOffset, height_offset + 40, 15, (settings.textColor)); renderer->drawString(RAM_var_compressed_c, false, COMMON_MARGIN + valueOffset, ramUsageOffset, 15, (settings.textColor));
renderer->drawString(RAM_percentage_var_compressed_c, false, ramPercentageOffset, height_offset + 40, 15, (settings.textColor)); renderer->drawString(RAM_percentage_var_compressed_c, false, ramPercentageOffset, ramUsageOffset, 15, (settings.textColor));
} }
} }
@@ -484,12 +512,27 @@ public:
); );
if (R_SUCCEEDED(hocclkCheck)) { if (R_SUCCEEDED(hocclkCheck)) {
const int RAM_GPU_Load = partLoad[HocClkPartLoad_EMC] - partLoad[HocClkPartLoad_EMCCpu]; if (settings.ramInfoMode == "Bandwidth") {
snprintf(RAM_load_c, sizeof RAM_load_c, const unsigned bwAll = partLoad[HocClkPartLoad_RamBWAll] / 1000;
"%u.%u%% CPU %u.%u%% GPU %u.%u%%", const unsigned bwAllD = (partLoad[HocClkPartLoad_RamBWAll] % 1000) / 100;
partLoad[HocClkPartLoad_EMC] / 10, partLoad[HocClkPartLoad_EMC] % 10, const unsigned bwPeak = partLoad[HocClkPartLoad_RamBWPeak] / 1000;
partLoad[HocClkPartLoad_EMCCpu] / 10, partLoad[HocClkPartLoad_EMCCpu] % 10, const unsigned bwPeakD= (partLoad[HocClkPartLoad_RamBWPeak]% 1000) / 100;
RAM_GPU_Load / 10, RAM_GPU_Load % 10); const unsigned bwCpu = partLoad[HocClkPartLoad_RamBWCpu] / 1000;
const unsigned bwCpuD = (partLoad[HocClkPartLoad_RamBWCpu] % 1000) / 100;
const unsigned bwGpu = partLoad[HocClkPartLoad_RamBWGpu] / 1000;
const unsigned bwGpuD = (partLoad[HocClkPartLoad_RamBWGpu] % 1000) / 100;
snprintf(RAM_bw_peak_c, sizeof RAM_bw_peak_c, "%u.%u GB/s", bwPeak, bwPeakD);
snprintf(RAM_bw_total_c, sizeof RAM_bw_total_c, "%u.%u GB/s", bwAll, bwAllD);
snprintf(RAM_bw_gpu_c, sizeof RAM_bw_gpu_c, "%u.%u GB/s", bwGpu, bwGpuD);
snprintf(RAM_bw_cpu_c, sizeof RAM_bw_cpu_c, "%u.%u GB/s", bwCpu, bwCpuD);
} else {
const int RAM_GPU_Load = partLoad[HocClkPartLoad_EMC] - partLoad[HocClkPartLoad_EMCCpu];
snprintf(RAM_load_c, sizeof RAM_load_c,
"%u.%u%% CPU %u.%u%% GPU %u.%u%%",
partLoad[HocClkPartLoad_EMC] / 10, partLoad[HocClkPartLoad_EMC] % 10,
partLoad[HocClkPartLoad_EMCCpu] / 10, partLoad[HocClkPartLoad_EMCCpu] % 10,
RAM_GPU_Load / 10, RAM_GPU_Load % 10);
}
} }
///Thermal ///Thermal
snprintf(SOC_temperature_c, sizeof SOC_temperature_c, "%.1f\u00B0C", SOC_temperatureF); snprintf(SOC_temperature_c, sizeof SOC_temperature_c, "%.1f\u00B0C", SOC_temperatureF);

View File

@@ -955,6 +955,11 @@ public:
const float RAM_Total_all_f = (RAM_Total_application_u + RAM_Total_applet_u + RAM_Total_system_u + RAM_Total_systemunsafe_u) / (1024.0f * 1024.0f * 1024.0f); const float RAM_Total_all_f = (RAM_Total_application_u + RAM_Total_applet_u + RAM_Total_system_u + RAM_Total_systemunsafe_u) / (1024.0f * 1024.0f * 1024.0f);
const float RAM_Used_all_f = (RAM_Used_application_u + RAM_Used_applet_u + RAM_Used_system_u + RAM_Used_systemunsafe_u) / (1024.0f * 1024.0f * 1024.0f); const float RAM_Used_all_f = (RAM_Used_application_u + RAM_Used_applet_u + RAM_Used_system_u + RAM_Used_systemunsafe_u) / (1024.0f * 1024.0f * 1024.0f);
snprintf(MICRO_RAM_all_c, sizeof(MICRO_RAM_all_c), "%.0f%.0fGB", RAM_Used_all_f, RAM_Total_all_f); snprintf(MICRO_RAM_all_c, sizeof(MICRO_RAM_all_c), "%.0f%.0fGB", RAM_Used_all_f, RAM_Total_all_f);
} else if (settings.ramInfoMode == "Bandwidth" && R_SUCCEEDED(hocclkCheck)) {
// Bandwidth mode: show GB/s from context (partLoad values are in MB/s)
const unsigned bwAll = partLoad[HocClkPartLoad_RamBWAll] / 1000;
const unsigned bwAllD = (partLoad[HocClkPartLoad_RamBWAll] % 1000) / 100;
snprintf(MICRO_RAM_all_c, sizeof(MICRO_RAM_all_c), "%u.%uGB/s", bwAll, bwAllD);
} else { } else {
// User wants percentage display // User wants percentage display
if (R_SUCCEEDED(hocclkCheck)) { if (R_SUCCEEDED(hocclkCheck)) {

View File

@@ -39,6 +39,10 @@ private:
std::atomic<bool> touchPollRunning{false}; std::atomic<bool> touchPollRunning{false};
public: public:
MiniOverlay() { MiniOverlay() {
CPU_temp_c[0] = '\0';
GPU_temp_c[0] = '\0';
RAM_temp_c[0] = '\0';
tsl::hlp::requestForeground(false); tsl::hlp::requestForeground(false);
disableJumpTo = true; disableJumpTo = true;
//tsl::initializeUltrahandSettings(); //tsl::initializeUltrahandSettings();
@@ -358,8 +362,32 @@ public:
width = renderer->getTextDimensions("100%@4444.4444 mV", false, fontsize).first; width = renderer->getTextDimensions("100%@4444.4444 mV", false, fontsize).first;
} }
if (settings.realTemps) { if (settings.realTemps) {
width += renderer->getTextDimensions(" 888.8°C", false, fontsize).first; width += renderer->getTextDimensions(" 88.8°C ", false, fontsize).first;
} }
} else if (key == "RAM" && settings.ramInfoMode == "Bandwidth" && R_SUCCEEDED(hocclkCheck)) {
width = renderer->getTextDimensions("99.9GB/s@4444.4", false, fontsize).first;
if (settings.realVolts) {
if (isMariko) {
if (settings.showVDD2 && settings.decimalVDD2 && settings.showVDDQ)
width += renderer->getTextDimensions("4444.4444 mV 4444 mV", false, fontsize).first;
else if (settings.showVDD2 && !settings.decimalVDD2 && settings.showVDDQ)
width += renderer->getTextDimensions("4444 mV 4444 mV", false, fontsize).first;
else if (settings.showVDD2 && settings.decimalVDD2)
width += renderer->getTextDimensions("4444.4 mV", false, fontsize).first;
else if (settings.showVDD2 && !settings.decimalVDD2)
width += renderer->getTextDimensions("4444 mV", false, fontsize).first;
else if (settings.showVDDQ)
width += renderer->getTextDimensions("4444 mV", false, fontsize).first;
} else {
if (settings.decimalVDD2)
width += renderer->getTextDimensions("4444.44 mV", false, fontsize).first;
else
width += renderer->getTextDimensions("4444 mV", false, fontsize).first;
}
}
if (settings.realTemps) {
width += renderer->getTextDimensions(" 88.8°C ", false, fontsize).first;
}
} else if (key == "GPU" || (key == "RAM" && settings.showpartLoad && R_SUCCEEDED(hocclkCheck))) { } else if (key == "GPU" || (key == "RAM" && settings.showpartLoad && R_SUCCEEDED(hocclkCheck))) {
//dimensions = renderer->drawString("100.0%@4444.4", false, 0, 0, fontsize, renderer->a(0x0000)); //dimensions = renderer->drawString("100.0%@4444.4", false, 0, 0, fontsize, renderer->a(0x0000));
@@ -376,15 +404,15 @@ public:
width = renderer->getTextDimensions("100%[100%,100%]@4444.4444 mV", false, fontsize).first; width = renderer->getTextDimensions("100%[100%,100%]@4444.4444 mV", false, fontsize).first;
} }
} }
if (key == "GPU" && settings.realTemps) { if (settings.realTemps) {
width += renderer->getTextDimensions(" 88.8°C", false, fontsize).first; width += renderer->getTextDimensions(" 88.8°C ", false, fontsize).first;
} }
} else if (key == "RAM" && (!settings.showpartLoad || R_FAILED(hocclkCheck))) { } else if (key == "RAM" && (!settings.showpartLoad || R_FAILED(hocclkCheck))) {
//dimensions = renderer->drawString("44444444MB@4444.4", false, 0, 0, fontsize, renderer->a(0x0000)); //dimensions = renderer->drawString("44444444MB@4444.4", false, 0, 0, fontsize, renderer->a(0x0000));
if (!settings.realVolts) { if (!settings.realVolts) {
width = renderer->getTextDimensions("100%@4444.4", false, fontsize).first; width = renderer->getTextDimensions("100%@4444.4", false, fontsize).first;
if (settings.realTemps) { if (settings.realTemps) {
width += renderer->getTextDimensions(" 88.8°C", false, fontsize).first; width += renderer->getTextDimensions(" 88.8°C ", false, fontsize).first;
} }
} else { } else {
if (isMariko) { if (isMariko) {
@@ -1070,7 +1098,7 @@ public:
} }
} }
if (settings.realTemps && realCPU_Temp != 0) { if (settings.realTemps && realCPU_Temp != 0 && CPU_temp_c[0] != '\0') {
char temp_buffer[48]; char temp_buffer[48];
snprintf(temp_buffer, sizeof(temp_buffer), " %s", CPU_temp_c); snprintf(temp_buffer, sizeof(temp_buffer), " %s", CPU_temp_c);
strncat(MINI_CPU_compressed_c, temp_buffer, sizeof(MINI_CPU_compressed_c) - strlen(MINI_CPU_compressed_c) - 1); strncat(MINI_CPU_compressed_c, temp_buffer, sizeof(MINI_CPU_compressed_c) - strlen(MINI_CPU_compressed_c) - 1);
@@ -1110,11 +1138,11 @@ public:
} }
} }
if (settings.realTemps && realGPU_Temp != 0) { if (settings.realTemps && realGPU_Temp != 0 && GPU_temp_c[0] != '\0') {
char temp_buffer[48]; char temp_buffer[48];
snprintf(temp_buffer, sizeof(temp_buffer), " %s", GPU_temp_c); snprintf(temp_buffer, sizeof(temp_buffer), " %s", GPU_temp_c);
strncat(MINI_GPU_Load_c, temp_buffer, sizeof(MINI_GPU_Load_c) - strlen(MINI_GPU_Load_c) - 1); strncat(MINI_GPU_Load_c, temp_buffer, sizeof(MINI_GPU_Load_c) - strlen(MINI_GPU_Load_c) - 1);
} }
// Only process RAM if needed // Only process RAM if needed
if (isActive("RAM")) { if (isActive("RAM")) {
@@ -1138,53 +1166,64 @@ public:
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10); RAM_Hz / 1000000, (RAM_Hz / 100000) % 10);
} }
} else { } else {
unsigned partLoadInt; if (settings.ramInfoMode == "Bandwidth" && R_SUCCEEDED(hocclkCheck)) {
// Bandwidth mode: show GB/s from context (partLoad values are in MB/s)
if (R_SUCCEEDED(hocclkCheck)) { const uint32_t ramFreq = settings.realFrequencies && realRAM_Hz ? realRAM_Hz : RAM_Hz;
partLoadInt = partLoad[HocClkPartLoad_EMC] / 10; const unsigned bwAll = partLoad[HocClkPartLoad_RamBWAll] / 1000;
const unsigned bwAllD = (partLoad[HocClkPartLoad_RamBWAll] % 1000) / 100;
if (settings.showpartLoadCPUGPU) { snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
unsigned ramCpuLoadInt = partLoad[HocClkPartLoad_EMCCpu] / 10; "%u.%uGB/s@%hu.%hhu",
int RAM_GPU_Load = partLoad[HocClkPartLoad_EMC] - partLoad[HocClkPartLoad_EMCCpu]; bwAll, bwAllD,
unsigned ramGpuLoadInt = RAM_GPU_Load / 10; ramFreq / 1000000, (ramFreq / 100000) % 10);
if (settings.realFrequencies && realRAM_Hz) {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%[%u%%,%u%%]@%hu.%hhu",
partLoadInt, ramCpuLoadInt, ramGpuLoadInt,
realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10);
} else {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%[%u%%,%u%%]@%hu.%hhu",
partLoadInt, ramCpuLoadInt, ramGpuLoadInt,
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10);
}
} else {
if (settings.realFrequencies && realRAM_Hz) {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", partLoadInt,
realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10);
} else {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", partLoadInt,
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10);
}
}
} else { } else {
const uint64_t RAM_Total_all = RAM_Total_application_u + RAM_Total_applet_u + unsigned partLoadInt;
RAM_Total_system_u + RAM_Total_systemunsafe_u;
const uint64_t RAM_Used_all = RAM_Used_application_u + RAM_Used_applet_u +
RAM_Used_system_u + RAM_Used_systemunsafe_u;
partLoadInt = (RAM_Total_all > 0) ? (unsigned)((RAM_Used_all * 100) / RAM_Total_all) : 0;
if (settings.realFrequencies && realRAM_Hz) { if (R_SUCCEEDED(hocclkCheck)) {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), partLoadInt = partLoad[HocClkPartLoad_EMC] / 10;
"%u%%@%hu.%hhu", partLoadInt,
realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10); if (settings.showpartLoadCPUGPU) {
unsigned ramCpuLoadInt = partLoad[HocClkPartLoad_EMCCpu] / 10;
int RAM_GPU_Load = partLoad[HocClkPartLoad_EMC] - partLoad[HocClkPartLoad_EMCCpu];
unsigned ramGpuLoadInt = RAM_GPU_Load / 10;
if (settings.realFrequencies && realRAM_Hz) {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%[%u%%,%u%%]@%hu.%hhu",
partLoadInt, ramCpuLoadInt, ramGpuLoadInt,
realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10);
} else {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%[%u%%,%u%%]@%hu.%hhu",
partLoadInt, ramCpuLoadInt, ramGpuLoadInt,
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10);
}
} else {
if (settings.realFrequencies && realRAM_Hz) {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", partLoadInt,
realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10);
} else {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", partLoadInt,
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10);
}
}
} else { } else {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), const uint64_t RAM_Total_all = RAM_Total_application_u + RAM_Total_applet_u +
"%u%%@%hu.%hhu", partLoadInt, RAM_Total_system_u + RAM_Total_systemunsafe_u;
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10); const uint64_t RAM_Used_all = RAM_Used_application_u + RAM_Used_applet_u +
RAM_Used_system_u + RAM_Used_systemunsafe_u;
partLoadInt = (RAM_Total_all > 0) ? (unsigned)((RAM_Used_all * 100) / RAM_Total_all) : 0;
if (settings.realFrequencies && realRAM_Hz) {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", partLoadInt,
realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10);
} else {
snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c),
"%u%%@%hu.%hhu", partLoadInt,
RAM_Hz / 1000000, (RAM_Hz / 100000) % 10);
}
} }
} }
} }
@@ -1218,11 +1257,12 @@ public:
} }
} }
} }
if (settings.realTemps && realRAM_Temp != 0) {
char temp_buffer[48]; if (settings.realTemps && realRAM_Temp != 0 && RAM_temp_c[0] != '\0') {
snprintf(temp_buffer, sizeof(temp_buffer), " %s", RAM_temp_c); char temp_buffer[48];
strncat(MINI_RAM_var_compressed_c, temp_buffer, sizeof(MINI_RAM_var_compressed_c) - strlen(MINI_RAM_var_compressed_c) - 1); snprintf(temp_buffer, sizeof(temp_buffer), " %s", RAM_temp_c);
} strncat(MINI_RAM_var_compressed_c, temp_buffer, sizeof(MINI_RAM_var_compressed_c) - strlen(MINI_RAM_var_compressed_c) - 1);
}
// Only process MEM if needed // Only process MEM if needed
if (isActive("MEM")) { if (isActive("MEM")) {

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

@@ -0,0 +1,81 @@
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/base_rules
################################################################################
IPL_LOAD_ADDR := 0x40010000
################################################################################
THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE)))
BUILDDIR := build
OUTPUTDIR := out
SOURCEDIR = fatal_handler
BDKDIR := bdk
GFXDIR := fatal_handler/gfx
TARGET := fatal_handler
BDKINC := -I$(BDKDIR)
GFXINC := -I$(GFXDIR)
GFX_INC := '"gfx.h"'
VPATH = $(dir ./$(SOURCEDIR)/) $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
VPATH += $(dir $(wildcard ./$(BDKDIR)/)) $(dir $(wildcard ./$(BDKDIR)/*/)) $(dir $(wildcard ./$(BDKDIR)/*/*/))
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
start.o exception_handlers.o irq.o main.o \
timer.o heap.o hw_init.o clock.o i2c.o gpio.o \
max7762x.o di.o util.o fuse.o pinmux.o \
secmon_exo.o gfx.o bpmp.o sdram.o minerva.o btn.o max77620-rtc.o se.o mc.o)
################################################################################
# BDK defines.
CUSTOMDEFINES := -DGFX_INC=$(GFX_INC)
CUSTOMDEFINES += -DBDK_MALLOC_NO_DEFRAG -DBDK_MC_ENABLE_AHB_REDIRECT -DBDK_EMUMMC_ENABLE
CUSTOMDEFINES += -DBDK_WATCHDOG_FIQ_ENABLE -DBDK_RESTART_BL_ON_WDT
INCDIRS := $(BDKINC) $(GFXINC)
WARNINGS := -Wall -Wsign-compare -Wno-array-bounds -Wno-stringop-overflow
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
################################################################################
BIN_TARGET := $(OUTPUTDIR)/$(TARGET).bin
BIN_OBJ := $(OUTPUTDIR)/$(TARGET).bin.o
BIN_HEADER := $(OUTPUTDIR)/$(TARGET)_bin.h
BIN_SYM := $(subst .,_,$(subst /,_,$(TARGET)))_bin
define bin2o
$(eval SYM := $(BIN_SYM))
$(eval BIN_SIZE := $(shell wc -c < $(BIN_TARGET)))
@$(OBJCOPY) --input-target binary --output-target elf32-littlearm --binary-architecture arm \
--redefine-sym _binary_$(shell echo $(BIN_TARGET) | tr '/.-' '___')_start=$(SYM) \
--redefine-sym _binary_$(shell echo $(BIN_TARGET) | tr '/.-' '___')_end=$(SYM)_end \
--redefine-sym _binary_$(shell echo $(BIN_TARGET) | tr '/.-' '___')_size=$(SYM)_size \
$(BIN_TARGET) $(BIN_OBJ)
@printf '#pragma once\n#include <stddef.h>\n#include <stdint.h>\nextern const uint8_t $(SYM)[];\nextern const uint8_t $(SYM)_end[];\n#if __cplusplus >= 201103L\nstatic constexpr size_t $(SYM)_size=$(BIN_SIZE);\n#else\nstatic const size_t $(SYM)_size=$(BIN_SIZE);\n#endif\n' > $(BIN_HEADER)
endef
################################################################################
.PHONY: all clean
all: $(BIN_OBJ) $(BIN_HEADER)
$(BIN_OBJ) $(BIN_HEADER): $(BIN_TARGET)
$(bin2o)
$(BIN_TARGET): $(BUILDDIR)/$(TARGET)/$(TARGET).elf
$(OBJCOPY) -S -O binary $< $(BIN_TARGET)
clean:
@rm -rf $(OBJS) $(BIN_OBJ) $(BIN_HEADER)
$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
@$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
$(BUILDDIR)/$(TARGET)/%.o: %.c
@$(CC) $(CFLAGS) $(INCDIRS) -c $< -o $@
$(BUILDDIR)/$(TARGET)/%.o: %.S
@$(CC) $(CFLAGS) -c $< -o $@
$(OBJS): $(BUILDDIR)/$(TARGET)
$(BUILDDIR)/$(TARGET):
@mkdir -p "$(BUILDDIR)"
@mkdir -p "$(BUILDDIR)/$(TARGET)"
@mkdir -p "$(OUTPUTDIR)"

View File

@@ -0,0 +1,558 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer
*
* 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 <stdarg.h>
#include <string.h>
#include "gfx.h"
// Global gfx console and context.
gfx_ctxt_t gfx_ctxt;
gfx_con_t gfx_con;
static bool gfx_con_init_done = false;
static const u8 _gfx_font[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 032 ( )
0x00, 0x30, 0x30, 0x18, 0x18, 0x00, 0x0C, 0x00, // Char 033 (!)
0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, // Char 034 (")
0x00, 0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66, // Char 035 (#)
0x00, 0x18, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x18, // Char 036 ($)
0x00, 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, // Char 037 (%)
0x00, 0x3C, 0x66, 0x3C, 0x1C, 0xE6, 0x66, 0xFC, // Char 038 (&)
0x00, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, // Char 039 (')
0x00, 0x30, 0x18, 0x0C, 0x0C, 0x18, 0x30, 0x00, // Char 040 (()
0x00, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x00, // Char 041 ())
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, // Char 042 (*)
0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, // Char 043 (+)
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C, 0x00, // Char 044 (,)
0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, // Char 045 (-)
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, // Char 046 (.)
0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, // Char 047 (/)
0x00, 0x3C, 0x66, 0x76, 0x6E, 0x66, 0x3C, 0x00, // Char 048 (0)
0x00, 0x18, 0x1C, 0x18, 0x18, 0x18, 0x7E, 0x00, // Char 049 (1)
0x00, 0x3C, 0x62, 0x30, 0x0C, 0x06, 0x7E, 0x00, // Char 050 (2)
0x00, 0x3C, 0x62, 0x38, 0x60, 0x66, 0x3C, 0x00, // Char 051 (3)
0x00, 0x6C, 0x6C, 0x66, 0xFE, 0x60, 0x60, 0x00, // Char 052 (4)
0x00, 0x7E, 0x06, 0x7E, 0x60, 0x66, 0x3C, 0x00, // Char 053 (5)
0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00, // Char 054 (6)
0x00, 0x7E, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00, // Char 055 (7)
0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, // Char 056 (8)
0x00, 0x3C, 0x66, 0x7C, 0x60, 0x66, 0x3C, 0x00, // Char 057 (9)
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, // Char 058 (:)
0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x00, // Char 059 (;)
0x00, 0x70, 0x1C, 0x06, 0x06, 0x1C, 0x70, 0x00, // Char 060 (<)
0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00, // Char 061 (=)
0x00, 0x0E, 0x38, 0x60, 0x60, 0x38, 0x0E, 0x00, // Char 062 (>)
0x00, 0x3C, 0x66, 0x30, 0x18, 0x00, 0x18, 0x00, // Char 063 (?)
0x00, 0x3C, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3C, // Char 064 (@)
0x00, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, // Char 065 (A)
0x00, 0x3E, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00, // Char 066 (B)
0x00, 0x3C, 0x66, 0x06, 0x06, 0x66, 0x3C, 0x00, // Char 067 (C)
0x00, 0x1E, 0x36, 0x66, 0x66, 0x36, 0x1E, 0x00, // Char 068 (D)
0x00, 0x7E, 0x06, 0x1E, 0x06, 0x06, 0x7E, 0x00, // Char 069 (E)
0x00, 0x3E, 0x06, 0x1E, 0x06, 0x06, 0x06, 0x00, // Char 070 (F)
0x00, 0x3C, 0x66, 0x06, 0x76, 0x66, 0x3C, 0x00, // Char 071 (G)
0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, // Char 072 (H)
0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 073 (I)
0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, // Char 074 (J)
0x00, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x00, // Char 075 (K)
0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00, // Char 076 (L)
0x00, 0x46, 0x6E, 0x7E, 0x56, 0x46, 0x46, 0x00, // Char 077 (M)
0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00, // Char 078 (N)
0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 079 (O)
0x00, 0x3E, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00, // Char 080 (P)
0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x70, 0x00, // Char 081 (Q)
0x00, 0x3E, 0x66, 0x3E, 0x1E, 0x36, 0x66, 0x00, // Char 082 (R)
0x00, 0x3C, 0x66, 0x0C, 0x30, 0x66, 0x3C, 0x00, // Char 083 (S)
0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, // Char 084 (T)
0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 085 (U)
0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, // Char 086 (V)
0x00, 0x46, 0x46, 0x56, 0x7E, 0x6E, 0x46, 0x00, // Char 087 (W)
0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, // Char 088 (X)
0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, // Char 089 (Y)
0x00, 0x7E, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00, // Char 090 (Z)
0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, // Char 091 ([)
0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, // Char 092 (\)
0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, // Char 093 (])
0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, // Char 094 (^)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, // Char 095 (_)
0x00, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, // Char 096 (`)
0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00, // Char 097 (a)
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00, // Char 098 (b)
0x00, 0x00, 0x3C, 0x06, 0x06, 0x06, 0x3C, 0x00, // Char 099 (c)
0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, // Char 100 (d)
0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00, // Char 101 (e)
0x00, 0x38, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00, // Char 102 (f)
0x00, 0x00, 0x7C, 0x66, 0x7C, 0x40, 0x3C, 0x00, // Char 103 (g)
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x00, // Char 104 (h)
0x00, 0x18, 0x00, 0x1C, 0x18, 0x18, 0x3C, 0x00, // Char 105 (i)
0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1E, 0x00, // Char 106 (j)
0x00, 0x06, 0x06, 0x36, 0x1E, 0x36, 0x66, 0x00, // Char 107 (k)
0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 108 (l)
0x00, 0x00, 0x66, 0xFE, 0xFE, 0xD6, 0xC6, 0x00, // Char 109 (m)
0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00, // Char 110 (n)
0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, // Char 111 (o)
0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x00, // Char 112 (p)
0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00, // Char 113 (q)
0x00, 0x00, 0x3E, 0x66, 0x06, 0x06, 0x06, 0x00, // Char 114 (r)
0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00, // Char 115 (s)
0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x70, 0x00, // Char 116 (t)
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00, // Char 117 (u)
0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, // Char 118 (v)
0x00, 0x00, 0xC6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00, // Char 119 (w)
0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, // Char 120 (x)
0x00, 0x00, 0x66, 0x66, 0x7C, 0x60, 0x3C, 0x00, // Char 121 (y)
0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00, // Char 122 (z)
0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08, 0x18, // Char 123 ({)
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // Char 124 (|)
0x00, 0x0C, 0x08, 0x08, 0x10, 0x08, 0x08, 0x0C, // Char 125 (})
0x00, 0x00, 0x00, 0x4C, 0x32, 0x00, 0x00, 0x00 // Char 126 (~)
};
void gfx_clear_grey(u8 color)
{
memset(gfx_ctxt.fb, color, gfx_ctxt.width * gfx_ctxt.height * 4);
}
void gfx_clear_partial_grey(u8 color, u32 pos_x, u32 height)
{
memset(gfx_ctxt.fb + pos_x * gfx_ctxt.stride, color, height * 4 * gfx_ctxt.stride);
}
void gfx_clear_color(u32 color)
{
for (u32 i = 0; i < gfx_ctxt.width * gfx_ctxt.height; i++)
gfx_ctxt.fb[i] = color;
}
void gfx_init_ctxt(u32 *fb, u32 width, u32 height, u32 stride)
{
gfx_ctxt.fb = fb;
gfx_ctxt.width = width;
gfx_ctxt.height = height;
gfx_ctxt.stride = stride;
}
void gfx_con_init()
{
gfx_con.gfx_ctxt = &gfx_ctxt;
gfx_con.fntsz = 16;
gfx_con.x = 0;
gfx_con.y = 0;
gfx_con.savedx = 0;
gfx_con.savedy = 0;
gfx_con.fgcol = TXT_CLR_DEFAULT;
gfx_con.fillbg = 1;
gfx_con.bgcol = TXT_CLR_BG;
gfx_con.mute = 0;
gfx_con_init_done = true;
}
void gfx_con_setcol(u32 fgcol, int fillbg, u32 bgcol)
{
gfx_con.fgcol = fgcol;
gfx_con.fillbg = fillbg;
gfx_con.bgcol = bgcol;
}
void gfx_con_getpos(u32 *x, u32 *y)
{
*x = gfx_con.x;
*y = gfx_con.y;
}
void gfx_con_setpos(u32 x, u32 y)
{
gfx_con.x = x;
gfx_con.y = y;
}
void gfx_putc(char c)
{
// Duplicate code for performance reasons.
switch (gfx_con.fntsz)
{
case 16:
if (c >= 32 && c <= 126)
{
u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];
u32 *fb = gfx_ctxt.fb + gfx_con.x + gfx_con.y * gfx_ctxt.stride;
for (u32 i = 0; i < 16; i += 2)
{
u8 v = *cbuf;
for (u32 k = 0; k < 2; k++)
{
for (u32 j = 0; j < 8; j++)
{
if (v & 1)
{
*fb = gfx_con.fgcol;
fb++;
*fb = gfx_con.fgcol;
}
else if (gfx_con.fillbg)
{
*fb = gfx_con.bgcol;
fb++;
*fb = gfx_con.bgcol;
}
else
fb++;
v >>= 1;
fb++;
}
fb += gfx_ctxt.stride - 16;
v = *cbuf;
}
cbuf++;
}
gfx_con.x += 16;
}
else if (c == '\n')
{
gfx_con.x = 0;
gfx_con.y += 16;
if (gfx_con.y > gfx_ctxt.height - 16)
gfx_con.y = 0;
}
break;
case 8:
default:
if (c >= 32 && c <= 126)
{
u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];
u32 *fb = gfx_ctxt.fb + gfx_con.x + gfx_con.y * gfx_ctxt.stride;
for (u32 i = 0; i < 8; i++)
{
u8 v = *cbuf++;
for (u32 j = 0; j < 8; j++)
{
if (v & 1)
*fb = gfx_con.fgcol;
else if (gfx_con.fillbg)
*fb = gfx_con.bgcol;
v >>= 1;
fb++;
}
fb += gfx_ctxt.stride - 8;
}
gfx_con.x += 8;
}
else if (c == '\n')
{
gfx_con.x = 0;
gfx_con.y += 8;
if (gfx_con.y > gfx_ctxt.height - 8)
gfx_con.y = 0;
}
break;
}
}
void gfx_puts(const char *s)
{
if (!s || !gfx_con_init_done || gfx_con.mute)
return;
for (; *s; s++)
gfx_putc(*s);
}
static void _gfx_putn(u32 v, int base, char fill, int fcnt)
{
static const char digits[] = "0123456789ABCDEF";
char *p;
char buf[65];
int c = fcnt;
bool negative = false;
if (base != 10 && base != 16)
return;
// Account for negative numbers.
if (base == 10 && v & 0x80000000)
{
negative = true;
v = (int)v * -1;
c--;
}
p = buf + 64;
*p = 0;
do
{
c--;
*--p = digits[v % base];
v /= base;
} while (v);
if (negative)
*--p = '-';
if (fill != 0)
{
while (c > 0 && p > buf)
{
*--p = fill;
c--;
}
}
gfx_puts(p);
}
void gfx_put_small_sep()
{
u8 prevFontSize = gfx_con.fntsz;
gfx_con.fntsz = 8;
gfx_putc('\n');
gfx_con.fntsz = prevFontSize;
}
void gfx_put_big_sep()
{
u8 prevFontSize = gfx_con.fntsz;
gfx_con.fntsz = 16;
gfx_putc('\n');
gfx_con.fntsz = prevFontSize;
}
void gfx_printf(const char *fmt, ...)
{
if (!gfx_con_init_done || gfx_con.mute)
return;
va_list ap;
int fill, fcnt;
va_start(ap, fmt);
while (*fmt)
{
if (*fmt == '%')
{
fmt++;
fill = 0;
fcnt = 0;
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
{
fcnt = *fmt;
fmt++;
if (*fmt >= '0' && *fmt <= '9')
{
fill = fcnt;
fcnt = *fmt - '0';
fmt++;
}
else
{
fill = ' ';
fcnt -= '0';
}
}
switch(*fmt)
{
case 'c':
gfx_putc(va_arg(ap, u32));
break;
case 's':
gfx_puts(va_arg(ap, char *));
break;
case 'd':
_gfx_putn(va_arg(ap, u32), 10, fill, fcnt);
break;
case 'p':
case 'P':
case 'x':
case 'X':
_gfx_putn(va_arg(ap, u32), 16, fill, fcnt);
break;
case 'k':
gfx_con.fgcol = va_arg(ap, u32);
break;
case 'K':
gfx_con.bgcol = va_arg(ap, u32);
gfx_con.fillbg = 1;
break;
case '%':
gfx_putc('%');
break;
case '\0':
goto out;
default:
gfx_putc('%');
gfx_putc(*fmt);
break;
}
}
else
gfx_putc(*fmt);
fmt++;
}
out:
va_end(ap);
}
static void _gfx_cputs(u32 color, const char *s)
{
gfx_con.fgcol = color;
gfx_puts(s);
gfx_putc('\n');
gfx_con.fgcol = TXT_CLR_DEFAULT;
}
void gfx_wputs(const char *s) { _gfx_cputs(TXT_CLR_WARNING, s); }
void gfx_eputs(const char *s) { _gfx_cputs(TXT_CLR_ERROR, s); }
void gfx_hexdump(u32 base, const void *buf, u32 len)
{
if (!gfx_con_init_done || gfx_con.mute)
return;
u8 *buff = (u8 *)buf;
u8 prevFontSize = gfx_con.fntsz;
gfx_con.fntsz = 8;
for (u32 i = 0; i < len; i++)
{
if (i % 0x10 == 0)
{
if (i != 0)
{
gfx_puts("| ");
for (u32 j = 0; j < 0x10; j++)
{
u8 c = buff[i - 0x10 + j];
if (c >= 32 && c <= 126)
gfx_putc(c);
else
gfx_putc('.');
}
gfx_putc('\n');
}
gfx_printf("%08x: ", base + i);
}
gfx_printf("%02x ", buff[i]);
if (i == len - 1)
{
int ln = len % 0x10 != 0;
u32 k = 0x10 - 1;
if (ln)
{
k = (len & 0xF) - 1;
for (u32 j = 0; j < 0x10 - k; j++)
gfx_puts(" ");
}
gfx_puts("| ");
for (u32 j = 0; j < (ln ? k : k + 1); j++)
{
u8 c = buff[i - k + j];
if (c >= 32 && c <= 126)
gfx_putc(c);
else
gfx_putc('.');
}
gfx_putc('\n');
}
}
gfx_putc('\n');
gfx_con.fntsz = prevFontSize;
}
static int abs(int x)
{
if (x < 0)
return -x;
return x;
}
void gfx_set_pixel(u32 x, u32 y, u32 color)
{
gfx_ctxt.fb[x + y * gfx_ctxt.stride] = color;
}
void gfx_line(int x0, int y0, int x1, int y1, u32 color)
{
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
int err = (dx > dy ? dx : -dy) / 2, e2;
while (1)
{
gfx_set_pixel(x0, y0, color);
if (x0 == x1 && y0 == y1)
break;
e2 = err;
if (e2 >-dx)
{
err -= dy;
x0 += sx;
}
if (e2 < dy)
{
err += dx;
y0 += sy;
}
}
}
void gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)
{
u32 pos = 0;
for (u32 y = pos_y; y < (pos_y + size_y); y++)
{
for (u32 x = pos_x; x < (pos_x + size_x); x++)
{
memset(&gfx_ctxt.fb[x + y*gfx_ctxt.stride], buf[pos], 4);
pos++;
}
}
}
void gfx_set_rect_rgb(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)
{
u32 pos = 0;
for (u32 y = pos_y; y < (pos_y + size_y); y++)
{
for (u32 x = pos_x; x < (pos_x + size_x); x++)
{
gfx_ctxt.fb[x + y * gfx_ctxt.stride] = buf[pos + 2] | (buf[pos + 1] << 8) | (buf[pos] << 16);
pos+=3;
}
}
}
void gfx_set_rect_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)
{
u32 *ptr = (u32 *)buf;
for (u32 y = pos_y; y < (pos_y + size_y); y++)
for (u32 x = pos_x; x < (pos_x + size_x); x++)
gfx_ctxt.fb[x + y * gfx_ctxt.stride] = *ptr++;
}
void gfx_render_bmp_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y)
{
for (u32 y = pos_y; y < (pos_y + size_y); y++)
{
for (u32 x = pos_x; x < (pos_x + size_x); x++)
gfx_ctxt.fb[x + y * gfx_ctxt.stride] = buf[(size_y + pos_y - 1 - y ) * size_x + x - pos_x];
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2018 M4xw
*
* 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 _GFX_H_
#define _GFX_H_
#include <bdk.h>
#define TXT_CLR_BG 0xFF1B1B1B // Dark Grey.
#define TXT_CLR_DEFAULT 0xFFCCCCCC // Light Grey.
#define TXT_CLR_WARNING 0xFFFFDD00 // Yellow.
#define TXT_CLR_ERROR 0xFFFF0000 // Red.
#define TXT_CLR_CYAN_L 0xFF00CCFF // Light Cyan.
#define TXT_CLR_TURQUOISE 0xFF00FFCC // Turquoise.
#define TXT_CLR_ORANGE 0xFFFFBA00 // Orange.
#define TXT_CLR_GREENISH 0xFF96FF00 // Toxic Green.
#define TXT_CLR_GREEN_D 0xFF008800 // Dark Green.
#define TXT_CLR_RED_D 0xFF880000 // Dark Red.
#define TXT_CLR_GREY_D 0xFF303030 // Darkest Grey.
#define TXT_CLR_GREY_DM 0xFF444444 // Darker Grey.
#define TXT_CLR_GREY_M 0xFF555555 // Dark Grey.
#define TXT_CLR_GREY 0xFF888888 // Grey.
#define EPRINTF(text) gfx_eputs(text)
#define EPRINTFARGS(text, args...) gfx_printf("%k"text"%k\n", TXT_CLR_ERROR, args, TXT_CLR_DEFAULT)
#define WPRINTF(text) gfx_wputs(text)
#define WPRINTFARGS(text, args...) gfx_printf("%k"text"%k\n", TXT_CLR_WARNING, args, TXT_CLR_DEFAULT)
typedef struct _gfx_ctxt_t
{
u32 *fb;
u32 width;
u32 height;
u32 stride;
} gfx_ctxt_t;
typedef struct _gfx_con_t
{
gfx_ctxt_t *gfx_ctxt;
u32 fntsz;
u32 x;
u32 y;
u32 savedx;
u32 savedy;
u32 fgcol;
int fillbg;
u32 bgcol;
bool mute;
} gfx_con_t;
// Global gfx console and context.
extern gfx_ctxt_t gfx_ctxt;
extern gfx_con_t gfx_con;
void gfx_init_ctxt(u32 *fb, u32 width, u32 height, u32 stride);
void gfx_clear_grey(u8 color);
void gfx_clear_partial_grey(u8 color, u32 pos_x, u32 height);
void gfx_clear_color(u32 color);
void gfx_con_init();
void gfx_con_setcol(u32 fgcol, int fillbg, u32 bgcol);
void gfx_con_getpos(u32 *x, u32 *y);
void gfx_con_setpos(u32 x, u32 y);
void gfx_putc(char c);
void gfx_puts(const char *s);
void gfx_wputs(const char *s);
void gfx_eputs(const char *s);
void gfx_printf(const char *fmt, ...) /* __attribute__((format(printf, 1, 2))) */;
void gfx_hexdump(u32 base, const void *buf, u32 len);
void gfx_set_pixel(u32 x, u32 y, u32 color);
void gfx_line(int x0, int y0, int x1, int y1, u32 color);
void gfx_put_small_sep();
void gfx_put_big_sep();
void gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
void gfx_set_rect_rgb(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
void gfx_set_rect_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
void gfx_render_bmp_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
#endif

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2019 Atmosphère-NX
*
* 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 <bdk.h>
#include "secmon_exo.h"
// Atmosphère reboot-to-fatal-error.
typedef struct _atm_fatal_error_ctx
{
u32 magic;
u32 error_desc;
u64 title_id;
union
{
u64 gprs[32];
struct
{
u64 _gprs[29];
u64 fp;
u64 lr;
u64 sp;
};
};
u64 pc;
u64 module_base;
u32 pstate;
u32 afsr0;
u32 afsr1;
u32 esr;
u64 far;
u64 report_identifier; // Normally just system tick.
u64 stack_trace_size;
u64 stack_dump_size;
u64 stack_trace[0x20];
u8 stack_dump[0x100];
u8 tls[0x100];
} atm_fatal_error_ctx;
#define ATM_FATAL_ERR_CTX_ADDR 0x4003E000
#define ATM_FATAL_MAGIC 0x30454641 // AFE0
#define HOS_PID_BOOT2 0x8
static const char *get_error_desc(u32 error_desc)
{
switch (error_desc)
{
case 0x100:
return "IABRT"; // Instruction Abort.
case 0x101:
return "DABRT"; // Data Abort.
case 0x102:
return "IUA"; // Instruction Unaligned Access.
case 0x103:
return "DUA"; // Data Unaligned Access.
case 0x104:
return "UDF"; // Undefined Instruction.
case 0x106:
return "SYS"; // System Error.
case 0x301:
return "SVC"; // Bad arguments or unimplemented SVC.
case 0xF00:
return "KRNL"; // Kernel panic.
case 0xFFD:
return "SO"; // Stack Overflow.
case 0xFFE:
return "std::abort";
default:
return "UNK";
}
}
void secmon_exo_check_panic()
{
volatile atm_fatal_error_ctx *rpt = (atm_fatal_error_ctx *)ATM_FATAL_ERR_CTX_ADDR;
// Mask magic to maintain compatibility with any AFE version, thanks to additive struct members.
if ((rpt->magic & 0xF0FFFFFF) != ATM_FATAL_MAGIC)
return;
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
WPRINTF("Panic occurred while running Atmosphere.\n\n");
WPRINTFARGS("Title ID: %08X%08X", (u32)((u64)rpt->title_id >> 32), (u32)rpt->title_id);
WPRINTFARGS("Error: %s (0x%x)\n", get_error_desc(rpt->error_desc), rpt->error_desc);
// Check if mixed atmosphere sysmodules.
if ((u32)rpt->title_id == HOS_PID_BOOT2)
WPRINTF("Mismatched Atmosphere files?\n");
// Change magic to invalid, to prevent double-display of error/bootlooping.
rpt->magic = 0;
display_backlight_brightness(100, 1000);
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) 2018-2021 CTCaer
*
* 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 _SECMON_EXO_H_
#define _SECMON_EXO_H_
#include <bdk.h>
void secmon_exo_check_panic();
#endif

View File

@@ -0,0 +1,25 @@
ENTRY(_start)
SECTIONS {
PROVIDE(__ipl_start = IPL_LOAD_ADDR);
. = __ipl_start;
.text : {
*(.text._start);
KEEP(*(._boot_cfg));
KEEP(*(._ipl_version));
*(.text._irq_setup);
*(.text*);
}
.data : {
*(.data*);
*(.rodata*);
}
. = ALIGN(0x10);
__ipl_end = .;
.bss : {
__bss_start = .;
*(COMMON)
*(.bss*)
__bss_end = .;
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) 2018 naehrwert
*
* Copyright (c) 2018-2024 CTCaer
*
* 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 <bdk.h>
#include "hos/secmon_exo.h"
typedef struct _log_ctx
{
u32 magic;
u32 sz;
u32 start;
u32 end;
char buf[];
} log_ctx_t;
#define IRAM_LOG_CTX_ADDR 0x4003C000
static void check_log(){
volatile log_ctx_t *log_ctx = (log_ctx_t*)IRAM_LOG_CTX_ADDR;
if(log_ctx->magic == 0xaabbccdd){
gfx_printf("\nLogs:\n");
gfx_printf((char*)log_ctx->buf);
}
}
volatile nyx_storage_t *nyx_str = (nyx_storage_t *)NYX_STORAGE_ADDR;
extern void pivot_stack(u32 stack_top);
void ipl_main()
{
// Do initial HW configuration. This is compatible with consecutive reruns without a reset.
hw_init();
// Pivot the stack under IPL. (Only max 4KB is needed).
pivot_stack(IPL_LOAD_ADDR);
// Place heap at a place outside of L4T/HOS configuration and binaries.
heap_init((void *)IPL_HEAP_START);
// Prep RTC regs for read. Needed for T210B01 R2C.
max77620_rtc_prep_read();
// Initialize display.
display_init();
u32 *fb = display_init_window_a_pitch();
gfx_init_ctxt(fb, 720, 1280, 720);
gfx_con_init();
// Initialize backlight PWM.
display_backlight_pwm_init();
display_backlight_brightness(100, 0);
// Show AMS errors
secmon_exo_check_panic();
check_log();
gfx_printf("\n\nPress POWER to power off\nPress VOLUME to boot RCM\n");
msleep(250);
do{
u8 btn = btn_read();
if(btn & BTN_POWER){
power_set_state(POWER_OFF);
}
if(btn & (BTN_VOL_DOWN | BTN_VOL_UP)){
power_set_state(REBOOT_RCM);
}
}while(true);
// Halt BPMP if we managed to get out of execution.
while (true)
bpmp_halt();
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2018 naehrwert
*
* 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/>.
*/
.section .text._start
.arm
.extern _reloc_ipl
.type _reloc_ipl, %function
.extern memset
.type memset, %function
.extern _irq_setup
.type _irq_setup, %function
.globl _start
.type _start, %function
_start:
ADR R0, _start
LDR R1, =__ipl_start
CMP R0, R1
BEQ _real_start
/* If we are not in the right location already, copy a relocator to upper IRAM. */
ADR R2, _reloc_ipl
LDR R3, =0x4003FF00
MOV R4, #(_real_start - _reloc_ipl)
_copy_loop:
LDMIA R2!, {R5}
STMIA R3!, {R5}
SUBS R4, #4
BNE _copy_loop
/* Use the relocator to copy ourselves into the right place. */
LDR R2, =__ipl_end
SUB R2, R2, R1
LDR R3, =_real_start
LDR R4, =0x4003FF00
BX R4
_reloc_ipl:
LDMIA R0!, {R4-R7}
STMIA R1!, {R4-R7}
SUBS R2, #0x10
BNE _reloc_ipl
/* Jump to the relocated entry. */
BX R3
_real_start:
/* Initially, we place our stack under relocator but will move it to under the payload. */
/* This depends on application scope. */
LDR SP, =0x4003FF00
LDR R0, =__bss_start
EOR R1, R1, R1
LDR R2, =__bss_end
SUB R2, R2, R0
BL memset
BL _irq_setup
B .
.globl pivot_stack
.type pivot_stack, %function
pivot_stack:
MOV SP, R0
BX LR

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

@@ -33,40 +33,39 @@
#include <switch/types.h> #include <switch/types.h>
typedef enum typedef enum
{ {
HocClkSocType_Erista = 0, HocClkSocType_Erista = 0, // T210, found in Icosa and Copper
HocClkSocType_Mariko, HocClkSocType_Mariko, // T214/T210B01, found in Hoag, Iowa, Calcio and Aula
// HocClkSocType_Drake, // T239, found in Switch 2. Maybe someday...
HocClkSocType_EnumMax HocClkSocType_EnumMax
} HocClkSocType; } HocClkSocType;
typedef enum typedef enum
{ {
HocClkConsoleType_Icosa = 0, HocClkConsoleType_Icosa = 0, // V1
HocClkConsoleType_Copper, HocClkConsoleType_Iowa, // V2
HocClkConsoleType_Hoag, HocClkConsoleType_Hoag, // Lite
HocClkConsoleType_Iowa, HocClkConsoleType_Aula, // OLED
HocClkConsoleType_Calcio,
HocClkConsoleType_Aula,
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, HocClkVoltage_EMCVDDQ, // DRAM VDDQ rail
HocClkVoltage_Display, HocClkVoltage_Display, // Display rail
HocClkVoltage_Battery, HocClkVoltage_Battery, // Battery voltage
HocClkVoltage_EnumMax, HocClkVoltage_EnumMax,
} HocClkVoltage; } HocClkVoltage;
typedef enum typedef enum
{ {
HocClkProfile_Handheld = 0, HocClkProfile_Handheld = 0,
HocClkProfile_HandheldCharging, HocClkProfile_HandheldCharging, // Not a real profile, just a marker
HocClkProfile_HandheldChargingUSB, HocClkProfile_HandheldChargingUSB,
HocClkProfile_HandheldChargingOfficial, HocClkProfile_HandheldChargingOfficial,
HocClkProfile_Docked, HocClkProfile_Docked, // Not shown on Lites
HocClkProfile_EnumMax HocClkProfile_EnumMax
} HocClkProfile; } HocClkProfile;
@@ -82,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, 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, 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;
@@ -107,8 +108,12 @@ typedef enum
HocClkPartLoad_EMCCpu, HocClkPartLoad_EMCCpu,
HocClkPartLoad_GPU, HocClkPartLoad_GPU,
HocClkPartLoad_CPUMax, HocClkPartLoad_CPUMax,
HocClkPartLoad_BAT, HocClkPartLoad_BAT, // Battery raw charge percentage
HocClkPartLoad_FAN, HocClkPartLoad_FAN,
HocClkPartLoad_RamBWAll,
HocClkPartLoad_RamBWCpu,
HocClkPartLoad_RamBWGpu,
HocClkPartLoad_RamBWPeak, // Maximum possible RAM bandwidth
HocClkPartLoad_EnumMax HocClkPartLoad_EnumMax
} HocClkPartLoad; } HocClkPartLoad;
@@ -123,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,
@@ -158,6 +165,64 @@ typedef enum {
RamDisplayMode_EnumMax, RamDisplayMode_EnumMax,
} RamDisplayMode; } RamDisplayMode;
typedef enum {
MemoryFrequencyMeasurementMode_PLL = 0,
MemoryFrequencyMeasurementMode_Actmon,
MemoryFrequencyMeasurementMode_EnumMax,
} MemoryFrequencyMeasurementMode;
typedef enum {
RamDisplayUnit_MHz = 0,
RamDisplayUnit_MTs,
RamDisplayUnit_MHzMTs,
RamDisplayUnit_EnumMax,
} 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)
// Packed u32 // Packed u32
@@ -219,8 +284,12 @@ 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 NULL; return "unknown";
} }
} }
@@ -233,7 +302,7 @@ static inline const char* hocclkFormatPowerSensor(HocClkPowerSensor powSensor, b
case HocClkPowerSensor_Avg: case HocClkPowerSensor_Avg:
return pretty ? "Avg" : "avg"; return pretty ? "Avg" : "avg";
default: default:
return NULL; return "unknown";
} }
} }
@@ -252,7 +321,7 @@ static inline const char* hocclkFormatProfile(HocClkProfile profile, bool pretty
case HocClkProfile_HandheldChargingOfficial: case HocClkProfile_HandheldChargingOfficial:
return pretty ? "PD Charger" : "handheld_charging_official"; return pretty ? "PD Charger" : "handheld_charging_official";
default: default:
return NULL; return "unknown";
} }
} }
@@ -266,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:
@@ -274,6 +343,64 @@ static inline const char* hocClkFormatVoltage(HocClkVoltage voltage, bool pretty
case HocClkVoltage_Display: case HocClkVoltage_Display:
return pretty ? "Display" : "display"; return pretty ? "Display" : "display";
default: default:
return NULL; 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,10 +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
u8 reserved[0x35B];
} HocClkContext; } HocClkContext;
typedef struct typedef struct
@@ -68,6 +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);

View File

@@ -29,7 +29,7 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include "board.h"
typedef enum { typedef enum {
HocClkConfigValue_PollingIntervalMs = 0, HocClkConfigValue_PollingIntervalMs = 0,
HocClkConfigValue_TempLogIntervalMs, HocClkConfigValue_TempLogIntervalMs,
@@ -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,
@@ -66,18 +62,32 @@ typedef enum {
HocClkConfigValue_RAMVoltDisplayMode, HocClkConfigValue_RAMVoltDisplayMode,
HocClkConfigValue_CpuGovernorMinimumFreq, HocClkConfigValue_CpuGovernorMinimumFreq,
HocClkConfigValue_DisplayVoltage,
HocClkConfigValue_MemoryFrequencyMeasurementMode,
HocClkConfigValue_RamDisplayUnit,
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_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,
@@ -87,8 +97,22 @@ typedef enum {
KipConfigValue_t6_tRTW, KipConfigValue_t6_tRTW,
KipConfigValue_t7_tWTR, KipConfigValue_t7_tWTR,
KipConfigValue_t8_tREFI, KipConfigValue_t8_tREFI,
KipConfigValue_mem_burst_read_latency,
KipConfigValue_mem_burst_write_latency, KipConfigValue_timingEmcTbreak,
KipConfigValue_low_t6_tRTW,
KipConfigValue_low_t7_tWTR,
KipConfigValue_t2_tRP_cap,
KipConfigValue_read_latency_1333,
KipConfigValue_read_latency_1600,
KipConfigValue_read_latency_1866,
KipConfigValue_read_latency_2133,
KipConfigValue_write_latency_1333,
KipConfigValue_write_latency_1600,
KipConfigValue_write_latency_1866,
KipConfigValue_write_latency_2133,
KipConfigValue_eristaCpuUV, KipConfigValue_eristaCpuUV,
KipConfigValue_eristaCpuVmin, KipConfigValue_eristaCpuVmin,
@@ -110,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,
@@ -172,7 +196,6 @@ typedef enum {
KipConfigValue_t7_tWTR_fine_tune, KipConfigValue_t7_tWTR_fine_tune,
KipCrc32, KipCrc32,
HocClkConfigValue_IsFirstLoad,
HocClkConfigValue_EnumMax, HocClkConfigValue_EnumMax,
} HocClkConfigValue; } HocClkConfigValue;
@@ -212,18 +235,12 @@ 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";
@@ -252,9 +269,32 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
return pretty ? "RAM Voltage / Usage Display Mode" : "ram_volt_usage_display_mode"; return pretty ? "RAM Voltage / Usage Display Mode" : "ram_volt_usage_display_mode";
case HocClkConfigValue_CpuGovernorMinimumFreq: case HocClkConfigValue_CpuGovernorMinimumFreq:
return pretty ? "CPU Governor Minimum Frequency" : "cpu_gov_min_freq"; return pretty ? "CPU Governor Minimum Frequency" : "cpu_gov_min_freq";
case HocClkConfigValue_DisplayVoltage:
return pretty ? "Display Voltage" : "display_voltage";
case HocClkConfigValue_MemoryFrequencyMeasurementMode:
return pretty ? "RAM Frequency Measurement Mode" : "mem_freq_measurement_mode";
case HocClkConfigValue_RamDisplayUnit:
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:
@@ -264,18 +304,17 @@ 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: case KipConfigValue_stepMode:
return pretty ? "Erista EMC Max Clock 2" : "erista_emc_max_clock1"; return pretty ? "Step Mode:" : "step_mode";
case KipConfigValue_eristaEmcMaxClock2:
return pretty ? "Erista EMC Max Clock 3" : "erista_emc_max_clock2";
case KipConfigValue_marikoEmcMaxClock: case KipConfigValue_marikoEmcMaxClock:
return pretty ? "Mariko EMC Max Clock" : "mariko_emc_max_clock"; return pretty ? "Mariko EMC Max Clock" : "mariko_emc_max_clock";
case KipConfigValue_marikoEmcVddqVolt: case KipConfigValue_marikoEmcVddqVolt:
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";
@@ -293,10 +332,34 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
return pretty ? "t7 - tWTR" : "t7_twtr"; return pretty ? "t7 - tWTR" : "t7_twtr";
case KipConfigValue_t8_tREFI: case KipConfigValue_t8_tREFI:
return pretty ? "t8 - tREFI" : "t8_trefi"; return pretty ? "t8 - tREFI" : "t8_trefi";
case KipConfigValue_mem_burst_read_latency:
return pretty ? "Memory Burst Read Latency" : "mem_burst_read_latency"; case KipConfigValue_timingEmcTbreak:
case KipConfigValue_mem_burst_write_latency: return pretty ? "Timing Emc Tbreak" : "timingEmcTbreak";
return pretty ? "Memory Burst Write Latency" : "mem_burst_write_latency"; case KipConfigValue_low_t6_tRTW:
return pretty ? "Low T6 - tRTW" : "low_t6_tRTW";
case KipConfigValue_low_t7_tWTR:
return pretty ? "Low T7 - tWTR" : "low_t7_tWTR";
case KipConfigValue_t2_tRP_cap:
return pretty ? "t2 - trp 1333WL Cap" : "t2_tRP_cap";
case KipConfigValue_read_latency_1333:
return pretty ? "1333 Read Latency" : "read_latency_1333";
case KipConfigValue_read_latency_1600:
return pretty ? "1600 Read Latency" : "read_latency_1600";
case KipConfigValue_read_latency_1866:
return pretty ? "1866 Read Latency" : "read_latency_1866";
case KipConfigValue_read_latency_2133:
return pretty ? "2133 Read Latency" : "read_latency_2133";
case KipConfigValue_write_latency_1333:
return pretty ? "1333 Write Latency" : "write_latency_1333";
case KipConfigValue_write_latency_1600:
return pretty ? "1600 Write Latency" : "write_latency_1600";
case KipConfigValue_write_latency_1866:
return pretty ? "1866 Write Latency" : "write_latency_1866";
case KipConfigValue_write_latency_2133:
return pretty ? "2133 Write Latency" : "write_latency_2133";
// CPU Erista // CPU Erista
case KipConfigValue_eristaCpuUV: case KipConfigValue_eristaCpuUV:
@@ -341,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";
@@ -403,7 +466,7 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
case KipConfigValue_g_volt_e_998400: return pretty ? "Erista GPU Volt 998 MHz" : "g_volt_e_998400"; case KipConfigValue_g_volt_e_998400: return pretty ? "Erista GPU Volt 998 MHz" : "g_volt_e_998400";
case KipConfigValue_g_volt_e_1036800: return pretty ? "Erista GPU Volt 1036 MHz" : "g_volt_e_1036800"; case KipConfigValue_g_volt_e_1036800: return pretty ? "Erista GPU Volt 1036 MHz" : "g_volt_e_1036800";
case KipConfigValue_g_volt_e_1075200: return pretty ? "Erista GPU Volt 1075 MHz" : "g_volt_e_1075200"; case KipConfigValue_g_volt_e_1075200: return pretty ? "Erista GPU Volt 1075 MHz" : "g_volt_e_1075200";
case KipConfigValue_t6_tRTW_fine_tune: return pretty ? "t6 - tRTW Fine Tune" : "t6_tRTW_fine_fune"; case KipConfigValue_t6_tRTW_fine_tune: return pretty ? "t6 - tRTW Fine Tune" : "t6_tRTW_fine_tune";
case KipConfigValue_t7_tWTR_fine_tune: return pretty ? "t7 - tWTR Fine Tune" : "t7_tWTR_fine_tune"; case KipConfigValue_t7_tWTR_fine_tune: return pretty ? "t7 - tWTR Fine Tune" : "t7_tWTR_fine_tune";
case KipCrc32: case KipCrc32:
return pretty ? "CRC32" : "crc32"; return pretty ? "CRC32" : "crc32";
@@ -427,11 +490,16 @@ 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_MarikoMiddleFreqs:
return 0ULL; return 0ULL;
case HocClkConfigValue_RamDisplayUnit:
return (uint64_t)RamDisplayUnit_MHz;
case HocClkConfigValue_EristaMaxCpuClock: case HocClkConfigValue_EristaMaxCpuClock:
return 1785ULL; return 1785ULL;
@@ -439,20 +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:
return 1200ULL; // Auto
case HocClkConfigValue_AulaDisplayColorPreset:
return AulaDisplayColorMode_DoNotOverride;
default: default:
return 0ULL; return 0ULL;
} }
@@ -465,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;
@@ -478,24 +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_stepMode:
case KipConfigValue_eristaEmcMaxClock2:
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:
@@ -504,8 +576,18 @@ static inline uint64_t hocclkValidConfigValue(HocClkConfigValue val, uint64_t in
case KipConfigValue_t6_tRTW: case KipConfigValue_t6_tRTW:
case KipConfigValue_t7_tWTR: case KipConfigValue_t7_tWTR:
case KipConfigValue_t8_tREFI: case KipConfigValue_t8_tREFI:
case KipConfigValue_mem_burst_read_latency: case KipConfigValue_timingEmcTbreak:
case KipConfigValue_mem_burst_write_latency: case KipConfigValue_low_t6_tRTW:
case KipConfigValue_low_t7_tWTR:
case KipConfigValue_t2_tRP_cap:
case KipConfigValue_read_latency_1333:
case KipConfigValue_read_latency_1600:
case KipConfigValue_read_latency_1866:
case KipConfigValue_read_latency_2133:
case KipConfigValue_write_latency_1333:
case KipConfigValue_write_latency_1600:
case KipConfigValue_write_latency_1866:
case KipConfigValue_write_latency_2133:
case KipConfigValue_eristaCpuUV: case KipConfigValue_eristaCpuUV:
case KipConfigValue_eristaCpuMaxVolt: case KipConfigValue_eristaCpuMaxVolt:
case KipConfigValue_marikoCpuUVLow: case KipConfigValue_marikoCpuUVLow:
@@ -521,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:
@@ -585,10 +667,22 @@ static inline uint64_t hocclkValidConfigValue(HocClkConfigValue val, uint64_t in
case HocClkConfigValue_GPUScheduling: case HocClkConfigValue_GPUScheduling:
case HocClkConfigValue_RAMVoltDisplayMode: case HocClkConfigValue_RAMVoltDisplayMode:
case HocClkConfigValue_CpuGovernorMinimumFreq: case HocClkConfigValue_CpuGovernorMinimumFreq:
case HocClkConfigValue_MemoryFrequencyMeasurementMode:
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:
return ((input >= 800) && (input <= 1325));
default: default:
return false; return true;
} }
} }

View File

@@ -31,7 +31,7 @@
#include "board.h" #include "board.h"
#include "clock_manager.h" #include "clock_manager.h"
#define HOCCLK_IPC_API_VERSION 1 #define HOCCLK_IPC_API_VERSION 2
#define HOCCLK_IPC_SERVICE_NAME "hoc:clk" #define HOCCLK_IPC_SERVICE_NAME "hoc:clk"
enum HocClkIpcCmd enum HocClkIpcCmd

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,62 +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_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, 0x7F, 12500, 600000, 1250000, };
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 Zeus 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 := 1.2.0 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,141 +1,215 @@
{ {
"Information": "Información", "Information": "Información",
"IDDQ:": "IDDQ:",
"Module: ": "Módulo:",
"sys-dock status:": "estado del sys-dock:",
"SaltyNX status:": "Estado de SaltyNX:",
"RR Display status:": "Estado de visualización RR:",
"Wafer Position:": "Posición de la oblea:",
"Credits": "Créditos",
"Developers": "Desarrolladores",
"Contributors": "Colaboradores",
"Testers": "Probadores",
"Special Thanks": "agradecimiento especial",
"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": "LA LICENCIA DE CERVEZA",
"Default": "Predeterminado", "Default": "Predeterminado",
"Do Not Override": "No anular", "Do Not Override": "No sobrescribir",
"Disabled": "Discapacitado", "Do not override": "No sobrescribir",
"Enabled": "Habilitado", "Disabled": "Desactivado",
" \\ue0e3 Reset": "\\ue0e3 Restablecer", "Enabled": "Activado",
"Display": "Pantalla", "Enabled (Default)": "Activado (predeterminado)",
"Application changed\\n\\n": "Aplicación modificada\\n\\n", "Enable": "Activar",
"The running application changed\\n\\n": "La aplicación en ejecución cambió\\n\\n", "Fatal error": "Error fatal",
"while editing was going on.": "mientras se realizaba la edición.", "Could not connect to hoc-clk sysmodule.\\n\\n": "No se pudo conectar al sysmodule hoc-clk.\\n\\n",
"Board": "tablero", "Please make sure everything is\\n\\n": "Asegúrate de que todo esté\\n\\n",
"%u.%u%u mV": "%u.%u%u mV", "correctly installed and enabled.": "correctamente instalado y activado.",
"Could not connect to hoc-clk sysmodule.\\n\\n": "No se pudo conectar al módulo del sistema hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Por favor asegúrese de que todo esté\\n\\n",
"correctly installed and enabled.": "correctamente instalado y habilitado.",
"Fatal error": "error fatal",
"Temporary Overrides ": "Anulaciones temporales",
"Sleep Mode": "Modo de suspensión",
"Stock": "Valores",
"Dev OC": "Desarrollador OC",
"Boost Mode": "Modo de impulso",
"Safe Max": "Máximo seguro",
"Unsafe Max": "Máximo inseguro",
"Absolute Max": "Máximo absoluto",
"Handheld Safe Max": "Caja fuerte de mano máx.",
"Enable": "Habilitar",
"Edit App Profile": "Editar perfil de aplicación", "Edit App Profile": "Editar perfil de aplicación",
"Edit Global Profile": "Editar perfil global", "Edit Global Profile": "Editar perfil global",
"Temporary Overrides": "Anulaciones temporales", "Temporary Overrides": "Ajustes temporales",
"Temporary Overrides ": "Ajustes temporales",
"  Reset": " Restablecer",
"Settings": "Configuración", "Settings": "Configuración",
"About": "Acerca de", "About": "Acerca de",
"Compiling with minimal features": "Compilando con características mínimas", "Credits": "Créditos",
"General Settings": "Configuraciones generales",
"Governor Settings": "Configuración del gobernador", "Application changed\\n\\n": "Aplicación cambiada\\n\\n",
"Safety Settings": "Configuraciones de seguridad", "The running application changed\\n\\n": "La aplicación en ejecución ha cambiado\\n\\n",
"Save KIP Settings": "Guardar configuración de KIP", "while editing was going on.": "mientras se estaba editando.",
"Sleep Mode": "Modo reposo",
"Stock": "Valores de fábrica",
"Dev OC": "OC de desarrollo",
"Boost Mode": "Modo boost",
"Safe Max": "Máximo seguro",
"Unsafe Max": "Máximo no seguro",
"Absolute Max": "Máximo absoluto",
"Handheld Safe Max": "Máximo seguro en portátil",
"General Settings": "Configuración general",
"Governor Settings": "Configuración del governor",
"Safety Settings": "Configuración de seguridad",
"Save KIP Settings": "Guardar configuración KIP",
"RAM Settings": "Configuración de RAM", "RAM Settings": "Configuración de RAM",
"CPU Settings": "Configuración de la 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",
"GPU Scheduling Override Method": "Método de anulación de programación de GPU",
"can be dangerous and may cause": "puede ser peligroso y puede causar", " Settings marked in blue": "La configuración en azul",
"damage to your battery or charger!": "¡Daños a su batería o cargador!", "don't require a reboot to apply!": "no requiere reinicio para aplicarse.",
"Charge Current Override": "Anulación de corriente de carga", "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 Voltage Display Mode": "Modo de visualización de voltaje de RAM",
"RAM Display Unit": "Unidad de visualización RAM",
"Polling Interval": "Intervalo de sondeo", "Polling Interval": "Intervalo de sondeo",
"CPU Governor Minimum Frequency": "Frecuencia mínima del gobernador de CPU",
"refresh rates may cause stress": "Las frecuencias de actualización pueden causar estrés.", "GPU Scheduling Override Method": "Método de sobrescritura del scheduling de GPU",
"or damage to your display! ": "o daños a su pantalla!", "GPU Scheduling Override": "Sobrescritura de scheduling de GPU",
"Proceed at your own risk!": "¡Continúe bajo su propio riesgo!", "GPU Boot Volt": "Voltaje de arranque GPU",
"Max Handheld Display": "Pantalla portátil máxima", "GPU Boot Voltage": "Voltaje de arranque GPU",
"Display Clock": "Reloj de pantalla", "Memory Frequency Measurement Mode": "Modo de medición de frecuencia de memoria",
"Official Rating": "Calificación oficial", " Overriding the charge current": "Sobrescribir la corriente de carga",
"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.",
"Charge Current Override": "Sobrescritura de corriente de carga",
"Display Color Preset": "Preajuste de color",
"Basic": "Básico",
"Saturated": "Saturado",
"Washed": "Lavado",
"Natural": "Natural",
"Vivid": "Vívido",
"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",
"or damage to your display! ": "o dañar la pantalla.",
"Proceed at your own risk!": "¡Úsalo bajo tu propio riesgo!",
"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",
" 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",
"TDP Threshold": "Umbral de TDP", "TDP Threshold": "Umbral de TDP",
"Power": "poder", "Power": "Potencia",
"Thermal Throttle Limit": "Límite del acelerador térmico", "HP Mode": "Modo alto rendimiento",
"HP Mode": "Modo HP",
"Default (Mariko)": "Predeterminado (Mariko)", "DVB Shift": "Desplazamiento DVB",
"Default (Erista)": "Predeterminado (Erista)", "SoC Max Volt": "Voltaje máximo del SoC",
"Rating": "Calificación", "Step Mode": "Modo de paso",
"Safe Max (Mariko)": "Max seguro (Mariko)", "RAM VDD2 Voltage": "Voltaje VDD2 de RAM",
"Safe Max (Erista)": "Safe Max (Erista)", "RAM VDDQ Voltage": "Voltaje VDDQ de RAM",
"RAM VDD2 Voltage": "Voltaje RAM VDD2", "Voltage": "Voltaje",
"Voltage": "voltaje", "RAM Frequency Editor": "Editor de frecuencia de RAM",
"RAM VDDQ Voltage": "Voltaje RAM VDDQ", "Ram Max Clock": "Frecuencia máxima de RAM",
"RAM Frequency Editor": "Editor de frecuencia RAM", "RAM Latency Editor": "Editor de latencias de RAM",
"JEDEC.": "JEDEC.", "RAM Timing Reductions": "Reducción de timings de RAM",
"High speedo needed!": "¡Se necesita alta velocidad!", "Memory Timings": "Timings de memoria",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (Necesita Speedo/PLL extremo)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (Necesita Speedo/PLL extremo)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (Necesita Speedo/PLL extremo)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (Necesita Speedo/PLL ridículo)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (Necesita Speedo/PLL ridículo)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (Necesita Speedo/PLL ridículo)",
"Ram Max Clock": "Ram Max Reloj",
"RAM Latency Editor": "Editor de latencia de RAM",
"RAM Timing Reductions": "Reducciones de tiempo de RAM",
"Memory Timings": "Tiempos de memoria",
"Advanced": "Avanzado", "Advanced": "Avanzado",
"t6 tRTW Fine Tune": "t6 tRTW Ajuste fino", "t6 tRTW Fine Tune": "Ajuste fino t6 tRTW",
"tRTW Fine Tune": "Ajuste fino tRTW", "tRTW Fine Tune": "Ajuste fino tRTW",
"t7 tWTR Fine Tune": "t7 tWTR Ajuste fino", "t7 tWTR Fine Tune": "Ajuste fino t7 tWTR",
"tWTR Fine Tune": "Ajuste fino de tWTR", "tWTR Fine Tune": "Ajuste fino tWTR",
"Memory Latencies": "Latencias de la memoria", "Memory Latencies": "Latencias de memoria",
"Read Latency": "Leer latencia", "Read Latency": "Latencia de lectura",
"Write Latency": "Latencia de escritura", "Write Latency": "Latencia de escritura",
"CPU Boost Clock": "Reloj de aumento de CPU", "High speedo needed!": "¡Se necesita alto speedo!",
"CPU UV": "procesador ultravioleta", "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 UV": "Undervolt de CPU",
"CPU Unlock": "Desbloqueo de CPU", "CPU Unlock": "Desbloqueo de CPU",
"CPU VMIN": "CPU VMIN", "CPU VMIN": "VMIN de CPU",
"CPU Max Voltage": "Voltaje máximo de la CPU", "CPU Max Voltage": "Voltaje máximo de CPU",
"CPU Max Clock": "Reloj máximo de CPU", "CPU Max Clock": "Frecuencia máxima de CPU",
"Extreme UV Table": "Mesa UV extrema", "Extreme UV Table": "Tabla de undervolt extrema",
"CPU UV Table": "Tabla UV de CPU", "CPU UV Table": "Tabla de undervolt de CPU",
"CPU Low UV": "CPU baja radiación ultravioleta", "CPU Low UV": "Undervolt bajo de CPU",
"CPU High UV": "CPU alta UV", "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 subvoltaje",
"SLT Table": "Mesa TR", "No Undervolt": "Sin undervolt",
"SLT Table": "Tabla SLT",
"HiOPT Table": "Tabla HiOPT", "HiOPT Table": "Tabla HiOPT",
"GPU Undervolt Table": "Tabla de subvoltaje de GPU", "GPU Undervolt Table": "Tabla de undervolt de GPU",
"GPU Minimum Voltage": "Voltaje mínimo de GPU", "GPU Minimum Voltage": "Voltaje mínimo de GPU",
"Calculate GPU Vmin": "Calcular GPU Vmin", "Calculate GPU Vmin": "Calcular Vmin de GPU",
"GPU VMIN": "GPU VMIN", "GPU VMIN": "VMIN de GPU",
"GPU Maximum Voltage": "Voltaje máximo de GPU", "GPU Maximum Voltage": "Voltaje máximo de GPU",
"GPU Voltage Offset": "Compensación de voltaje de GPU", "GPU Voltage Offset": "Offset de voltaje de GPU",
"Do not override": "no anular", "GPU DVFS Mode": "Modo DVFS de GPU",
"Enabled (Default)": "Habilitado (predeterminado)", "GPU DVFS Offset": "Offset DVFS de GPU",
"96.6% limit": "límite del 96,6%",
"99.7% limit": "límite del 99,7%",
"GPU Scheduling Override": "Anulación de programación de GPU",
"Official Service": "Servicio Oficial",
"GPU DVFS Mode": "Modo GPU DVFS",
"GPU DVFS Offset": "Compensación 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)",
"1075MHz without UV, 1152MHz on SLT": "1075MHz sin UV, 1152MHz en SLT", "Official Service": "Servicio oficial",
"or 1228MHz on HiOPT can cause ": "o 1228MHz en HiOPT pueden causar", "96.6% limit": "Límite 96,6%",
"permanent damage to your Switch!": "¡Daño permanente a tu Switch!", "99.7% limit": "Límite 99,7%",
"921MHz without UV and 960MHz on": "921MHz sin UV y 960MHz encendido", " Setting GPU Clocks past": "Ajustar frecuencias de GPU más allá",
"SLT or HiOPT can cause ": "SLT o HiOPT pueden causar" "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",
"or 1228MHz on HiOPT can cause ": "o 1228MHz en HiOPT pueden causar ",
"permanent damage to your Switch!": "¡daño permanente a tu Switch!",
"921MHz without UV and 960MHz on": "921MHz sin undervolt y 960MHz en",
"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,141 +1,215 @@
{ {
"Information": "Informazioni", "Information": "Informazioni",
"IDDQ:": "IDDQ:",
"Module: ": "Modulo:",
"sys-dock status:": "stato del dock di sistema:",
"SaltyNX status:": "Stato di SaltyNX:",
"RR Display status:": "Stato di visualizzazione RR:",
"Wafer Position:": "Posizione del 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": "LA LICENZA PER GLI ARTICOLI DI BIRRA",
"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": "Visualizzazione", "Enable": "Abilita",
"Fatal error": "Errore fatale",
"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",
"correctly installed and enabled.": "correttamente installato e abilitato.",
"Edit App Profile": "Modifica Profilo Dell'App",
"Edit Global Profile": "Modifica Profilo Globale",
"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", "Application changed\\n\\n": "Applicazione modificata\\n\\n",
"The running application changed\\n\\n": "L'applicazione in esecuzione è cambiata\\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.", "while editing was going on.": "mentre era in corso la modifica.",
"Board": "Consiglio",
"%u.%u%u mV": "%u.%u%u mV", "Sleep Mode": "Modalità di Sospensione",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Impossibile connettersi al modulo di sistema hoc-clk.\\n\\n", "Stock": "Originale",
"Please make sure everything is\\n\\n": "Assicurati che tutto sia\\n\\n", "Dev OC": "OC dev",
"correctly installed and enabled.": "correttamente installato e abilitato.", "Boost Mode": "Modalità Boost",
"Fatal error": "Errore fatale", "Safe Max": "Massimo Sicuro",
"Temporary Overrides ": "Sostituzioni temporanee", "Unsafe Max": "Massimo Non Sicuro",
"Sleep Mode": "Modalità di sospensione", "Absolute Max": "Massimo Assoluto",
"Stock": "Magazzino", "Handheld Safe Max": "Massimo Sicuro Modalità Portatile",
"Dev OC": "OC di sviluppo",
"Boost Mode": "Modalità potenziamento", "General Settings": "Impostazioni Generali",
"Safe Max": "Sicuro massimo", "Governor Settings": "Impostazioni Del Governor",
"Unsafe Max": "Non sicuro Max", "Safety Settings": "Impostazioni Di Sicurezza",
"Absolute Max": "Massimo assoluto", "Save KIP Settings": "Salva le impostazioni del KIP",
"Handheld Safe Max": "Cassaforte portatile max",
"Enable": "Abilita",
"Edit App Profile": "Modifica profilo dell'app",
"Edit Global Profile": "Modifica profilo globale",
"Temporary Overrides": "Sostituzioni temporanee",
"Settings": "Impostazioni",
"About": "Circa",
"Compiling with minimal features": "Compilazione con funzionalità minime",
"General Settings": "Impostazioni generali",
"Governor Settings": "Impostazioni del governatore",
"Safety Settings": "Impostazioni di sicurezza",
"Save KIP Settings": "Salva le impostazioni KIP",
"RAM Settings": "Impostazioni della RAM", "RAM Settings": "Impostazioni della RAM",
"CPU Settings": "Impostazioni della CPU", "CPU Settings": "Impostazioni della CPU",
"GPU Settings": "Impostazioni della GPU", "GPU Settings": "Impostazioni della GPU",
"Display Settings": "Impostazioni di visualizzazione", "Display Settings": "Impostazioni dello Schermo",
"Experimental Settings": "Impostazioni sperimentali",
"Experimental": "Sperimentale", "Experimental": "Sperimentale",
"GPU Scheduling Override Method": "Metodo di override della pianificazione GPU",
" 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": "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",
"CPU Governor Minimum Frequency": "Frequenza minima del governatore della CPU", "Saturated": "Saturo",
"Washed": "Sbiadito",
"Natural": "Naturale",
"Vivid": "Vivace",
"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 portatile massimo", "Max Handheld Display": "Display Massimo in Modalità Portatile",
"Display Clock": "Visualizza orologio", "Max Handheld Display Hz": "Hz max in modalità portatile",
"Official Rating": "Valutazione ufficiale", "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",
"TDP Threshold": "Soglia TDP", "TDP Threshold": "Soglia TDP",
"Power": "Potenza", "Power": "Potenza",
"Thermal Throttle Limit": "Limite della valvola termica",
"HP Mode": "Modalità HP", "HP Mode": "Modalità HP",
"DVB Shift": "Offset DVB",
"SoC Max Volt": "Tensione massima SoC",
"Step Mode": "Modalità passo",
"RAM VDD2 Voltage": "Tensione RAM VDD2",
"RAM VDDQ Voltage": "Voltaggio VDDQ della RAM",
"Voltage": "Voltaggio",
"RAM Frequency Editor": "Editor della frequenza RAM",
"Ram Max Clock": "Frequenza Massima Ram",
"RAM Latency Editor": "Editor della Latenza RAM",
"RAM Timing Reductions": "Riduzioni dei Timing della RAM",
"Memory Timings": "Timing di Memoria",
"Advanced": "Avanzato",
"t6 tRTW Fine Tune": "Regolazione Fine t6 tRTW",
"tRTW Fine Tune": "Regolazione Fine tRTW",
"t7 tWTR Fine Tune": "Regolazione Fine t7 tWTR",
"tWTR Fine Tune": "Regolazione Fine tWTR",
"Memory Latencies": "Latenza della Memoria",
"Read Latency": "Latenza di Lettura",
"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 UV": "Undervolt CPU",
"CPU Unlock": "Sblocco della CPU",
"CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "Voltaggio massimo della CPU",
"CPU Max Clock": "Frequenza massima della CPU",
"Extreme UV Table": "Tabella UV estremo",
"CPU UV Table": "Tabella UV della CPU",
"CPU Low UV": "CPU UV Bassa Frequenza",
"CPU High UV": "CPU UV Alta Frequenza",
"CPU Low VMIN": "CPU VMIN Bassa Frequenza",
"CPU High VMIN": "CPU VMIN Alta Frequenza",
"No Undervolt": "Nessun Undervolt",
"SLT Table": "Tabella SLT",
"HiOPT Table": "Tabella HiOPT",
"GPU Undervolt Table": "Tabella di Undervolt GPU",
"GPU Minimum Voltage": "Voltaggio Minimo della GPU",
"Calculate GPU Vmin": "Calcola GPU Vmin",
"GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "Voltaggio massimo della GPU",
"GPU Voltage Offset": "Offset di Voltaggio della GPU",
"GPU DVFS Mode": "Modalità DVFS GPU",
"GPU DVFS Offset": "Offset DVFS della GPU",
"GPU Voltage Table": "Tabella delle Tensioni della GPU",
"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",
"or 1228MHz on HiOPT can cause ": "o 1228 MHz su HiOPT possono causare",
"permanent damage to your Switch!": "danni permanenti alla tua Switch!",
"921MHz without UV and 960MHz on": "921 MHz senza UV e 960 MHz su",
"SLT or HiOPT can cause ": "SLT o HiOPT possono causare",
"Default (Mariko)": "Predefinito (Mariko)", "Default (Mariko)": "Predefinito (Mariko)",
"Default (Erista)": "Predefinito (Erista)", "Default (Erista)": "Predefinito (Erista)",
"Rating": "Valutazione", "Rating": "Valutazione",
"Safe Max (Mariko)": "Safe Max (Mariko)", "Safe Max (Mariko)": "Massimo Sicuro (Mariko)",
"Safe Max (Erista)": "Safe Max (Erista)", "Safe Max (Erista)": "Massimo Sicuro (Erista)",
"RAM VDD2 Voltage": "Tensione RAM VDD2",
"Voltage": "Voltaggio", "Voltages": "Tensioni",
"RAM VDDQ Voltage": "Voltaggio VDDQ della RAM", "RAM Voltage:": "Tensione RAM:",
"RAM Frequency Editor": "Editor della frequenza RAM", "Display Voltage:": "Tensione display:",
"JEDEC.": "JEDEC.", "Temperatures": "Temperature",
"High speedo needed!": "È necessaria l'alta velocità!", "PLLX Temp:": "PLLX Temp:",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (richiede Speedo/PLL estremo)", "AOTAG Temp:": "AOTAG Temp:",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (richiede Speedo/PLL estremo)", "BQ24193 Temp:": "BQ24193 Temp:",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (richiede Speedo/PLL estremo)", "Normal": "Normale",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (è necessario un ridicolo Speedo/PLL)", "Warm": "Caldo",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (è necessario un ridicolo Speedo/PLL)", "Hot": "Molto caldo",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (è necessario un ridicolo Speedo/PLL)", "Overheat": "Surriscaldamento",
"Ram Max Clock": "Orologio Ram Max", "Not Patched": "Non patchato",
"RAM Latency Editor": "Editor della latenza RAM", "Invalid": "Non valido",
"RAM Timing Reductions": "Riduzioni della temporizzazione della RAM", "RAM Bandwidth": "Banda RAM",
"Memory Timings": "Tempi di memoria", "RAM BW (Peak):": "BW RAM (Picco):",
"Advanced": "Avanzato", "RAM BW (All):": "BW RAM (Tutto):",
"t6 tRTW Fine Tune": "t6 tRTW Sintonia fine", "RAM BW (CPU):": "BW RAM (CPU):",
"tRTW Fine Tune": "tRTW Sintonia fine", "RAM BW (GPU):": "BW RAM (GPU):",
"t7 tWTR Fine Tune": "t7 tWTR Sintonia fine", "Hardware Info": "Info hardware",
"tWTR Fine Tune": "tWTR Sintonia fine", "Console Type:": "Tipo di console:",
"Memory Latencies": "Latenza della memoria", "Speedo:": "Speedo:",
"Read Latency": "Leggi latenza", "DRAM Module: ": "Modulo DRAM: ",
"Write Latency": "Scrivi latenza", "Software Info": "Info software",
"CPU Boost Clock": "Orologio di potenziamento della CPU", "KIP version:": "Versione KIP:",
"CPU UV": "UV della CPU", "sys-dock status:": "stato di sys-dock",
"CPU Unlock": "Sblocco della CPU", "SaltyNX status:": "Stato di SaltyNX:",
"CPU VMIN": "CPUVMIN", "RR Display status:": "Stato del RR:",
"CPU Max Voltage": "Voltaggio massimo della CPU", "Wafer Position:": "Posizione nel Wafer:",
"CPU Max Clock": "Orologio massimo della CPU", "IDDQ:": "IDDQ:",
"Extreme UV Table": "Tavolo UV estremo", "Module: ": "Modulo:",
"CPU UV Table": "Tabella UV della CPU", "Board": "Scheda",
"CPU Low UV": "CPU con raggi UV bassi", "Display": "Schermo",
"CPU High UV": "UV elevato della CPU",
"CPU Low VMIN": "VMIN CPU basso", "Developers": "Sviluppatori",
"CPU High VMIN": "CPU alta VMIN", "Contributors": "Collaboratori",
"No Undervolt": "Nessuna sottotensione", "Testers": "Tester",
"SLT Table": "Tabella SLT", "Translators": "Traduttori",
"HiOPT Table": "Tabella HiOPT", "Special Thanks": "Un Ringraziamento Speciale",
"GPU Undervolt Table": "Tabella di sottotensione GPU",
"GPU Minimum Voltage": "Voltaggio minimo della GPU", "X: %u Y: %u": "X: %u Y: %u",
"Calculate GPU Vmin": "Calcola GPU Vmin", "%u.%u%u mV": "%u.%u%u mV",
"GPU VMIN": "GPUVMIN", "Compiling with minimal features": "Compilazione con funzionalità minime",
"GPU Maximum Voltage": "Voltaggio massimo della GPU", "THE BEER-WARE LICENSE": "THE BEER-WARE LICENSE"
"GPU Voltage Offset": "Offset di tensione 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 della pianificazione GPU",
"Official Service": "Servizio ufficiale",
"GPU DVFS Mode": "Modalità DVFS GPU",
"GPU DVFS Offset": "Offset DVFS della GPU",
"GPU Voltage Table": "Tabella delle tensioni della GPU",
"GPU Custom Table (mV)": "Tabella personalizzata GPU (mV)",
"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",
"permanent damage to your Switch!": "danni permanenti al tuo Switch!",
"921MHz without UV and 960MHz on": "921 MHz senza UV e 960 MHz attivi",
"SLT or HiOPT can cause ": "SLT o HiOPT possono causare"
} }

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

@@ -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

@@ -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

@@ -24,19 +24,18 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#pragma once #pragma once
#include <cstdint>
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <cstdint>
#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;
} }
@@ -44,4 +43,50 @@ 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(std::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) {
if (mhz == 0)
return FREQ_DEFAULT_TEXT;
uint32_t mts = mhz * 2;
char buf[24];
switch (unit) {
case RamDisplayUnit_MHz:
snprintf(buf, sizeof(buf), "%u MHz", mhz);
break;
case RamDisplayUnit_MHzMTs:
snprintf(buf, sizeof(buf), "%u MHz (%u MT/s)", mhz, mts);
break;
case RamDisplayUnit_MTs:
default:
snprintf(buf, sizeof(buf), "%u MT/s", mts);
break;
}
return buf;
}
static inline std::string formatListFreqHzMem(uint32_t hz, RamDisplayUnit unit) {
return formatListFreqMem(hz / 1000000, unit);
}
static inline std::string formatMemClockKhzLabel(uint32_t khz, RamDisplayUnit unit) {
uint32_t mhz = khz / 1000;
uint32_t mts = khz / 500;
char buf[32];
switch (unit) {
case RamDisplayUnit_MHz:
snprintf(buf, sizeof(buf), "%u MHz", mhz);
break;
case RamDisplayUnit_MHzMTs:
snprintf(buf, sizeof(buf), "%u MHz (%u MT/s)", mhz, mts);
break;
case RamDisplayUnit_MTs:
default:
snprintf(buf, sizeof(buf), "%u MT/s", mts);
break;
}
return buf;
}

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;
@@ -31,11 +33,19 @@ tsl::elm::ListItem* RETROStatusItem = NULL;
tsl::elm::ListItem* waferCordsItem = NULL; tsl::elm::ListItem* waferCordsItem = NULL;
tsl::elm::ListItem* ramVoltItem = NULL; tsl::elm::ListItem* ramVoltItem = NULL;
tsl::elm::ListItem* eristaPLLXItem = NULL; tsl::elm::ListItem* eristaPLLXItem = NULL;
tsl::elm::ListItem* dispVoltItem = NULL;
tsl::elm::ListItem* ramBWItemAll = NULL;
tsl::elm::ListItem* ramBWItemCpu = NULL;
tsl::elm::ListItem* ramBWItemGpu = 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()
{ {
@@ -48,20 +58,71 @@ AboutGui::~AboutGui()
void AboutGui::listUI() void AboutGui::listUI()
{ {
BaseMenuGui::refresh();
if (!this->context)
return;
this->listElement->addItem( this->listElement->addItem(
new tsl::elm::CategoryHeader("Information") new tsl::elm::CategoryHeader("Voltages")
); );
ramVoltItem = ramVoltItem =
new tsl::elm::ListItem("RAM Voltage:"); new tsl::elm::ListItem("RAM Voltage:");
this->listElement->addItem(ramVoltItem);
if(IsMariko()) {
this->listElement->addItem(ramVoltItem);
}
dispVoltItem =
new tsl::elm::ListItem("Display Voltage:");
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(
new tsl::elm::CategoryHeader("RAM Bandwidth")
);
ramBWItemMax =
new tsl::elm::ListItem("RAM BW (Peak):");
this->listElement->addItem(ramBWItemMax);
ramBWItemAll =
new tsl::elm::ListItem("RAM BW (All):");
this->listElement->addItem(ramBWItemAll);
ramBWItemCpu =
new tsl::elm::ListItem("RAM BW (CPU):");
this->listElement->addItem(ramBWItemCpu);
ramBWItemGpu =
new tsl::elm::ListItem("RAM BW (GPU):");
this->listElement->addItem(ramBWItemGpu);
this->listElement->addItem(
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);
@@ -71,9 +132,29 @@ 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 =
new tsl::elm::ListItem("Wafer Position:");
this->listElement->addItem(waferCordsItem);
if(IsHoag()) {
RETROStatusItem =
new tsl::elm::ListItem("RR Display status:");
this->listElement->addItem(RETROStatusItem);
}
this->listElement->addItem(
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:");
@@ -84,167 +165,20 @@ void AboutGui::listUI()
new tsl::elm::ListItem("SaltyNX status:"); new tsl::elm::ListItem("SaltyNX status:");
this->listElement->addItem(saltyNXStatusItem); this->listElement->addItem(saltyNXStatusItem);
if(IsHoag()) {
RETROStatusItem =
new tsl::elm::ListItem("RR Display status:");
this->listElement->addItem(RETROStatusItem);
}
waferCordsItem =
new tsl::elm::ListItem("Wafer Position:");
this->listElement->addItem(waferCordsItem);
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() {
@@ -308,6 +242,10 @@ 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");
@@ -316,16 +254,213 @@ void AboutGui::refresh()
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", 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);
dispVoltItem->setValue(strings[5]);
sprintf(strings[6], "%u MB/s", context->partLoad[HocClkPartLoad_RamBWAll]);
ramBWItemAll->setValue(strings[6]);
sprintf(strings[7], "%u MB/s", context->partLoad[HocClkPartLoad_RamBWCpu]);
ramBWItemCpu->setValue(strings[7]);
sprintf(strings[8], "%u MB/s", context->partLoad[HocClkPartLoad_RamBWGpu]);
ramBWItemGpu->setValue(strings[8]);
sprintf(strings[9], "%u MB/s", context->partLoad[HocClkPartLoad_RamBWPeak]);
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"
@@ -59,9 +60,11 @@ void AppProfileGui::openFreqChoiceGui(tsl::elm::ListItem* listItem, HocClkProfil
} else if (module == HocClkModule_GPU) { } else if (module == HocClkModule_GPU) {
labels = IsMariko() ? *(marikoUV[configList.values[KipConfigValue_marikoGpuUV]]) : *(eristaUV[configList.values[KipConfigValue_eristaGpuUV]]); labels = IsMariko() ? *(marikoUV[configList.values[KipConfigValue_marikoGpuUV]]) : *(eristaUV[configList.values[KipConfigValue_eristaGpuUV]]);
} }
tsl::changeTo<FreqChoiceGui>(this->profileList->mhzMap[profile][module] * 1000000, hzList, hzCount, module, [this, listItem, profile, module](std::uint32_t hz) { RamDisplayUnit memUnit = (RamDisplayUnit)configList.values[HocClkConfigValue_RamDisplayUnit];
tsl::changeTo<FreqChoiceGui>(this->profileList->mhzMap[profile][module] * 1000000, hzList, hzCount, module, [this, listItem, profile, module, memUnit](std::uint32_t hz) {
this->profileList->mhzMap[profile][module] = hz / 1000000; this->profileList->mhzMap[profile][module] = hz / 1000000;
listItem->setValue(formatListFreqMHz(this->profileList->mhzMap[profile][module])); std::uint32_t mhz = this->profileList->mhzMap[profile][module];
listItem->setValue(module == HocClkModule_MEM ? formatListFreqMem(mhz, memUnit) : formatListFreqMHz(mhz));
Result rc = hocclkIpcSetProfiles(this->applicationId, this->profileList); Result rc = hocclkIpcSetProfiles(this->applicationId, this->profileList);
if(R_FAILED(rc)) if(R_FAILED(rc))
{ {
@@ -104,8 +107,10 @@ void AppProfileGui::openValueChoiceGui(
void AppProfileGui::addModuleListItem(HocClkProfile profile, HocClkModule module) void AppProfileGui::addModuleListItem(HocClkProfile profile, HocClkModule module)
{ {
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(hocclkFormatModule(module, true)); tsl::elm::ListItem* listItem = new tsl::elm::ListItem(hocclkFormatModule(module, true));
listItem->setValue(formatListFreqMHz(this->profileList->mhzMap[profile][module])); RamDisplayUnit memUnit = (RamDisplayUnit)configList.values[HocClkConfigValue_RamDisplayUnit];
listItem->setClickListener([this, listItem, profile, module](u64 keys) { std::uint32_t mhz = this->profileList->mhzMap[profile][module];
listItem->setValue(module == HocClkModule_MEM ? formatListFreqMem(mhz, memUnit) : formatListFreqMHz(mhz));
listItem->setClickListener([this, listItem, profile, module, memUnit](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A) if((keys & HidNpadButton_A) == HidNpadButton_A)
{ {
this->openFreqChoiceGui(listItem, profile, module); this->openFreqChoiceGui(listItem, profile, module);
@@ -115,7 +120,7 @@ void AppProfileGui::addModuleListItem(HocClkProfile profile, HocClkModule module
{ {
// Reset to "Default" (0 MHz) // Reset to "Default" (0 MHz)
this->profileList->mhzMap[profile][module] = 0; this->profileList->mhzMap[profile][module] = 0;
listItem->setValue(formatListFreqMHz(0)); listItem->setValue(module == HocClkModule_MEM ? formatListFreqMem(0, memUnit) : formatListFreqMHz(0));
Result rc = hocclkIpcSetProfiles(this->applicationId, this->profileList); Result rc = hocclkIpcSetProfiles(this->applicationId, this->profileList);
if(R_FAILED(rc)) if(R_FAILED(rc))
@@ -286,6 +291,9 @@ public:
: applicationId(appId), profileList(pList), profile(prof) {} : applicationId(appId), profileList(pList), profile(prof) {}
void listUI() override { void listUI() override {
BaseMenuGui::refresh(); // get latest context
if(!this->context)
return;
Result rc = hocclkIpcGetConfigValues(&configList); Result rc = hocclkIpcGetConfigValues(&configList);
if (R_FAILED(rc)) [[unlikely]] { if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc);
@@ -296,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] ? 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

@@ -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

@@ -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, 4, 8, 15); static constexpr tsl::Color dynamicLogoRGB1 = tsl::Color(7, 15, 15, 15);
static constexpr tsl::Color dynamicLogoRGB2 = tsl::Color(7, 15, 15, 15); static constexpr tsl::Color dynamicLogoRGB2 = tsl::Color(2, 8, 11, 15);
static constexpr tsl::Color STATIC_AQUA = tsl::Color(2, 10, 12, 15); static constexpr tsl::Color STATIC_TEAL = tsl::Color(7, 15, 15, 15);
const std::string name = "Horizon OC Zeus"; 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,26 +99,20 @@ 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);
b = std::clamp<u8>(b, 0, 15); b = std::clamp<u8>(b, 0, 15);
bool lightning = (fmod(timeNow, 5.0) < 0.15); // bool lightning = (fmod(timeNow, 5.0) < 0.15);
if (lightning) { // if (lightning) {
r = std::min<u8>(r + 4, 15); // r = std::min<u8>(r + 4, 15);
g = std::min<u8>(g + 4, 15); // g = std::min<u8>(g + 4, 15);
b = std::min<u8>(b + 15, 15); // b = std::min<u8>(b + 15, 15);
} // }
tsl::Color color(r, g, b, 15); tsl::Color color(r, g, b, 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_AQUA, 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

@@ -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,20 +24,24 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#include "../format.h"
#include "base_menu_gui.h" #include "base_menu_gui.h"
#include "fatal_gui.h" #include "fatal_gui.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();
@@ -48,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
static constexpr const char* const 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", "DISP", "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;
@@ -72,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);
@@ -89,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)
@@ -104,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
@@ -117,81 +128,80 @@ 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
renderer->drawString(labels[5], false, positions[5], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); renderer->drawString(labels[5], false, positions[5], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(labels[6], false, positions[6]-1, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); renderer->drawString(labels[6], false, positions[6], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(labels[7], false, positions[7], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); renderer->drawString(labels[7], false, positions[7], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
// Temperatures with color - use pre-computed colors // Temperatures with color - use pre-computed colors
renderer->drawString(displayStrings[11], false, dataPositions[0], 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); 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[13], false, positions[4], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // disp label renderer->drawString(labels[12], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // fan label
renderer->drawString(displayStrings[25], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp freq renderer->drawString(displayStrings[24], false, dataPositions[1] + 5, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // fan speed
renderer->drawString(labels[12], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // fan label renderer->drawString(labels[13], false, positions[4] + 4, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // disp label
renderer->drawString(displayStrings[24], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // fan speed 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], 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], 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], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // FPS label
renderer->drawString(displayStrings[26], false, dataPositions[2], 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;
@@ -201,7 +211,6 @@ void BaseMenuGui::refresh()
this->context = new HocClkContext; this->context = new HocClkContext;
} }
// === HOCCLK CONTEXT UPDATE ===
Result rc = hocclkIpcGetCurrentContext(this->context); Result rc = hocclkIpcGetCurrentContext(this->context);
if (R_FAILED(rc)) [[unlikely]] { if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("hocclkIpcGetCurrentContext", rc); FatalGui::openWithResultCode("hocclkIpcGetCurrentContext", rc);
@@ -223,35 +232,57 @@ 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
sprintf(displayStrings[4], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); std::uint32_t unit = configList.values[HocClkConfigValue_RamDisplayUnit];
std::uint32_t mhz = hz / 1000000U;
std::uint32_t mts = mhz * 2;
std::uint32_t tenth = (hz / 100000U) % 10U;
if (unit == RamDisplayUnit_MTs)
sprintf(displayStrings[4], "%u MT/s", mts);
else if (unit == RamDisplayUnit_MHz)
sprintf(displayStrings[4], "%u.%u MHz", mhz, tenth);
else if (unit == RamDisplayUnit_MHzMTs) {
hz = context->realFreqs[HocClkModule_MEM];
mhz = hz / 1000000U;
tenth = (hz / 100000U) % 10U;
sprintf(displayStrings[4], "%u.%u MHz", mhz, tenth);
}
// 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
sprintf(displayStrings[7], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); unit = configList.values[HocClkConfigValue_RamDisplayUnit];
mhz = hz / 1000000U;
mts = mhz * 2;
tenth = (hz / 100000U) % 10U;
if (unit == RamDisplayUnit_MTs || unit == RamDisplayUnit_MHzMTs)
sprintf(displayStrings[7], "%u MT/s", mts);
else
sprintf(displayStrings[7], "%u.%u MHz", mhz, tenth);
// Voltages // Voltages
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");
@@ -259,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);
@@ -275,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]));
@@ -302,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]));
@@ -322,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

@@ -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() { bool IsAula() {
if (!g_hardwareModelCached) { if (!g_hardwareModelCached) {
setsysGetProductModel(&HWmodel); setsysGetProductModel(&HWmodel);
g_hardwareModelCached = true; g_hardwareModelCached = true;
}
g_isAula = (HWmodel == SetSysProductModel_Aula);
return g_isAula;
} }
bool IsHoag() { g_isAula = (HWmodel == SetSysProductModel_Aula);
if (!g_hardwareModelCached) { return g_isAula;
setsysGetProductModel(&HWmodel); }
g_hardwareModelCached = true; bool IsHoag() {
} if (!g_hardwareModelCached) {
g_isHoag = (HWmodel == SetSysProductModel_Hoag); setsysGetProductModel(&HWmodel);
return g_isHoag; g_hardwareModelCached = true;
} }
bool IsMariko() { g_isHoag = (HWmodel == SetSysProductModel_Hoag);
if (!g_hardwareModelCached) { return g_isHoag;
setsysGetProductModel(&HWmodel); }
g_hardwareModelCached = true; bool IsMariko() {
} if (!g_hardwareModelCached) {
g_isMariko = (HWmodel == SetSysProductModel_Iowa || setsysGetProductModel(&HWmodel);
HWmodel == SetSysProductModel_Hoag || g_hardwareModelCached = true;
HWmodel == SetSysProductModel_Calcio || }
HWmodel == SetSysProductModel_Aula); g_isMariko = (HWmodel == SetSysProductModel_Iowa || HWmodel == SetSysProductModel_Hoag || HWmodel == SetSysProductModel_Calcio ||
HWmodel == SetSysProductModel_Aula);
return g_isMariko; return g_isMariko;
} }
bool IsErista() { bool IsErista() {
return !IsMariko(); return !IsMariko();
} }
BaseMenuGui(); BaseMenuGui();
~BaseMenuGui(); ~BaseMenuGui();
void preDraw(tsl::gfx::Renderer* renderer) override; void preDraw(tsl::gfx::Renderer *renderer) override;
tsl::elm::List* listElement; tsl::elm::List *listElement;
tsl::elm::Element* baseUI() override; tsl::elm::Element *baseUI() override;
void refresh() override; void refresh() override;
virtual void listUI() = 0; 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

@@ -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

@@ -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

@@ -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,17 +38,19 @@ 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 = formatListFreqHz(hz); if (module == HocClkModule_MEM)
text = formatListFreqHzMem(hz, (RamDisplayUnit)this->configList->values[HocClkConfigValue_RamDisplayUnit]);
else
text = formatListFreqHz(hz);
std::string rightText = ""; std::string rightText = "";
auto it = labels.find(hz); auto it = labels.find(hz);
@@ -63,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();
@@ -104,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
@@ -113,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;
@@ -155,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;
@@ -203,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("", "");

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