Compare commits

..

103 Commits
0.9.1 ... 0.9.4

Author SHA1 Message Date
Michael Scire
c62c4846fc Bump version to 0.9.4. 2019-09-14 10:43:39 -07:00
Michael Scire
8db5b01507 hbl_html: enforce line ending = lf (fixes broken whitelist) 2019-09-14 10:43:39 -07:00
Michael Scire
a6e405c988 ldr: fix hbl_html redirection invocation 2019-09-14 10:43:39 -07:00
Michael Scire
6613fda4b1 ams_mitm: add temporary hid mitm on 9.x for compat 2019-09-14 10:43:39 -07:00
Michael Scire
a18a6e87df git subrepo pull emummc
subrepo:
  subdir:   "emummc"
  merged:   "5f5817e6"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "5f5817e6"
git-subrepo:
  version:  "0.4.0"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "5d6aba9"
2019-09-14 10:43:39 -07:00
Michael Scire
93d83c5bb9 ams: initial support for 9.0.0 2019-09-14 10:43:39 -07:00
Michael Scire
6ee8720028 boot: fix pinmux init off-by-one 2019-08-29 00:18:40 -07:00
Michael Scire
600d68bd1a ams_mitm: fix bis key generation for newer hardware 2019-08-29 00:14:23 -07:00
hexkyz
0c3a294cbe Minor information update regarding previously unknown mysteries 2019-08-22 20:52:40 +01:00
Michael Scire
25218795b4 Bump version to 0.9.3 2019-08-08 18:06:21 -07:00
Michael Scire
a65ec67128 git subrepo push stratosphere/libstratosphere
subrepo:
  subdir:   "stratosphere/libstratosphere"
  merged:   "2d081135"
upstream:
  origin:   "https://github.com/Atmosphere-NX/libstratosphere"
  branch:   "master"
  commit:   "2d081135"
git-subrepo:
  version:  "0.4.0"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "5d6aba9"
2019-08-08 17:50:09 -07:00
Michael Scire
5d753f2384 Add default system settings for hbl applet support 2019-08-08 17:45:31 -07:00
Michael Scire
1f2de35f94 fatal: use new vi enum value 2019-08-07 13:02:02 -07:00
Michael Scire
5c140b4f35 dist: include fusee-mtc in release zips. 2019-08-05 19:37:02 -07:00
Michael Scire
362ee3cdb0 autobackup: dump bis keys (closes #583). 2019-08-05 19:35:04 -07:00
Michael Scire
215f1bc8ee fatal: fix abort in viSetDisplayPowerState on < 3.0.0 2019-08-05 18:55:04 -07:00
hexkyz
4d72c2b37a fusee-primary: force displaying of fatal errors 2019-07-31 20:01:01 +01:00
hexkyz
dc4dbe29ae Move memory training code into it's own stage (fusee-mtc) 2019-07-26 20:38:15 +01:00
TuxSH
72dd25a99e Fix uart init 2019-07-24 00:52:02 +02:00
Michael Scire
39d041466d fatal: refactor into sts namespace 2019-07-23 14:01:16 -07:00
Michael Scire
442ebff829 util: fix copy/paste error in intrusive lists 2019-07-23 14:01:16 -07:00
hexkyz
7e169bc7df pm: work around HOS bug 2019-07-23 19:38:14 +01:00
hexkyz
00f4e5158f Add missing dummy reads in gpio code 2019-07-23 18:33:34 +01:00
hexkyz
0c688189f6 Fix uart pinmux configuration 2019-07-21 21:21:13 +01:00
hexkyz
7cee36544c Cleanup and re-write uart code 2019-07-21 19:18:15 +01:00
hexkyz
f9c1d5fc1b Fix GPIO/SFIO defines: cosmetic change, gpio code was working properly despite the mistake 2019-07-21 15:55:40 +01:00
Michael Scire
d95e20952c kvdb: fix iterator access issue 2019-07-18 20:34:15 -07:00
Michael Scire
32a90334bb spl: rsa service does not need a dispatch table 2019-07-17 20:58:46 -07:00
Michael Scire
f534d3498e git subrepo clone https://github.com/Atmosphere-NX/libstratosphere stratosphere/libstratosphere
subrepo:
  subdir:   "stratosphere/libstratosphere"
  merged:   "0c5dab80"
upstream:
  origin:   "https://github.com/Atmosphere-NX/libstratosphere"
  branch:   "master"
  commit:   "0c5dab80"
git-subrepo:
  version:  "0.4.0"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "5d6aba9"
2019-07-17 20:04:00 -07:00
Michael Scire
3ea9f444db Remove libstratosphere submodule 2019-07-17 20:03:48 -07:00
TuxSH
5672c935ed Update libstratosphere submodule 2019-07-16 01:26:07 +02:00
Michael Scire
4cc2b5c38a creport: address review commentary 2019-07-15 14:35:48 -07:00
Michael Scire
00e3d874e3 creport: fix dangling reference to user_result 2019-07-15 14:35:48 -07:00
Michael Scire
803e91a8c4 creport: pass user break result directly 2019-07-15 14:35:48 -07:00
Michael Scire
227a1d938d creport: refactor to use sts:: namespace. 2019-07-15 14:35:48 -07:00
Michael Scire
fc7f06dc78 pm/sm: add ability to forward declare mitm'd services (closes #557) 2019-07-11 22:24:59 -07:00
Michael Scire
6777dd9b38 pm: inform sm of title ids. remove inconsistent mitm association. 2019-07-11 22:24:59 -07:00
Michael Scire
4db212ea7b pm: actually use the flag detection code in libstratosphere 2019-07-11 22:24:59 -07:00
Michael Scire
8177a27db9 pm: fix boot2 launch logic error 2019-07-11 22:24:59 -07:00
Michael Scire
27ff119ba6 pm: fix minor resource manager bugs 2019-07-11 22:24:59 -07:00
Michael Scire
c20774ff5d pm: fix missing flag clears 2019-07-11 22:24:59 -07:00
Michael Scire
a9f5b7728b pm: address review comments. 2019-07-11 22:24:59 -07:00
Michael Scire
08ad48fbf3 pm: implement correct application thread boosting mechanism 2019-07-11 22:24:59 -07:00
Michael Scire
2d0c881ffe strat: go all in on ncm::TitleId 2019-07-11 22:24:59 -07:00
Michael Scire
c916a7db88 strat: remove sizeof() / sizeof([0]) 2019-07-11 22:24:59 -07:00
Michael Scire
a5da286351 fix dumb mistake 2019-07-11 22:24:59 -07:00
Michael Scire
20a48c3a26 pm: complete rewrite 2019-07-11 22:24:59 -07:00
hexkyz
5bba0f47ff Merge pull request #625 from suppai/master
Fix compilation with latest libnx master
2019-07-08 16:56:54 +01:00
suppai
bfc987abcd Fix for libnx commit 4f441a4/latest master at time of writing 2019-07-07 23:56:21 -04:00
hexkyz
85bf7c86e0 fusee: cleanup and optimize boot sequence 2019-07-06 20:58:01 +01:00
Michael Scire
2225b86eea Adjust version string based on ReSwitched vote. 2019-07-02 11:49:24 -07:00
hexkyz
d09be18359 Fix argument type for isalnum and toupper 2019-07-02 17:22:28 +01:00
hexkyz
09ab3efddd Fix argument type for isspace 2019-07-01 20:29:43 +01:00
hexkyz
382a0192f9 Fix spacing in diskio 2019-07-01 20:20:34 +01:00
hexkyz
e3b968fa80 Update FatFs to R0.13c 2019-07-01 20:12:30 +01:00
Connor
6f85b11fcc Fix for 4.X units (new strato rework broke a method in spl) (#616)
* Fix for 4.X units (new strato rework broke a method in spl)

* Fixed formatting in spl
2019-07-01 03:53:46 -07:00
hexkyz
e561919a52 Fix logic in ldr_ro_manager
Fix argument type for isdigit/isxdigit
2019-06-30 18:48:16 +01:00
Michael Scire
b0a66a63ba Fix sept-secondary headers in fusee-secondary 2019-06-29 20:13:24 -07:00
Michael Scire
0d840e199d Bump version to 0.9.2. 2019-06-29 20:05:21 -07:00
Michael Scire
3a2bceef8d git subrepo pull emummc
subrepo:
  subdir:   "emummc"
  merged:   "5f51fa3b"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "5f51fa3b"
git-subrepo:
  version:  "0.4.0"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "5d6aba9"
2019-06-28 11:36:07 -07:00
hexkyz
e871a754a8 fusee: remove unnecessary prefix from emummc config keys 2019-06-28 16:35:18 +01:00
hexkyz
6333327b81 fusee: update partition based emummc sector detection 2019-06-28 16:34:04 +01:00
Michael Scire
18ca8aaf5b stratosphere: all in on enum class CommandId 2019-06-27 23:34:53 -07:00
SciresM
67c0f4527e Merge pull request #603 from Atmosphere-NX/ldr_rewrite
loader: completely rewrite.
2019-06-27 23:28:00 -07:00
Michael Scire
e5c5101e8a Add missing extension cleanup. 2019-06-27 20:51:57 -07:00
Michael Scire
934ff7bbde <int> -> <s32> 2019-06-27 20:16:56 -07:00
Michael Scire
014f08f6b4 ldr: fix mount check mistake 2019-06-27 18:01:44 -07:00
Michael Scire
6ba2090c01 ldr: address review commentary. 2019-06-27 17:37:33 -07:00
Michael Scire
61fcf5e0f4 loader: completely rewrite. 2019-06-26 15:46:19 -07:00
Michael Scire
9217e4c5f9 sm: add HasService/HasMitm, refactor into sts:: 2019-06-24 17:57:49 -07:00
SciresM
3ccbb34c62 Merge pull request #598 from Atmosphere-NX/ro_refactor
ro: refactor/rewrite into sts:: namespace
2019-06-24 15:40:45 -07:00
Michael Scire
9baa4a17ed ro: refactor/rewrite into sts:: namespace 2019-06-24 02:05:51 -07:00
SciresM
6bbece39bc Merge pull request #592 from Atmosphere-NX/boot_refactor
Refactor boot sysmodule to use sts::boot namespace.
2019-06-23 20:39:39 -07:00
hexkyz
729447eab0 fusee: cleanup and simplify emummc logic 2019-06-23 18:50:20 +01:00
Michael Scire
1e7f41ea9f boot: move updater into libstrat 2019-06-22 12:30:36 -07:00
Michael Scire
d0d4888184 boot/spl: update for spl-in-libstrat 2019-06-22 12:23:46 -07:00
Michael Scire
804e5d49bb boot: split out gpio, pinmux. 2019-06-22 11:34:18 -07:00
Michael Scire
6d1d226842 remove unnecessary sts:: prefixing 2019-06-22 00:14:24 -07:00
Michael Scire
06416aeded boot: refactor to use sts::boot namespace 2019-06-22 00:10:21 -07:00
Michael Scire
4fbae9e5a4 boot: move updater to sts::updater namespace 2019-06-21 21:06:04 -07:00
Michael Scire
c87be7cd69 boot: refactor i2c driver into namespace 2019-06-21 20:25:27 -07:00
SciresM
e62754ed56 Merge pull request #585 from Atmosphere-NX/sm_rewrite
Completely re-write sm.
2019-06-21 17:37:06 -07:00
Michael Scire
53d7281e66 sm: use enums for GetInfo 2019-06-21 17:37:01 -07:00
SciresM
731a2c11a4 Merge pull request #587 from Atmosphere-NX/spl_refactor
spl: refactor into sts namespace
2019-06-21 17:33:34 -07:00
hexkyz
ec4d078d6d fusee: fix emummc multipart device 2019-06-21 22:14:14 +01:00
Michael Scire
f9b48f06a3 spl: refactor into sts namespace 2019-06-21 01:36:00 -07:00
Michael Scire
d986ffa153 sm: use AutoHandles 2019-06-20 23:51:15 -07:00
Michael Scire
2357bc70a7 Implementation cleanup 2019-06-20 23:34:59 -07:00
Michael Scire
e86e1588e3 Simplify namespacing 2019-06-20 18:32:00 -07:00
Michael Scire
4be88c7180 sm: adjust Makefile 2019-06-20 18:24:35 -07:00
Michael Scire
8e8daa64ba sm: completely rewrite module 2019-06-20 18:23:40 -07:00
Michael Scire
1671c04e24 stratosphere: prefer static waitable managers 2019-06-20 13:15:39 -07:00
Michael Scire
d3d6c552b7 stratosphere: remove trailing whitespace 2019-06-20 13:00:32 -07:00
Michael Scire
8d9336f561 git subrepo clone --branch=develop --force https://github.com/m4xw/emuMMC emummc
subrepo:
  subdir:   "emummc"
  merged:   "e935968d"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "e935968d"
git-subrepo:
  version:  "0.4.0"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "5d6aba9"
2019-06-20 12:41:50 -07:00
Michael Scire
169ec9c12e Update libstrat 2019-06-20 05:01:42 -07:00
Michael Scire
60b831f369 ams_mitm: refactor for R_TRY 2019-06-20 04:04:33 -07:00
Michael Scire
4191dcee75 dmnt: fix missing init 2019-06-20 04:04:11 -07:00
Michael Scire
44725c8910 sm: refactor mitm service handle acquisition 2019-06-20 02:21:01 -07:00
Michael Scire
cead8a36ea stratosphere: more result cleanup 2019-06-20 02:00:59 -07:00
Michael Scire
7b6050a0cb boot: refactor for R_TRY 2019-06-20 00:57:17 -07:00
Michael Scire
491383c637 dmnt: trailing whitespace 2019-06-19 22:20:44 -07:00
Michael Scire
d7a3645f7f dmnt: update for R_TRY 2019-06-19 22:19:53 -07:00
Michael Scire
241b8f4627 fusee: fix config init/ini read order 2019-06-19 20:28:06 -07:00
757 changed files with 128259 additions and 93370 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
common/defaults/hbl_html/accessible-urls/accessible-urls.txt text eol=lf

3
.gitmodules vendored
View File

@@ -1,6 +1,3 @@
[submodule "common/include/boost"]
path = common/include/boost
url = https://github.com/Atmosphere-NX/ext-boost.git
[submodule "stratosphere/libstratosphere"]
path = stratosphere/libstratosphere
url = https://github.com/Atmosphere-NX/libstratosphere.git

View File

@@ -57,6 +57,7 @@ dist: all
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000037
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/sept/payload.bin
cp sept/sept-primary/sept-primary.bin atmosphere-$(AMSVER)/sept/sept-primary.bin

View File

@@ -1,6 +1,7 @@
BCT0
[stage1]
stage2_path = atmosphere/fusee-secondary.bin
stage2_mtc_path = atmosphere/fusee-mtc.bin
stage2_addr = 0xF0000000
stage2_entrypoint = 0xF0000000

View File

@@ -16,7 +16,7 @@ fatal_auto_reboot_interval = u64!0x0
; Make the power menu's "reboot" button reboot to payload.
; Set to "normal" for normal reboot, "rcm" for rcm reboot.
power_menu_reboot_function = str!payload
; Controls whether dmnt cheats should be toggled on or off by
; Controls whether dmnt cheats should be toggled on or off by
; default. 1 = toggled on by default, 0 = toggled off by default.
dmnt_cheats_enabled_by_default = u8!0x1
; Controls whether dmnt should always save cheat toggle state
@@ -28,4 +28,13 @@ dmnt_always_save_cheat_toggles = u8!0x0
; 0 = Do not redirect, 1 = Redirect.
; NOTE: EXPERIMENTAL
; If you do not know what you are doing, do not touch this yet.
fsmitm_redirect_saves_to_sd = u8!0x0
fsmitm_redirect_saves_to_sd = u8!0x0
[hbloader]
; Controls the size of the homebrew heap when running as applet.
; If set to zero, all available applet memory is used as heap.
; The default is zero.
applet_heap_size = u64!0x0
; Controls the amount of memory to reserve when running as applet
; for usage by other applets. This setting has no effect if
; applet_heap_size is non-zero. The default is zero.
applet_heap_reservation_size = u64!0x8000000

View File

@@ -27,11 +27,12 @@
#define ATMOSPHERE_TARGET_FIRMWARE_700 8
#define ATMOSPHERE_TARGET_FIRMWARE_800 9
#define ATMOSPHERE_TARGET_FIRMWARE_810 10
#define ATMOSPHERE_TARGET_FIRMWARE_900 11
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_810
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_900
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE_100
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_810
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_900
/* TODO: What should this be, for release? */
#define ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG ATMOSPHERE_TARGET_FIRMWARE_CURRENT

View File

@@ -19,10 +19,10 @@
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
#define ATMOSPHERE_RELEASE_VERSION_MINOR 9
#define ATMOSPHERE_RELEASE_VERSION_MICRO 1
#define ATMOSPHERE_RELEASE_VERSION_MICRO 4
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 8
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 1
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 9
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0
#endif

View File

@@ -1,4 +1,69 @@
# Changelog
## 0.9.4
+ Support was added for 9.0.0.
+ **Please note**: 9.0.0 made a number of changes that may cause some issues with homebrew. Details:
+ 9.0.0 changed HID in a way that causes libnx to be unable to detect button input.
+ Homebrew should be recompiled with newest libnx to fix this.
+ Atmosphere now provides a temporary hid-mitm that will cause homebrew to continue to work as expected.
+ This mitm will be removed in a future Atmosphere revision once homebrew has been updated, to allow users to use a custom hid mitm again if they desire.
+ 9.0.0 introduced an dependency in FS on the USB system module in order to launch the SD card.
+ This means the USB system module must now be launched before the SD card is initialized.
+ Correspondingly, the USB system module can no longer be IPS patched, and its settings cannot be reliably mitm'd.
+ We know this is frustrating, so we'll be looking into whether there is some way of addressing this in the future.
+ An off-by-one error was fixed in `boot` system module's pinmux initialization.
+ This could theoretically have caused issues with HdmiCec communication.
+ No users reported issues, so it's unclear if this was a problem in practice.
+ A bug was fixed that could cause webapplet launching homebrew to improperly set the accessible url whitelist.
+ BIS key generation has been fixed for newer hardware.
+ Newer hardware uses new, per-firmware device key to generate BIS keys instead of the first device key, so previously the wrong keys were generated as backup.
+ This only affects units manufactured after ~5.0.0.
+ General system stability improvements to enhance the user's experience.
## 0.9.3
+ Thanks to hexkyz, fusee's boot sequence has been greatly optimized.
+ Memory training is now managed by a separate binary (`fusee-mtc`, loaded by fusee-primary before fusee-secondary).
+ Unnecessarily long splash screen display times were reduced.
+ The end result is that Atmosphere now boots *significantly* faster. :)
+ **Note:** This means fusee-primary must be updated for Atmosphere to boot successfully.
+ The version string was adjusted, and now informs users whether or not they are using emummc.
+ Atmosphere now automatically backs up the user's BIS keys on boot.
+ This should prevent a user from corrupting nand without access to a copy of the keys needed to fix it.
+ This is especially relevant on ipatched units, where the RCM vulnerability is not an option for addressing bricks.
+ The `pm` system module was rewritten as part of Stratosphere's ongoing refactor.
+ Support was added for forward-declaring a mitm'd service before a custom user sysmodule is launched.
+ This should help resolve dependency issues with service registration times.
+ SM is now informed of every process's title id, including built-in system modules.
+ The `creport` system module was rewritten as part of Stratosphere's ongoing refactor.
+ creport now dumps up to 0x100 of stack from each thread in the target process.
+ A few bugs were fixed, including one that caused creport to incorrectly dump process dying messages.
+ Defaults were added to `system_settings.ini` for controlling hbloader's memory usage in applet mode.
+ These defaults reserve enough memory so that homebrew can launch swkbd while in applet mode.
+ The `fatal` system module was rewritten as part of Stratosphere's ongoing refactor.
+ Incorrect display output ("2000-0000") has been fixed. Fatal will now correctly show 2162-0002 when this occurs.
+ A longstanding bug in how fatal manages the displays has been fixed, and official display init behavior is now matched precisely.
+ General system stability improvements to enhance the user's experience.
## 0.9.2
+ A number of emummc bugfixes were added (all thanks to @m4xw's hard work). The following is a summary of emummc changes:
+ Support for file-based emummc instances was fixed.
+ Please note: file-based emummc is still unoptimized, and so may be much slower than partition-based.
+ This speed differential should hopefully be made better in a future emummc update.
+ The way emummc handles power management was completely overhauled.
+ Emummc now properly handles init/de-init, and now supports low voltage mode.
+ Much better support for shutdown was added, which should assuage corruption/synchronization problems.
+ This should also improve support for more types of SD cards.
+ A bug was fixed that caused emummc to not work on lower system versions due to missing SVC access.
+ **Please note**: The configuration entries used for emummc have been changed.
+ `emummc_` prefixes have been removed, since they are superfluous given the `emummc` category they are under.
+ As an example, `emummc!emummc_enabled` is now `emummc!enabled`.
+ INI configurations made by @CTCaer's [tool](https://github.com/ctcaer/hekate/releases/latest) (which is the recommended way to manage emummc) should automatically work as expected/be corrected.
+ **If you do not wish to use the above, you will need to manually correct your configuration file**.
+ General system stability improvements to enhance the user's experience.
+ Stratosphere is currently in the process of being re-written/refactored.
+ Stratosphere was my (SciresM's) first C++ project, ever -- the code written for it a year ago when I was learning C++ is/was of much lower quality than code written more recently.
+ Code is thus being re-rwitten for clarity/stlye/to de-duplicate functionality, with much being moved into libstratosphere.
+ Stratosphere will, after the rewrite, globally use the `sts::` namespace -- this should greatly enhancing libstratosphere's ability to provide functionality for system modules.
+ The rewritten modules consistently have lower memory footprints, and should be easier to maintain going forwards.
+ The `sm`, `boot`, `spl`, `ro`, and `loader` modules have been tackled so far.
+ General system stability improvements to enhance the user's experience.
## 0.9.1
+ Support was added for 8.1.0.
+ Please note, emummc is still considered **beta/experimental** -- this is not the inevitable bugfix update for it, although some number of bugs have been fixed. :)

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/m4xw/emuMMC
branch = develop
commit = e7799388e8d3de17fd178ffe310be2e81ef46d6f
parent = f2086fe05492cb523b60fa10e4425c4ea59521b3
commit = 5f5817e646d4c800ae4bd6db4a57eee6bde62eed
parent = 68091a28a23836032c98396259f7ee4796b312f9
method = rebase
cmdver = 0.4.0

View File

@@ -2,7 +2,7 @@
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
### Supported Horizon Versions
**1.0.0 - 8.0.1**
**1.0.0 - 9.0.0**
## Features
* Arbitrary SDMMC backend selection

View File

@@ -116,6 +116,7 @@
"svcReplyAndReceive": "0x43",
"svcReplyAndReceiveWithUserBuffer": "0x44",
"svcCreateEvent": "0x45",
"svcReadWriteRegister": "0x4E",
"svcCreateInterruptEvent": "0x53",
"svcQueryIoMapping": "0x55",
"svcCreateDeviceAddressSpace": "0x56",

View File

@@ -41,29 +41,31 @@
#include "offsets/800_exfat.h"
#include "offsets/810.h"
#include "offsets/810_exfat.h"
#include "offsets/900.h"
#include "offsets/900_exfat.h"
#include "../utils/fatal.h"
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
#define DEFINE_OFFSET_STRUCT(vers) \
static const fs_offsets_t GET_OFFSET_STRUCT_NAME(vers) = { \
.sdmmc_accessor_gc = FS_OFFSET##vers##_SDMMC_ACCESSOR_GC, \
.sdmmc_accessor_sd = FS_OFFSET##vers##_SDMMC_ACCESSOR_SD, \
.sdmmc_accessor_nand = FS_OFFSET##vers##_SDMMC_ACCESSOR_NAND, \
.sdmmc_wrapper_read = FS_OFFSET##vers##_SDMMC_WRAPPER_READ, \
.sdmmc_wrapper_write = FS_OFFSET##vers##_SDMMC_WRAPPER_WRITE, \
.clkrst_set_min_v_clock_rate = FS_OFFSET##vers##_CLKRST_SET_MIN_V_CLK_RATE, \
.rtld = FS_OFFSET##vers##_RTLD, \
.rtld_destination = FS_OFFSET##vers##_RTLD_DESTINATION, \
.lock_mutex = FS_OFFSET##vers##_LOCK_MUTEX, \
.unlock_mutex = FS_OFFSET##vers##_UNLOCK_MUTEX, \
.sd_mutex = FS_OFFSET##vers##_SD_MUTEX, \
.nand_mutex = FS_OFFSET##vers##_NAND_MUTEX, \
.active_partition = FS_OFFSET##vers##_ACTIVE_PARTITION, \
.sdmmc_das_handle = FS_OFFSET##vers##_SDMMC_DAS_HANDLE, \
.shutdown_sd = FS_OFFSET##vers##_SHUTDOWN_SD, \
.sd_das_init = FS_OFFSET##vers##_SD_DAS_INIT, \
.nintendo_paths = FS_OFFSET##vers##_NINTENDO_PATHS, \
.sdmmc_accessor_gc = FS_OFFSET##vers##_SDMMC_ACCESSOR_GC, \
.sdmmc_accessor_sd = FS_OFFSET##vers##_SDMMC_ACCESSOR_SD, \
.sdmmc_accessor_nand = FS_OFFSET##vers##_SDMMC_ACCESSOR_NAND, \
.sdmmc_wrapper_read = FS_OFFSET##vers##_SDMMC_WRAPPER_READ, \
.sdmmc_wrapper_write = FS_OFFSET##vers##_SDMMC_WRAPPER_WRITE, \
.clkrst_set_min_v_clock_rate = FS_OFFSET##vers##_CLKRST_SET_MIN_V_CLK_RATE, \
.rtld = FS_OFFSET##vers##_RTLD, \
.rtld_destination = FS_OFFSET##vers##_RTLD_DESTINATION, \
.lock_mutex = FS_OFFSET##vers##_LOCK_MUTEX, \
.unlock_mutex = FS_OFFSET##vers##_UNLOCK_MUTEX, \
.sd_mutex = FS_OFFSET##vers##_SD_MUTEX, \
.nand_mutex = FS_OFFSET##vers##_NAND_MUTEX, \
.active_partition = FS_OFFSET##vers##_ACTIVE_PARTITION, \
.sdmmc_das_handle = FS_OFFSET##vers##_SDMMC_DAS_HANDLE, \
.sdmmc_accessor_controller_close = FS_OFFSET##vers##_SDMMC_WRAPPER_CONTROLLER_CLOSE, \
.sd_das_init = FS_OFFSET##vers##_SD_DAS_INIT, \
.nintendo_paths = FS_OFFSET##vers##_NINTENDO_PATHS, \
}
// Actually define offset structs
@@ -92,6 +94,8 @@ DEFINE_OFFSET_STRUCT(_800);
DEFINE_OFFSET_STRUCT(_800_EXFAT);
DEFINE_OFFSET_STRUCT(_810);
DEFINE_OFFSET_STRUCT(_810_EXFAT);
DEFINE_OFFSET_STRUCT(_900);
DEFINE_OFFSET_STRUCT(_900_EXFAT);
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
switch (version) {
@@ -145,6 +149,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
return &(GET_OFFSET_STRUCT_NAME(_810));
case FS_VER_8_1_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_810_EXFAT));
case FS_VER_9_0_0:
return &(GET_OFFSET_STRUCT_NAME(_900));
case FS_VER_9_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_900_EXFAT));
default:
fatal_abort(Fatal_UnknownVersion);
}

View File

@@ -41,13 +41,13 @@ typedef struct {
// Misc funcs
uintptr_t lock_mutex;
uintptr_t unlock_mutex;
uintptr_t sdmmc_accessor_controller_close;
// Misc data
uintptr_t sd_mutex;
uintptr_t nand_mutex;
uintptr_t active_partition;
uintptr_t sdmmc_das_handle;
// NOPs
uintptr_t shutdown_sd;
uintptr_t sd_das_init;
// Nintendo Paths
fs_offsets_nintendo_path_t nintendo_paths[];

View File

@@ -36,7 +36,7 @@ typedef struct sdmmc_accessor_vt
void *map_device_addr_space;
void *unmap_device_addr_space;
void *controller_open;
void *controller_close;
uint64_t (*sdmmc_accessor_controller_close)(void *);
uint64_t (*read_write)(void *, uint64_t, uint64_t, void *, uint64_t, uint64_t);
// More not included because we don't use it.
} sdmmc_accessor_vt_t;

View File

@@ -59,6 +59,9 @@ enum FS_VER
FS_VER_8_1_0,
FS_VER_8_1_0_EXFAT,
FS_VER_9_0_0,
FS_VER_9_0_0_EXFAT,
FS_VER_MAX,
};

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_100_LOCK_MUTEX 0x2884
#define FS_OFFSET_100_UNLOCK_MUTEX 0x28F0
#define FS_OFFSET_100_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x6A8AC
// Misc Data
#define FS_OFFSET_100_SD_MUTEX 0xE36058
#define FS_OFFSET_100_NAND_MUTEX 0xE30610
@@ -41,7 +43,6 @@
#define FS_OFFSET_100_SDMMC_DAS_HANDLE 0xE2F730
// NOPs
#define FS_OFFSET_100_SHUTDOWN_SD 0x22548
#define FS_OFFSET_100_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_200_LOCK_MUTEX 0x3264
#define FS_OFFSET_200_UNLOCK_MUTEX 0x32D0
#define FS_OFFSET_200_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4
// Misc Data
#define FS_OFFSET_200_SD_MUTEX 0xE42268
#define FS_OFFSET_200_NAND_MUTEX 0xE3CED0
@@ -41,7 +43,6 @@
#define FS_OFFSET_200_SDMMC_DAS_HANDLE 0xE3BDD0
// NOPs
#define FS_OFFSET_200_SHUTDOWN_SD 0x20C48
#define FS_OFFSET_200_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_200_EXFAT_LOCK_MUTEX 0x3264
#define FS_OFFSET_200_EXFAT_UNLOCK_MUTEX 0x32D0
#define FS_OFFSET_200_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4
// Misc Data
#define FS_OFFSET_200_EXFAT_SD_MUTEX 0xF22268
#define FS_OFFSET_200_EXFAT_NAND_MUTEX 0xF1CED0
@@ -41,7 +43,6 @@
#define FS_OFFSET_200_EXFAT_SDMMC_DAS_HANDLE 0xF1BDD0
// NOPs
#define FS_OFFSET_200_EXFAT_SHUTDOWN_SD 0x20C48
#define FS_OFFSET_200_EXFAT_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_210_LOCK_MUTEX 0x3264
#define FS_OFFSET_210_UNLOCK_MUTEX 0x32D0
#define FS_OFFSET_210_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4
// Misc Data
#define FS_OFFSET_210_SD_MUTEX 0xE43268
#define FS_OFFSET_210_NAND_MUTEX 0xE3DED0
@@ -41,7 +43,6 @@
#define FS_OFFSET_210_SDMMC_DAS_HANDLE 0xE3CDD0
// NOPs
#define FS_OFFSET_210_SHUTDOWN_SD 0x20E60
#define FS_OFFSET_210_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_210_EXFAT_LOCK_MUTEX 0x3264
#define FS_OFFSET_210_EXFAT_UNLOCK_MUTEX 0x32D0
#define FS_OFFSET_210_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4
// Misc Data
#define FS_OFFSET_210_EXFAT_SD_MUTEX 0xF22268
#define FS_OFFSET_210_EXFAT_NAND_MUTEX 0xF1CED0
@@ -41,7 +43,6 @@
#define FS_OFFSET_210_EXFAT_SDMMC_DAS_HANDLE 0xF1BDD0
// NOPs
#define FS_OFFSET_210_EXFAT_SHUTDOWN_SD 0x20E60
#define FS_OFFSET_210_EXFAT_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_300_LOCK_MUTEX 0x35CC
#define FS_OFFSET_300_UNLOCK_MUTEX 0x3638
#define FS_OFFSET_300_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270
// Misc Data
#define FS_OFFSET_300_SD_MUTEX 0xE69268
#define FS_OFFSET_300_NAND_MUTEX 0xE646F0
@@ -41,7 +43,6 @@
#define FS_OFFSET_300_SDMMC_DAS_HANDLE 0xE635A0
// NOPs
#define FS_OFFSET_300_SHUTDOWN_SD 0x258D8
#define FS_OFFSET_300_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_300_EXFAT_LOCK_MUTEX 0x35CC
#define FS_OFFSET_300_EXFAT_UNLOCK_MUTEX 0x3638
#define FS_OFFSET_300_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270
// Misc Data
#define FS_OFFSET_300_EXFAT_SD_MUTEX 0xF4C268
#define FS_OFFSET_300_EXFAT_NAND_MUTEX 0xF476F0
@@ -41,7 +43,6 @@
#define FS_OFFSET_300_EXFAT_SDMMC_DAS_HANDLE 0xF465A0
// NOPs
#define FS_OFFSET_300_EXFAT_SHUTDOWN_SD 0x258D8
#define FS_OFFSET_300_EXFAT_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_301_LOCK_MUTEX 0x3638
#define FS_OFFSET_301_UNLOCK_MUTEX 0x36A4
#define FS_OFFSET_301_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C
// Misc Data
#define FS_OFFSET_301_SD_MUTEX 0xE69268
#define FS_OFFSET_301_NAND_MUTEX 0xE646F0
@@ -41,7 +43,6 @@
#define FS_OFFSET_301_SDMMC_DAS_HANDLE 0xE635A0
// NOPs
#define FS_OFFSET_301_SHUTDOWN_SD 0x25944
#define FS_OFFSET_301_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_301_EXFAT_LOCK_MUTEX 0x3638
#define FS_OFFSET_301_EXFAT_UNLOCK_MUTEX 0x36A4
#define FS_OFFSET_301_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C
// Misc Data
#define FS_OFFSET_301_EXFAT_SD_MUTEX 0xF4C268
#define FS_OFFSET_301_EXFAT_NAND_MUTEX 0xF476F0
@@ -41,7 +43,6 @@
#define FS_OFFSET_301_EXFAT_SDMMC_DAS_HANDLE 0xF465A0
// NOPs
#define FS_OFFSET_301_EXFAT_SHUTDOWN_SD 0x25944
#define FS_OFFSET_301_EXFAT_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_400_LOCK_MUTEX 0x39A0
#define FS_OFFSET_400_UNLOCK_MUTEX 0x3A0C
#define FS_OFFSET_400_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48
// Misc Data
#define FS_OFFSET_400_SD_MUTEX 0xE80268
#define FS_OFFSET_400_NAND_MUTEX 0xE7BC60
@@ -41,7 +43,6 @@
#define FS_OFFSET_400_SDMMC_DAS_HANDLE 0xE7ABF0
// NOPs
#define FS_OFFSET_400_SHUTDOWN_SD 0x32D70
#define FS_OFFSET_400_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_400_EXFAT_LOCK_MUTEX 0x39A0
#define FS_OFFSET_400_EXFAT_UNLOCK_MUTEX 0x3A0C
#define FS_OFFSET_400_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48
// Misc Data
#define FS_OFFSET_400_EXFAT_SD_MUTEX 0xF63268
#define FS_OFFSET_400_EXFAT_NAND_MUTEX 0xF5EC60
@@ -41,7 +43,6 @@
#define FS_OFFSET_400_EXFAT_SDMMC_DAS_HANDLE 0xF5DBF0
// NOPs
#define FS_OFFSET_400_EXFAT_SHUTDOWN_SD 0x32D70
#define FS_OFFSET_400_EXFAT_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_410_LOCK_MUTEX 0x39A0
#define FS_OFFSET_410_UNLOCK_MUTEX 0x3A0C
#define FS_OFFSET_410_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC
// Misc Data
#define FS_OFFSET_410_SD_MUTEX 0xE80268
#define FS_OFFSET_410_NAND_MUTEX 0xE7BC60
@@ -41,7 +43,6 @@
#define FS_OFFSET_410_SDMMC_DAS_HANDLE 0xE7ABF0
// NOPs
#define FS_OFFSET_410_SHUTDOWN_SD 0x32D70
#define FS_OFFSET_410_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_410_EXFAT_LOCK_MUTEX 0x39A0
#define FS_OFFSET_410_EXFAT_UNLOCK_MUTEX 0x3A0C
#define FS_OFFSET_410_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC
// Misc Data
#define FS_OFFSET_410_EXFAT_SD_MUTEX 0xF63268
#define FS_OFFSET_410_EXFAT_NAND_MUTEX 0xF5EC60
@@ -41,7 +43,6 @@
#define FS_OFFSET_410_EXFAT_SDMMC_DAS_HANDLE 0xF5DBF0
// NOPs
#define FS_OFFSET_410_EXFAT_SHUTDOWN_SD 0x32D70
#define FS_OFFSET_410_EXFAT_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_500_LOCK_MUTEX 0x4080
#define FS_OFFSET_500_UNLOCK_MUTEX 0x40D0
#define FS_OFFSET_500_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380
// Misc Data
#define FS_OFFSET_500_SD_MUTEX 0xEC3268
#define FS_OFFSET_500_NAND_MUTEX 0xEBDE58
@@ -41,7 +43,6 @@
#define FS_OFFSET_500_SDMMC_DAS_HANDLE 0xEBCE30
// NOPs
#define FS_OFFSET_500_SHUTDOWN_SD 0x443E8
#define FS_OFFSET_500_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_500_EXFAT_LOCK_MUTEX 0x4080
#define FS_OFFSET_500_EXFAT_UNLOCK_MUTEX 0x40D0
#define FS_OFFSET_500_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380
// Misc Data
#define FS_OFFSET_500_EXFAT_SD_MUTEX 0xFA8268
#define FS_OFFSET_500_EXFAT_NAND_MUTEX 0xFA2E58
@@ -41,7 +43,6 @@
#define FS_OFFSET_500_EXFAT_SDMMC_DAS_HANDLE 0xFA1E30
// NOPs
#define FS_OFFSET_500_EXFAT_SHUTDOWN_SD 0x443E8
#define FS_OFFSET_500_EXFAT_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_510_LOCK_MUTEX 0x4080
#define FS_OFFSET_510_UNLOCK_MUTEX 0x40D0
#define FS_OFFSET_510_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750
// Misc Data
#define FS_OFFSET_510_SD_MUTEX 0xEC4268
#define FS_OFFSET_510_NAND_MUTEX 0xEBEE58
@@ -41,7 +43,6 @@
#define FS_OFFSET_510_SDMMC_DAS_HANDLE 0xEBDE30
// NOPs
#define FS_OFFSET_510_SHUTDOWN_SD 0x44578
#define FS_OFFSET_510_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_510_EXFAT_LOCK_MUTEX 0x4080
#define FS_OFFSET_510_EXFAT_UNLOCK_MUTEX 0x40D0
#define FS_OFFSET_510_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750
// Misc Data
#define FS_OFFSET_510_EXFAT_SD_MUTEX 0xFA9268
#define FS_OFFSET_510_EXFAT_NAND_MUTEX 0xFA3E58
@@ -41,7 +43,6 @@
#define FS_OFFSET_510_EXFAT_SDMMC_DAS_HANDLE 0xFA2E30
// NOPs
#define FS_OFFSET_510_EXFAT_SHUTDOWN_SD 0x44578
#define FS_OFFSET_510_EXFAT_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_600_LOCK_MUTEX 0x1412C0
#define FS_OFFSET_600_UNLOCK_MUTEX 0x141310
#define FS_OFFSET_600_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x148500
// Misc Data
#define FS_OFFSET_600_SD_MUTEX 0xF06268
#define FS_OFFSET_600_NAND_MUTEX 0xF01BA0
@@ -41,7 +43,6 @@
#define FS_OFFSET_600_SDMMC_DAS_HANDLE 0xE01670
// NOPs
#define FS_OFFSET_600_SHUTDOWN_SD 0xB2F28
#define FS_OFFSET_600_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_600_EXFAT_LOCK_MUTEX 0x14C9C0
#define FS_OFFSET_600_EXFAT_UNLOCK_MUTEX 0x14CA10
#define FS_OFFSET_600_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x153C00
// Misc Data
#define FS_OFFSET_600_EXFAT_SD_MUTEX 0xFEB268
#define FS_OFFSET_600_EXFAT_NAND_MUTEX 0xFE6BA0
@@ -41,7 +43,6 @@
#define FS_OFFSET_600_EXFAT_SDMMC_DAS_HANDLE 0xEE6670
// NOPs
#define FS_OFFSET_600_EXFAT_SHUTDOWN_SD 0xBE628
#define FS_OFFSET_600_EXFAT_SD_DAS_INIT 0x0
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_700_LOCK_MUTEX 0x148A90
#define FS_OFFSET_700_UNLOCK_MUTEX 0x148AE0
#define FS_OFFSET_700_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14FD50
// Misc Data
#define FS_OFFSET_700_SD_MUTEX 0xF123E8
#define FS_OFFSET_700_NAND_MUTEX 0xF0DBE8
@@ -41,7 +43,6 @@
#define FS_OFFSET_700_SDMMC_DAS_HANDLE 0xE0E7A0
// NOPs
#define FS_OFFSET_700_SHUTDOWN_SD 0xB8FCC
#define FS_OFFSET_700_SD_DAS_INIT 0x85FE8
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_700_EXFAT_LOCK_MUTEX 0x154040
#define FS_OFFSET_700_EXFAT_UNLOCK_MUTEX 0x154090
#define FS_OFFSET_700_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15B300
// Misc Data
#define FS_OFFSET_700_EXFAT_SD_MUTEX 0xFF73E8
#define FS_OFFSET_700_EXFAT_NAND_MUTEX 0xFF2BE8
@@ -41,7 +43,6 @@
#define FS_OFFSET_700_EXFAT_SDMMC_DAS_HANDLE 0xEF3A00
// NOPs
#define FS_OFFSET_700_EXFAT_SHUTDOWN_SD 0xC457C
#define FS_OFFSET_700_EXFAT_SD_DAS_INIT 0x91598
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_800_LOCK_MUTEX 0x14B6D0
#define FS_OFFSET_800_UNLOCK_MUTEX 0x14B720
#define FS_OFFSET_800_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0
// Misc Data
#define FS_OFFSET_800_SD_MUTEX 0xF1A3E8
#define FS_OFFSET_800_NAND_MUTEX 0xF15BE8
@@ -41,7 +43,6 @@
#define FS_OFFSET_800_SDMMC_DAS_HANDLE 0xE167C0
// NOPs
#define FS_OFFSET_800_SHUTDOWN_SD 0xBAF6C
#define FS_OFFSET_800_SD_DAS_INIT 0x87D58
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_800_EXFAT_LOCK_MUTEX 0x156C80
#define FS_OFFSET_800_EXFAT_UNLOCK_MUTEX 0x156CD0
#define FS_OFFSET_800_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90
// Misc Data
#define FS_OFFSET_800_EXFAT_SD_MUTEX 0xFFE3E8
#define FS_OFFSET_800_EXFAT_NAND_MUTEX 0xFF9BE8
@@ -41,7 +43,6 @@
#define FS_OFFSET_800_EXFAT_SDMMC_DAS_HANDLE 0xEFAA20
// NOPs
#define FS_OFFSET_800_EXFAT_SHUTDOWN_SD 0xC651C
#define FS_OFFSET_800_EXFAT_SD_DAS_INIT 0x93308
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_810_LOCK_MUTEX 0x14B6D0
#define FS_OFFSET_810_UNLOCK_MUTEX 0x14B720
#define FS_OFFSET_810_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0
// Misc Data
#define FS_OFFSET_810_SD_MUTEX 0xF1A3E8
#define FS_OFFSET_810_NAND_MUTEX 0xF15BE8
@@ -41,7 +43,6 @@
#define FS_OFFSET_810_SDMMC_DAS_HANDLE 0xE167C0
// NOPs
#define FS_OFFSET_810_SHUTDOWN_SD 0xBAF6C
#define FS_OFFSET_810_SD_DAS_INIT 0x87D58
// Nintendo Paths

View File

@@ -34,6 +34,8 @@
#define FS_OFFSET_810_EXFAT_LOCK_MUTEX 0x156C80
#define FS_OFFSET_810_EXFAT_UNLOCK_MUTEX 0x156CD0
#define FS_OFFSET_810_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90
// Misc Data
#define FS_OFFSET_810_EXFAT_SD_MUTEX 0xFFE3E8
#define FS_OFFSET_810_EXFAT_NAND_MUTEX 0xFF9BE8
@@ -41,7 +43,6 @@
#define FS_OFFSET_810_EXFAT_SDMMC_DAS_HANDLE 0xEFAA20
// NOPs
#define FS_OFFSET_810_EXFAT_SHUTDOWN_SD 0xC651C
#define FS_OFFSET_810_EXFAT_SD_DAS_INIT 0x93308
// Nintendo Paths

View File

@@ -0,0 +1,59 @@
/*
* 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/>.
*/
#ifndef __FS_900_H__
#define __FS_900_H__
// Accessor vtable getters
#define FS_OFFSET_900_SDMMC_ACCESSOR_GC 0x1430F0
#define FS_OFFSET_900_SDMMC_ACCESSOR_SD 0x141200
#define FS_OFFSET_900_SDMMC_ACCESSOR_NAND 0x13C080
// Hooks
#define FS_OFFSET_900_SDMMC_WRAPPER_READ 0x1377E0
#define FS_OFFSET_900_SDMMC_WRAPPER_WRITE 0x1378C0
#define FS_OFFSET_900_RTLD 0x454
#define FS_OFFSET_900_RTLD_DESTINATION 0x9C
#define FS_OFFSET_900_CLKRST_SET_MIN_V_CLK_RATE 0x136A00
// Misc funcs
#define FS_OFFSET_900_LOCK_MUTEX 0x25280
#define FS_OFFSET_900_UNLOCK_MUTEX 0x252D0
#define FS_OFFSET_900_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
// Misc Data
#define FS_OFFSET_900_SD_MUTEX 0xE1D3E8
#define FS_OFFSET_900_NAND_MUTEX 0xE18258
#define FS_OFFSET_900_ACTIVE_PARTITION 0xE18298
#define FS_OFFSET_900_SDMMC_DAS_HANDLE 0xDFEFA0
// NOPs
#define FS_OFFSET_900_SD_DAS_INIT 0x1472BC
// Nintendo Paths
#define FS_OFFSET_900_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x00068A60, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00070A40, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00081CB4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00081EF4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0008211C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_900_H__

View File

@@ -0,0 +1,59 @@
/*
* 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/>.
*/
#ifndef __FS_900_EXFAT_H__
#define __FS_900_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_900_EXFAT_SDMMC_ACCESSOR_GC 0x1430F0
#define FS_OFFSET_900_EXFAT_SDMMC_ACCESSOR_SD 0x141200
#define FS_OFFSET_900_EXFAT_SDMMC_ACCESSOR_NAND 0x13C080
// Hooks
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_READ 0x1377E0
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_WRITE 0x1378C0
#define FS_OFFSET_900_EXFAT_RTLD 0x454
#define FS_OFFSET_900_EXFAT_RTLD_DESTINATION 0x9C
#define FS_OFFSET_900_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x136A00
// Misc funcs
#define FS_OFFSET_900_EXFAT_LOCK_MUTEX 0x25280
#define FS_OFFSET_900_EXFAT_UNLOCK_MUTEX 0x252D0
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
// Misc Data
#define FS_OFFSET_900_EXFAT_SD_MUTEX 0xE2B3E8
#define FS_OFFSET_900_EXFAT_NAND_MUTEX 0xE26258
#define FS_OFFSET_900_EXFAT_ACTIVE_PARTITION 0xE26298
#define FS_OFFSET_900_EXFAT_SDMMC_DAS_HANDLE 0xE0CFA0
// NOPs
#define FS_OFFSET_900_EXFAT_SD_DAS_INIT 0x1472BC
// Nintendo Paths
#define FS_OFFSET_900_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x00068A60, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00070A40, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00081CB4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00081EF4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0008211C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_900_EXFAT_H__

View File

@@ -24,11 +24,13 @@
#include "../utils/types.h"
#include "../utils/util.h"
#include "../utils/fatal.h"
#include "../emuMMC/emummc.h"
#define DPRINTF(...) //fprintf(stdout, __VA_ARGS__)
sdmmc_accessor_t *_current_accessor = NULL;
bool sdmmc_memcpy_buf = false;
extern bool custom_driver;
static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
{
@@ -52,25 +54,25 @@ intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned i
char *_buf = (char *)buf;
char *actual_buf_start = _buf;
char *actual_buf_end = &_buf[512 * num_sectors];
char *dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer;
char *dma_buffer_start = _this->parent->dmaBuffers[0].device_addr_buffer;
if (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer_size])
if (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[0].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_EMMC;
dma_buf_idx = 0;
}
else
{
dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer_size])
dma_buffer_start = _this->parent->dmaBuffers[1].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[1].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_SD;
dma_buf_idx = 1;
}
else
{
dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer_size])
dma_buffer_start = _this->parent->dmaBuffers[2].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[2].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_GC;
dma_buf_idx = 2;
}
else
{
@@ -86,30 +88,69 @@ intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned i
return admaaddr;
}
int sdmmc_get_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_sectors)
int sdmmc_calculate_dma_index(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors)
{
int dma_buf_idx = 0;
int blkSize = num_sectors * 512;
char *_buf = (char *)buf;
char *actual_buf_start = _buf;
char *actual_buf_end = &_buf[512 * num_sectors];
char *dma_buffer_start = _this->parent->dmaBuffers[0].device_addr_buffer;
if (_this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer_size >= blkSize)
if (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[0].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_EMMC;
dma_buf_idx = 0;
}
else
{
if (_this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer_size >= blkSize)
dma_buffer_start = _this->parent->dmaBuffers[1].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[1].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_SD;
dma_buf_idx = 1;
}
else
{
if (_this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer_size >= blkSize)
dma_buffer_start = _this->parent->dmaBuffers[2].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[2].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_GC;
dma_buf_idx = 2;
}
else
{
// If buffer is on a random heap
return -1;
}
}
}
sdmmc_memcpy_buf = false;
return dma_buf_idx;
}
int sdmmc_calculate_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_sectors)
{
int dma_buf_idx = 0;
int blkSize = num_sectors * 512;
if (_this->parent->dmaBuffers[0].device_addr_buffer_size >= blkSize)
{
dma_buf_idx = 0;
}
else
{
if (_this->parent->dmaBuffers[1].device_addr_buffer_size >= blkSize)
{
dma_buf_idx = 1;
}
else
{
if (_this->parent->dmaBuffers[2].device_addr_buffer_size >= blkSize)
{
dma_buf_idx = 2;
}
else
{
// Can't find a fitting buffer
return 0;
}
}
@@ -266,14 +307,112 @@ out:;
return 1;
}
extern _sdmmc_accessor_sd sdmmc_accessor_sd;
extern _sdmmc_accessor_nand sdmmc_accessor_nand;
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)
{
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0);
if (!custom_driver)
{
sdmmc_accessor_t *accessor_sd = sdmmc_accessor_sd();
sdmmc_accessor_t *accessor_nand = sdmmc_accessor_nand();
if (sdmmc_calculate_dma_addr(accessor_sd, buf, num_sectors))
{
return !accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, buf, num_sectors * 512, 1);
}
else
{
if (sdmmc_calculate_dma_addr(accessor_nand, buf, num_sectors))
{
// buf is on the nand dma buffer
int original_dma_idx = sdmmc_calculate_dma_index(accessor_nand, buf, num_sectors);
sdmmc_dma_buffer_t *original_dma_buffer = &accessor_nand->parent->dmaBuffers[original_dma_idx];
// Next entry
int dma_idx = sdmmc_calculate_fitting_dma_index(accessor_sd, num_sectors) + 1;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer = original_dma_buffer->device_addr_buffer;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_masked = original_dma_buffer->device_addr_buffer_masked;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_size = original_dma_buffer->device_addr_buffer_size;
u64 res = accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, buf, num_sectors * 512, 1);
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer = 0;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_masked = 0;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_size = 0;
return !res;
}
else
{
// buf is on a heap
int dma_idx = sdmmc_calculate_fitting_dma_index(accessor_sd, num_sectors);
void *dma_buf = &accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer[0];
u64 res = accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, dma_buf, num_sectors * 512, 1);
memcpy(buf, dma_buf, num_sectors * 512);
return !res;
}
}
}
else
{
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0);
}
}
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)
{
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1);
if (!custom_driver)
{
sdmmc_accessor_t *accessor_sd = sdmmc_accessor_sd();
sdmmc_accessor_t *accessor_nand = sdmmc_accessor_nand();
if (sdmmc_calculate_dma_addr(accessor_sd, buf, num_sectors))
{
return !accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, buf, num_sectors * 512, 0);
}
else
{
if (sdmmc_calculate_dma_addr(accessor_nand, buf, num_sectors))
{
// buf is on the nand dma buffer
int original_dma_idx = sdmmc_calculate_dma_index(accessor_nand, buf, num_sectors);
sdmmc_dma_buffer_t *original_dma_buffer = &accessor_nand->parent->dmaBuffers[original_dma_idx];
// Next entry
int dma_idx = sdmmc_calculate_fitting_dma_index(accessor_sd, num_sectors) + 1;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer = original_dma_buffer->device_addr_buffer;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_masked = original_dma_buffer->device_addr_buffer_masked;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_size = original_dma_buffer->device_addr_buffer_size;
u64 res = accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, buf, num_sectors * 512, 0);
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer = 0;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_masked = 0;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_size = 0;
return !res;
}
else
{
// buf is on a heap
int dma_idx = sdmmc_calculate_fitting_dma_index(accessor_sd, num_sectors);
void *dma_buf = &accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer[0];
memcpy(dma_buf, buf, num_sectors * 512);
u64 res = accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, dma_buf, num_sectors * 512, 0);
return !res;
}
}
}
else
{
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1);
}
}
/*
@@ -703,7 +842,7 @@ static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, i
if (cond & SD_OCR_CCS)
storage->has_sector_access = 1;
if (false && cond & SD_ROCR_S18A && supports_low_voltage)
if (cond & SD_ROCR_S18A && supports_low_voltage)
{
//The low voltage regulator configuration is valid for SDMMC1 only.
if (storage->sdmmc->id == SDMMC_1 &&

View File

@@ -114,6 +114,7 @@ int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition);
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);
int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors);
int sdmmc_get_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_sectors);
int sdmmc_calculate_dma_index(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors);
int sdmmc_calculate_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_sectors);
#endif

View File

@@ -641,23 +641,6 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)
static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
{
if(sdmmc->id == SDMMC_1)
{
static int last_power = SDMMC_POWER_3_3;
if(power == SDMMC_POWER_1_8 && last_power == SDMMC_POWER_3_3)
{
last_power = power = SDMMC_POWER_1_8;
if (!_sdmmc_autocal_config_offset(sdmmc, power))
return;
}
else if(power == SDMMC_POWER_3_3 && last_power == SDMMC_POWER_1_8)
{
last_power = power = SDMMC_POWER_3_3;
if (!_sdmmc_autocal_config_offset(sdmmc, power))
return;
}
}
bool should_enable_sd_clock = false;
if (sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)
{
@@ -811,7 +794,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
if (!admaaddr)
{
// buf is on a heap
int dma_idx = sdmmc_get_fitting_dma_index(_current_accessor, blkcnt);
int dma_idx = sdmmc_calculate_fitting_dma_index(_current_accessor, blkcnt);
admaaddr = (u64)&_current_accessor->parent->dmaBuffers[dma_idx].device_addr_buffer_masked[0];
sdmmc->last_dma_idx = dma_idx;
}
@@ -1011,10 +994,13 @@ static int _sdmmc_config_sdmmc1()
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;
//Make sure SDMMC1 controller is reset.
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_NO_IOPOWER, (1 << 12), (1 << 12));
usleep(1000);
//Make sure the SDMMC1 controller is powered.
//PMC(APBDEV_PMC_NO_IOPOWER) &= ~(1 << 12);
//Assume 3.3V SD card voltage.
//PMC(APBDEV_PMC_PWR_DET_VAL) |= (1 << 12);
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_NO_IOPOWER, ~(1 << 12), (1 << 12));
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_PWR_DET_VAL, (1 << 12), (1 << 12));
//Set enable SD card power.
PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN | 1; //GPIO control, pull down.
@@ -1025,10 +1011,10 @@ static int _sdmmc_config_sdmmc1()
usleep(1000);
//Enable SD card power.
//max77620_regulator_set_voltage(REGULATOR_LDO2, 3300000);
//max77620_regulator_enable(REGULATOR_LDO2, 1);
max77620_regulator_set_voltage(REGULATOR_LDO2, 3300000);
max77620_regulator_enable(REGULATOR_LDO2, 1);
//usleep(1000);
usleep(1000);
//For good measure.
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = 0x10000000;
@@ -1071,7 +1057,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int n
sdmmc->regs->veniotrimctl &= 0xFFFFFFFB;
static const u32 trim_values[] = { 2, 8, 3, 8 };
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFF) | (trim_values[sdmmc->id] << 24);
sdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & 0xF) | 7;
sdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & 0xFFFFFFF0) | 7;
if (!_sdmmc_autocal_config_offset(sdmmc, power))
return 0;
_sdmmc_autocal_execute(sdmmc, power);
@@ -1103,8 +1089,9 @@ void sdmmc_end(sdmmc_t *sdmmc)
if (sdmmc->id == SDMMC_1)
{
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
//max77620_regulator_enable(REGULATOR_LDO2, 0);
msleep(100); // To power cycle min 1ms without power is needed.
msleep(1); // To power cycle min 1ms without power is needed.
max77620_regulator_enable(REGULATOR_LDO2, 0);
msleep(100); // Some extra.
}
_sdmmc_get_clkcon(sdmmc);
@@ -1158,7 +1145,7 @@ int sdmmc_enable_low_voltage(sdmmc_t *sdmmc)
_sdmmc_get_clkcon(sdmmc);
max77620_regulator_set_voltage(REGULATOR_LDO2, 1800000);
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~(1 << 12);
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_PWR_DET_VAL, ~(1 << 12), (1 << 12));
_sdmmc_autocal_config_offset(sdmmc, SDMMC_POWER_1_8);
_sdmmc_autocal_execute(sdmmc, SDMMC_POWER_1_8);

View File

@@ -92,26 +92,9 @@ static void _sdmmc_ensure_initialized(void)
}
}
void sdmmc_finalize(void)
{
if (!sdmmc_storage_end(&sd_storage))
{
fatal_abort(Fatal_InitSD);
}
storageSDinitialized = false;
}
static void _file_based_update_filename(char *outFilename, u32 sd_path_len, u32 part_idx)
{
if (part_idx < 10)
{
outFilename[sd_path_len] = '0';
itoa(part_idx, &outFilename[sd_path_len + 1], 10);
}
else
{
itoa(part_idx, &outFilename[sd_path_len], 10);
}
snprintf(outFilename + sd_path_len, 3, "%02d", part_idx);
}
static void _file_based_emmc_finalize(void)
@@ -119,11 +102,13 @@ static void _file_based_emmc_finalize(void)
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_File) && fat_mounted)
{
// Close all open handles.
f_close(f_emu.fp_boot0);
f_close(f_emu.fp_boot1);
f_close(&f_emu.fp_boot0);
f_close(&f_emu.fp_boot1);
for (int i = 0; i < f_emu.parts; i++)
f_close(f_emu.fp_gpp[i]);
{
f_close(&f_emu.fp_gpp[i]);
}
// Force unmount FAT volume.
f_mount(NULL, "", 1);
@@ -132,6 +117,18 @@ static void _file_based_emmc_finalize(void)
}
}
void sdmmc_finalize(void)
{
_file_based_emmc_finalize();
if (!sdmmc_storage_end(&sd_storage))
{
fatal_abort(Fatal_InitSD);
}
storageSDinitialized = false;
}
static void _file_based_emmc_initialize(void)
{
char path[sizeof(emuMMC_ctx.storagePath) + 0x20];
@@ -143,36 +140,32 @@ static void _file_based_emmc_initialize(void)
int path_len = strlen(path);
// Open BOOT0 physical partition.
f_emu.fp_boot0 = (FIL *)malloc(sizeof(FIL));
memcpy(path + path_len, "BOOT0", 6);
if (f_open(f_emu.fp_boot0, path, FA_READ | FA_WRITE) != FR_OK)
if (f_open(&f_emu.fp_boot0, path, FA_READ | FA_WRITE) != FR_OK)
fatal_abort(Fatal_InitSD);
// Open BOOT1 physical partition.
f_emu.fp_boot1 = (FIL *)malloc(sizeof(FIL));
memcpy(path + path_len, "BOOT1", 6);
if (f_open(f_emu.fp_boot1, path, FA_READ | FA_WRITE) != FR_OK)
if (f_open(&f_emu.fp_boot1, path, FA_READ | FA_WRITE) != FR_OK)
fatal_abort(Fatal_InitSD);
// Open handles for GPP physical partition files.
_file_based_update_filename(path, path_len, 00);
if (f_open(f_emu.fp_gpp[0], path, FA_READ | FA_WRITE) != FR_OK)
if (f_open(&f_emu.fp_gpp[0], path, FA_READ | FA_WRITE) != FR_OK)
fatal_abort(Fatal_InitSD);
f_emu.part_size = f_size(f_emu.fp_gpp[0]);
f_emu.part_size = f_size(&f_emu.fp_gpp[0]) >> 9;
// Iterate folder for split parts and stop if next doesn't exist.
// Supports up to 32 parts of any size.
// TODO: decide on max parts and define them. (hekate produces up to 30 parts on 1GB mode.)
for (f_emu.parts = 1; f_emu.parts < 32; f_emu.parts++)
{
f_emu.fp_gpp[f_emu.parts] = (FIL *)malloc(sizeof(FIL));
_file_based_update_filename(path, path_len, f_emu.parts);
if (f_open(f_emu.fp_gpp[f_emu.parts], path, FA_READ | FA_WRITE) != FR_OK)
if (f_open(&f_emu.fp_gpp[f_emu.parts], path, FA_READ | FA_WRITE) != FR_OK)
{
free(f_emu.fp_gpp[f_emu.parts]);
// Check if single file.
if (f_emu.parts == 1)
f_emu.parts = 0;
@@ -257,14 +250,20 @@ sdmmc_accessor_t *sdmmc_accessor_get(int mmc_id)
void mutex_lock_handler(int mmc_id)
{
lock_mutex(sd_mutex);
if (custom_driver)
{
lock_mutex(sd_mutex);
}
lock_mutex(nand_mutex);
}
void mutex_unlock_handler(int mmc_id)
{
unlock_mutex(nand_mutex);
unlock_mutex(sd_mutex);
if (custom_driver)
{
unlock_mutex(sd_mutex);
}
}
int sdmmc_nand_get_active_partition_index()
@@ -303,19 +302,19 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
case FS_EMMC_PARTITION_GPP:
if (f_emu.parts)
{
fp_tmp = f_emu.fp_gpp[sector / f_emu.part_size];
fp_tmp = &f_emu.fp_gpp[sector / f_emu.part_size];
sector = sector % f_emu.part_size;
}
else
{
fp_tmp = f_emu.fp_gpp[0];
fp_tmp = &f_emu.fp_gpp[0];
}
break;
case FS_EMMC_PARTITION_BOOT1:
fp_tmp = f_emu.fp_boot1;
fp_tmp = &f_emu.fp_boot1;
break;
case FS_EMMC_PARTITION_BOOT0:
fp_tmp = f_emu.fp_boot0;
fp_tmp = &f_emu.fp_boot0;
break;
}
@@ -324,10 +323,44 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
; //TODO. Out of range. close stuff and fatal?
}
uint64_t res = 0;
if (!is_write)
return !(f_read(fp_tmp, buf, num_sectors << 9, NULL));
res = !(f_read(fp_tmp, buf, num_sectors << 9, NULL));
else
return !(f_write(fp_tmp, buf, num_sectors << 9, NULL));
res = !(f_write(fp_tmp, buf, num_sectors << 9, NULL));
return res;
}
// Controller close wrapper
uint64_t sdmmc_wrapper_controller_close(int mmc_id)
{
sdmmc_accessor_t *_this;
_this = sdmmc_accessor_get(mmc_id);
if (_this != NULL)
{
if (mmc_id == FS_SDMMC_SD)
{
return 0;
}
if (mmc_id == FS_SDMMC_EMMC)
{
// Close file handles and unmount
_file_based_emmc_finalize();
// Close SD
sdmmc_accessor_get(FS_SDMMC_SD)->vtab->sdmmc_accessor_controller_close(sdmmc_accessor_get(FS_SDMMC_SD));
// Close eMMC
return _this->vtab->sdmmc_accessor_controller_close(_this);
}
return _this->vtab->sdmmc_accessor_controller_close(_this);
}
fatal_abort(Fatal_CloseAccessor);
}
// FS read wrapper.
@@ -366,6 +399,18 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
if (mmc_id == FS_SDMMC_SD)
{
static bool first_sd_read = true;
if (first_sd_read)
{
first_sd_read = false;
// Because some SD cards have issues with emuMMC's driver
// we currently swap to FS's driver after first SD read
// TODO: Fix remaining driver issues
custom_driver = false;
// FS will handle sd mutex w/o custom driver from here on
unlock_mutex(sd_mutex);
}
// Call hekates driver.
if (sdmmc_storage_read(&sd_storage, sector, num_sectors, buf))
{

View File

@@ -50,6 +50,8 @@ sdmmc_accessor_t *sdmmc_accessor_get(int mmc_id);
void mutex_lock_handler(int mmc_id);
void mutex_unlock_handler(int mmc_id);
// Hooks
uint64_t sdmmc_wrapper_controller_close(int mmc_id);
uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned int sector, unsigned int num_sectors);
uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_sectors, void *buf, uint64_t bufSize);
@@ -59,9 +61,9 @@ typedef struct _file_based_ctxt
uint64_t parts;
uint64_t part_size;
FATFS *sd_fs;
FIL *fp_boot0;
FIL *fp_boot1;
FIL *fp_gpp[32];
FIL fp_boot0;
FIL fp_boot1;
FIL fp_gpp[32];
} file_based_ctxt;
#ifdef __cplusplus

View File

@@ -22,6 +22,8 @@
#include <string.h>
#include "nx/svc.h"
#include "nx/smc.h"
#include "soc/clock.h"
#include "soc/i2c.h"
#include "emuMMC/emummc.h"
#include "emuMMC/emummc_ctx.h"
#include "FS/FS_offsets.h"
@@ -174,6 +176,8 @@ void setup_hooks(void)
INJECT_HOOK(fs_offsets->sdmmc_wrapper_read, sdmmc_wrapper_read);
// sdmmc_wrapper_write hook
INJECT_HOOK(fs_offsets->sdmmc_wrapper_write, sdmmc_wrapper_write);
// sdmmc_wrapper_controller_close hook
INJECT_HOOK(fs_offsets->sdmmc_accessor_controller_close, sdmmc_wrapper_controller_close);
// On 8.0.0+, we need to hook the regulator setup, because
// otherwise it will abort because we have already turned it on.
@@ -203,10 +207,6 @@ void populate_function_pointers(void)
void write_nops(void)
{
// This NOPs out a call to ShutdownSdCard when preparing for shutdown/reboot.
// This prevents the PatrolReader from hanging when saving its state, which
// occurs immediately afterwards (in ShutdownMmc).
INJECT_NOP(fs_offsets->shutdown_sd);
// On 7.0.0+, we need to attach to device address space ourselves.
// This patches an abort that happens when Nintendo's code sees SD
// is already attached
@@ -316,4 +316,7 @@ void __init()
populate_function_pointers();
write_nops();
setup_nintendo_paths();
clock_enable_i2c5();
i2c_init();
}

View File

@@ -20,7 +20,8 @@
#include "../utils/util.h"
#include "t210.h"
static u32 i2c_addrs[] = {
// TODO: not hardcode I2C_5
static u64 i2c_addrs[] = {
0x7000C000, 0x7000C400, 0x7000C500,
0x7000C700, 0x7000D000, 0x7000D100
};
@@ -28,6 +29,7 @@ static u32 i2c_addrs[] = {
static void _i2c_wait(vu32 *base)
{
base[I2C_CONFIG_LOAD] = 0x25;
for (u32 i = 0; i < 20; i++)
{
usleep(1);
@@ -44,8 +46,7 @@ static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
u32 tmp = 0;
memcpy(&tmp, buf, size);
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[0], 0x2000);
base = base + (i2c_addrs[idx] - i2c_addrs[0]);
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[I2C_5], 0x1000);
base[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).
base[I2C_CMD_DATA1] = tmp; //Set value.
base[I2C_CNFG] = (2 * size - 2) | 0x2800; //Set size and send mode.
@@ -66,8 +67,7 @@ static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
if (size > 8)
return 0;
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[0], 0x2000);
base = base + (i2c_addrs[idx] - i2c_addrs[0]);
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[I2C_5], 0x1000);
base[I2C_CMD_ADDR0] = (x << 1) | 1; // Set x (recv mode).
base[I2C_CNFG] = (size - 1) << 1 | 0x2840; // Set size and recv mode.
@@ -93,10 +93,9 @@ static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
return 1;
}
void i2c_init(u32 idx)
void i2c_init()
{
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[0], 0x2000);
base = base + (i2c_addrs[idx] - i2c_addrs[0]);
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[I2C_5], 0x1000);
base[I2C_CLK_DIVISOR_REGISTER] = 0x50001;
base[I2C_BUS_CLEAR_CONFIG] = 0x90003;
@@ -104,7 +103,6 @@ void i2c_init(u32 idx)
for (u32 i = 0; i < 10; i++)
{
usleep(20000);
if (base[INTERRUPT_STATUS_REGISTER] & 0x800)
break;
}

View File

@@ -37,7 +37,7 @@
#define I2C_BUS_CLEAR_STATUS 0x22
#define I2C_CONFIG_LOAD 0x23
void i2c_init(u32 idx);
void i2c_init();
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);

View File

@@ -15,13 +15,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "fatal.h"
void __attribute__((noreturn)) fatal_abort(enum FatalReason abortReason)
{
atmosphere_fatal_error_ctx error_ctx;
memset(&error_ctx, 0, sizeof(atmosphere_fatal_error_ctx));
// Basic error storage for Atmosphere
// TODO: Maybe include a small reboot2payload stub?
error_ctx.magic = ATMOSPHERE_REBOOT_TO_FATAL_MAGIC;
error_ctx.title_id = 0x0100000000000000; // FS
error_ctx.error_desc = abortReason;
// Copy fatal context
smcCopyToIram(ATMOSPHERE_FATAL_ERROR_ADDR, &error_ctx, sizeof(atmosphere_fatal_error_ctx));
// Reboot to RCM
smcRebootToRcm();
while(true)
while (true)
; // Should never be reached
}

View File

@@ -18,7 +18,8 @@
#pragma once
#include "../nx/smc.h"
enum FatalReason {
enum FatalReason
{
Fatal_InitMMC = 0,
Fatal_InitSD,
Fatal_InvalidAccessor,
@@ -28,7 +29,49 @@ enum FatalReason {
Fatal_UnknownVersion,
Fatal_BadResult,
Fatal_GetConfig,
Fatal_CloseAccessor,
Fatal_Max
};
#define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20
#define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100
/* Atmosphere reboot-to-fatal-error. */
typedef struct
{
uint32_t magic;
uint32_t error_desc;
uint64_t title_id;
union {
uint64_t gprs[32];
struct
{
uint64_t _gprs[29];
uint64_t fp;
uint64_t lr;
uint64_t sp;
};
};
uint64_t pc;
uint64_t module_base;
uint32_t pstate;
uint32_t afsr0;
uint32_t afsr1;
uint32_t esr;
uint64_t far;
uint64_t report_identifier; /* Normally just system tick. */
uint64_t stack_trace_size;
uint64_t stack_dump_size;
uint64_t stack_trace[AMS_FATAL_ERROR_MAX_STACKTRACE];
uint8_t stack_dump[AMS_FATAL_ERROR_MAX_STACKDUMP];
} atmosphere_fatal_error_ctx;
/* "AFE1" */
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC 0x31454641
/* "AFE0" */
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0 0x30454641
#define ATMOSPHERE_FATAL_ERROR_ADDR 0x4003E000
#define ATMOSPHERE_FATAL_ERROR_CONTEXT ((volatile atmosphere_fatal_error_ctx *)(ATMOSPHERE_FATAL_ERROR_ADDR))
void __attribute__((noreturn)) fatal_abort(enum FatalReason abortReason);

View File

@@ -79,7 +79,7 @@ typedef enum {
CARDEVICE_UARTC = ((1 << 5) | 0x17),
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
CARDEVICE_UNK = ((3 << 5) | 0x1E),
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
CARDEVICE_SE = ((3 << 5) | 0x1F),
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
CARDEVICE_TSEC = ((2 << 5) | 0x13),

View File

@@ -35,6 +35,14 @@
#define MC_SMMU_PTB_DATA 0x20
#define MC_SMMU_TLB_FLUSH 0x30
#define MC_SMMU_PTC_FLUSH 0x34
#define MC_SMMU_ASID_SECURITY 0x38
#define MC_SMMU_ASID_SECURITY_1 0x3c
#define MC_SMMU_ASID_SECURITY_2 0x9e0
#define MC_SMMU_ASID_SECURITY_3 0x9e4
#define MC_SMMU_ASID_SECURITY_4 0x9e8
#define MC_SMMU_ASID_SECURITY_5 0x9ec
#define MC_SMMU_ASID_SECURITY_6 0x9f0
#define MC_SMMU_ASID_SECURITY_7 0x9f4
#define MC_SMMU_AFI_ASID 0x238
#define MC_SMMU_AVPC_ASID 0x23c
#define MC_SMMU_PPCS1_ASID 0x298

View File

@@ -13,7 +13,7 @@
* 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 <stdint.h>
#include <stdbool.h>
@@ -64,7 +64,7 @@ void setup_dram_magic_numbers(void) {
void bootup_misc_mmio(void) {
/* Initialize Fuse registers. */
fuse_init();
/* Verify Security Engine sanity. */
se_set_in_context_save_mode(false);
/* TODO: se_verify_keys_unreadable(); */
@@ -85,6 +85,9 @@ void bootup_misc_mmio(void) {
setup_dram_magic_numbers();
}
/* On 9.0.0+, Nintendo writes random values to context save scratch here, and locks the SRK scratch. */
/* There's no real need for us to do this, so we won't. */
/* Mark TMR5, TMR6, TMR7, TMR8, WDT0, WDT1, WDT2 and WDT3 as secure. */
SHARED_TIMER_SECURE_CFG_0 = 0xF1E0;
@@ -111,7 +114,7 @@ void bootup_misc_mmio(void) {
MAKE_MC_REG(MC_SECURITY_CFG1) = 0;
MAKE_MC_REG(MC_SECURITY_CFG3) = 3;
configure_default_carveouts();
/* Mark registers secure world only. */
if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_100) {
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 = APB_SSER0_SATA_AUX | APB_SSER0_DTV | APB_SSER0_QSPI | APB_SSER0_SATA | APB_SSER0_LA;
@@ -140,28 +143,26 @@ void bootup_misc_mmio(void) {
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = sec_disable_2;
}
/* Reset Translation Enable Registers. */
/* Reset Translation Enable registers. */
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_0) = 0xFFFFFFFF;
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_1) = 0xFFFFFFFF;
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_2) = 0xFFFFFFFF;
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_3) = 0xFFFFFFFF;
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_4) = 0xFFFFFFFF;
/* TODO: What are these MC reg writes? */
/* Set SMMU ASID security registers. */
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
MAKE_MC_REG(0x038) = 0xE;
MAKE_MC_REG(MC_SMMU_ASID_SECURITY) = 0xE;
} else {
MAKE_MC_REG(0x038) = 0x0;
MAKE_MC_REG(MC_SMMU_ASID_SECURITY) = 0x0;
}
MAKE_MC_REG(0x03C) = 0;
/* MISC registers. */
MAKE_MC_REG(0x9E0) = 0;
MAKE_MC_REG(0x9E4) = 0;
MAKE_MC_REG(0x9E8) = 0;
MAKE_MC_REG(0x9EC) = 0;
MAKE_MC_REG(0x9F0) = 0;
MAKE_MC_REG(0x9F4) = 0;
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_1) = 0;
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_2) = 0;
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_3) = 0;
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_4) = 0;
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_5) = 0;
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_6) = 0;
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_7) = 0;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
MAKE_MC_REG(MC_SMMU_PTB_ASID) = 0;
@@ -176,7 +177,7 @@ void bootup_misc_mmio(void) {
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
MAKE_MC_REG(MC_SMMU_CONFIG) = 1; /* Enable SMMU. */
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
/* Clear RESET Vector, setup CPU Secure Boot RESET Vectors. */
uint32_t reset_vec;
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
@@ -204,7 +205,7 @@ void bootup_misc_mmio(void) {
intr_set_enabled(INTERRUPT_ID_SECURITY_ENGINE, 1);
intr_set_cpu_mask(INTERRUPT_ID_SECURITY_ENGINE, 8);
intr_set_edge_level(INTERRUPT_ID_SECURITY_ENGINE, 0);
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
intr_set_priority(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
intr_set_group(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
@@ -215,10 +216,10 @@ void bootup_misc_mmio(void) {
if (!g_has_booted_up) {
/* N doesn't do this, but we should for compatibility. */
uart_select(UART_A);
uart_config(UART_A);
clkrst_reboot(CARDEVICE_UARTA);
uart_init(UART_A, 115200);
intr_register_handler(INTERRUPT_ID_SECURITY_ENGINE, se_operation_completed);
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
intr_register_handler(INTERRUPT_ID_ACTIVITY_MONITOR_4X, actmon_interrupt_handler);

View File

@@ -13,26 +13,57 @@
* 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 <string.h>
#include "i2c.h"
#include "utils.h"
#include "timers.h"
#include "pinmux.h"
/* Prototypes for internal commands. */
volatile i2c_registers_t *i2c_get_registers_from_id(unsigned int id);
void i2c_load_config(volatile i2c_registers_t *regs);
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id);
void i2c_load_config(volatile tegra_i2c_t *regs);
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size);
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
bool i2c_write(volatile i2c_registers_t *regs, uint8_t device, void *src, size_t src_size);
bool i2c_read(volatile i2c_registers_t *regs, uint8_t device, void *dst, size_t dst_size);
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size);
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size);
/* Configure I2C pinmux. */
void i2c_config(I2CDevice id) {
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
switch (id) {
case I2C_1:
pinmux->gen1_i2c_scl = PINMUX_INPUT;
pinmux->gen1_i2c_sda = PINMUX_INPUT;
break;
case I2C_2:
pinmux->gen2_i2c_scl = PINMUX_INPUT;
pinmux->gen2_i2c_sda = PINMUX_INPUT;
break;
case I2C_3:
pinmux->gen3_i2c_scl = PINMUX_INPUT;
pinmux->gen3_i2c_sda = PINMUX_INPUT;
break;
case I2C_4:
pinmux->cam_i2c_scl = PINMUX_INPUT;
pinmux->cam_i2c_sda = PINMUX_INPUT;
break;
case I2C_5:
pinmux->pwr_i2c_scl = PINMUX_INPUT;
pinmux->pwr_i2c_sda = PINMUX_INPUT;
break;
case I2C_6:
/* Unused. */
break;
default: break;
}
}
/* Initialize I2C based on registers. */
void i2c_init(unsigned int id) {
volatile i2c_registers_t *regs = i2c_get_registers_from_id(id);
void i2c_init(I2CDevice id) {
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
/* Setup divisor, and clear the bus. */
regs->I2C_I2C_CLK_DIVISOR_REGISTER_0 = 0x50001;
@@ -43,7 +74,7 @@ void i2c_init(unsigned int id) {
/* Wait a while until BUS_CLEAR_DONE is set. */
for (unsigned int i = 0; i < 10; i++) {
wait(20000);
wait(25);
if (regs->I2C_INTERRUPT_STATUS_REGISTER_0 & 0x800) {
break;
}
@@ -57,20 +88,20 @@ void i2c_init(unsigned int id) {
regs->I2C_INTERRUPT_STATUS_REGISTER_0 = int_status;
}
/* Sets a bit in a PMIC register over I2C during CPU shutdown. */
/* Sets a bit in a PMIC register over I2C during CPU shutdown. */
void i2c_send_pmic_cpu_shutdown_cmd(void) {
uint32_t val = 0;
/* PMIC == Device 4:3C. */
i2c_query(4, 0x3C, 0x41, &val, 1);
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
val |= 4;
i2c_send(4, 0x3C, 0x41, &val, 1);
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
}
/* Queries the value of TI charger bit over I2C. */
bool i2c_query_ti_charger_bit_7(void) {
uint32_t val = 0;
/* TI Charger = Device 0:6B. */
i2c_query(0, 0x6B, 0, &val, 1);
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
return (val & 0x80) != 0;
}
@@ -78,34 +109,34 @@ bool i2c_query_ti_charger_bit_7(void) {
void i2c_clear_ti_charger_bit_7(void) {
uint32_t val = 0;
/* TI Charger = Device 0:6B. */
i2c_query(0, 0x6B, 0, &val, 1);
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
val &= 0x7F;
i2c_send(0, 0x6B, 0, &val, 1);
i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
}
/* Sets TI charger bit over I2C. */
void i2c_set_ti_charger_bit_7(void) {
uint32_t val = 0;
/* TI Charger = Device 0:6B. */
i2c_query(0, 0x6B, 0, &val, 1);
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
val |= 0x80;
i2c_send(0, 0x6B, 0, &val, 1);
i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
}
/* Get registers pointer based on I2C ID. */
volatile i2c_registers_t *i2c_get_registers_from_id(unsigned int id) {
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id) {
switch (id) {
case 0:
case I2C_1:
return I2C1_REGS;
case 1:
case I2C_2:
return I2C2_REGS;
case 2:
case I2C_3:
return I2C3_REGS;
case 3:
case I2C_4:
return I2C4_REGS;
case 4:
case I2C_5:
return I2C5_REGS;
case 5:
case I2C_6:
return I2C6_REGS;
default:
generic_panic();
@@ -114,7 +145,7 @@ volatile i2c_registers_t *i2c_get_registers_from_id(unsigned int id) {
}
/* Load hardware config for I2C4. */
void i2c_load_config(volatile i2c_registers_t *regs) {
void i2c_load_config(volatile tegra_i2c_t *regs) {
/* Set MSTR_CONFIG_LOAD, TIMEOUT_CONFIG_LOAD, undocumented bit. */
regs->I2C_I2C_CONFIG_LOAD_0 = 0x25;
@@ -128,10 +159,10 @@ void i2c_load_config(volatile i2c_registers_t *regs) {
}
/* Reads a register from a device over I2C, writes result to output. */
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
volatile i2c_registers_t *regs = i2c_get_registers_from_id(id);
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
uint32_t val = r;
/* Write single byte register ID to device. */
if (!i2c_write(regs, device, &val, 1)) {
return false;
@@ -140,12 +171,12 @@ bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst
if (dst_size > 4) {
return false;
}
return i2c_read(regs, device, dst, dst_size);
}
/* Writes a value to a register over I2C. */
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size) {
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size) {
uint32_t val = r;
if (src_size == 0) {
return true;
@@ -158,7 +189,7 @@ bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_
}
/* Writes bytes to device over I2C. */
bool i2c_write(volatile i2c_registers_t *regs, uint8_t device, void *src, size_t src_size) {
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size) {
if (src_size > 4) {
return false;
} else if (src_size == 0) {
@@ -177,8 +208,7 @@ bool i2c_write(volatile i2c_registers_t *regs, uint8_t device, void *src, size_t
i2c_load_config(regs);
/* Config |= SEND; */
regs->I2C_I2C_CNFG_0 |= 0x200;
regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
while (regs->I2C_I2C_STATUS_0 & 0x100) {
/* Wait until not busy. */
@@ -189,7 +219,7 @@ bool i2c_write(volatile i2c_registers_t *regs, uint8_t device, void *src, size_t
}
/* Reads bytes from device over I2C. */
bool i2c_read(volatile i2c_registers_t *regs, uint8_t device, void *dst, size_t dst_size) {
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size) {
if (dst_size > 4) {
return false;
} else if (dst_size == 0) {
@@ -205,13 +235,12 @@ bool i2c_read(volatile i2c_registers_t *regs, uint8_t device, void *dst, size_t
i2c_load_config(regs);
/* Config |= SEND; */
regs->I2C_I2C_CNFG_0 |= 0x200;
regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
while (regs->I2C_I2C_STATUS_0 & 0x100) {
/* Wait until not busy. */
}
/* Ensure success. */
if ((regs->I2C_I2C_STATUS_0 & 0xF) != 0) {
return false;

View File

@@ -19,10 +19,27 @@
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "memory_map.h"
/* Exosphere driver for the Tegra X1 I2C registers. */
#define MAX77621_CPU_I2C_ADDR 0x1B
#define MAX77621_GPU_I2C_ADDR 0x1C
#define MAX17050_I2C_ADDR 0x36
#define MAX77620_PWR_I2C_ADDR 0x3C
#define MAX77620_RTC_I2C_ADDR 0x68
#define BQ24193_I2C_ADDR 0x6B
typedef enum {
I2C_1 = 0,
I2C_2 = 1,
I2C_3 = 2,
I2C_4 = 3,
I2C_5 = 4,
I2C_6 = 5,
} I2CDevice;
typedef struct {
uint32_t I2C_I2C_CNFG_0;
uint32_t I2C_I2C_CMD_ADDR0_0;
@@ -65,7 +82,7 @@ typedef struct {
uint32_t I2C_I2C_INTERFACE_TIMING_1_0;
uint32_t I2C_I2C_HS_INTERFACE_TIMING_0_0;
uint32_t I2C_I2C_HS_INTERFACE_TIMING_1_0;
} i2c_registers_t;
} tegra_i2c_t;
static inline uintptr_t get_i2c_dtv_234_base(void) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DTV_I2C234);
@@ -75,17 +92,20 @@ static inline uintptr_t get_i2c56_spi2b_base(void) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_I2C56_SPI2B);
}
#define I2C1_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x000))
#define I2C2_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x400))
#define I2C3_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x500))
#define I2C4_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x700))
#define I2C5_REGS ((volatile i2c_registers_t *)(get_i2c56_spi2b_base() + 0x000))
#define I2C6_REGS ((volatile i2c_registers_t *)(get_i2c56_spi2b_base() + 0x100))
#define I2C1_REGS ((volatile tegra_i2c_t *)(get_i2c_dtv_234_base() + 0x000))
#define I2C2_REGS ((volatile tegra_i2c_t *)(get_i2c_dtv_234_base() + 0x400))
#define I2C3_REGS ((volatile tegra_i2c_t *)(get_i2c_dtv_234_base() + 0x500))
#define I2C4_REGS ((volatile tegra_i2c_t *)(get_i2c_dtv_234_base() + 0x700))
#define I2C5_REGS ((volatile tegra_i2c_t *)(get_i2c56_spi2b_base() + 0x000))
#define I2C6_REGS ((volatile tegra_i2c_t *)(get_i2c56_spi2b_base() + 0x100))
void i2c_init(unsigned int id);
void i2c_config(I2CDevice id);
void i2c_init(I2CDevice id);
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
void i2c_send_pmic_cpu_shutdown_cmd(void);
bool i2c_query_ti_charger_bit_7(void);
void i2c_clear_ti_charger_bit_7(void);
void i2c_set_ti_charger_bit_7(void);

View File

@@ -43,6 +43,7 @@ static const uint8_t mkey_vectors_dev[MASTERKEY_REVISION_MAX][0x10] =
{0x6F, 0xD2, 0x84, 0x1D, 0x05, 0xEC, 0x40, 0x94, 0x5F, 0x18, 0xB3, 0x81, 0x09, 0x98, 0x8D, 0x4E}, /* Master key 05 encrypted with Master key 06. */
{0x37, 0xAF, 0xAB, 0x35, 0x79, 0x09, 0xD9, 0x48, 0x29, 0xD2, 0xDB, 0xA5, 0xA5, 0xF5, 0x30, 0x19}, /* Master key 06 encrypted with Master key 07. */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: Master key 07 encrypted with Master key 08. */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: Master key 08 encrypted with Master key 09. */
};
/* Retail unit keys. */
@@ -57,6 +58,7 @@ static const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] =
{0x1E, 0x1E, 0x22, 0xC0, 0x5A, 0x33, 0x3C, 0xB9, 0x0B, 0xA9, 0x03, 0x04, 0xBA, 0xDB, 0x07, 0x57}, /* Master key 05 encrypted with Master key 06. */
{0xA4, 0xD4, 0x52, 0x6F, 0xD1, 0xE4, 0x36, 0xAA, 0x9F, 0xCB, 0x61, 0x27, 0x1C, 0x67, 0x65, 0x1F}, /* Master key 06 encrypted with Master key 07. */
{0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29}, /* Master key 07 encrypted with Master key 08. */
{0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80}, /* Master key 08 encrypted with Master key 09. */
};
bool check_mkey_revision(unsigned int revision, bool is_retail) {

View File

@@ -19,8 +19,8 @@
/* This is glue code to enable master key support across versions. */
/* TODO: Update to 0xA on release of new master key. */
#define MASTERKEY_REVISION_MAX 0x9
/* TODO: Update to 0xB on release of new master key. */
#define MASTERKEY_REVISION_MAX 0xA
#define MASTERKEY_REVISION_100_230 0x00
#define MASTERKEY_REVISION_300 0x01
@@ -29,8 +29,9 @@
#define MASTERKEY_REVISION_500_510 0x04
#define MASTERKEY_REVISION_600_610 0x05
#define MASTERKEY_REVISION_620 0x06
#define MASTERKEY_REVISION_700_800 0x07
#define MASTERKEY_REVISION_810_CURRENT 0x08
#define MASTERKEY_REVISION_700_800 0x07
#define MASTERKEY_REVISION_810 0x08
#define MASTERKEY_REVISION_900_CURRENT 0x09
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)

View File

@@ -40,6 +40,14 @@ static inline uintptr_t get_mc_base(void) {
#define MC_SMMU_PTB_DATA 0x20
#define MC_SMMU_TLB_FLUSH 0x30
#define MC_SMMU_PTC_FLUSH 0x34
#define MC_SMMU_ASID_SECURITY 0x38
#define MC_SMMU_ASID_SECURITY_1 0x3c
#define MC_SMMU_ASID_SECURITY_2 0x9e0
#define MC_SMMU_ASID_SECURITY_3 0x9e4
#define MC_SMMU_ASID_SECURITY_4 0x9e8
#define MC_SMMU_ASID_SECURITY_5 0x9ec
#define MC_SMMU_ASID_SECURITY_6 0x9f0
#define MC_SMMU_ASID_SECURITY_7 0x9f4
#define MC_SMMU_AFI_ASID 0x238
#define MC_SMMU_AVPC_ASID 0x23c
#define MC_SMMU_PPCS1_ASID 0x298

View File

@@ -18,26 +18,15 @@
#define EXOSPHERE_MISC_H
#include <stdint.h>
#include "memory_map.h"
/* Exosphere driver for the Tegra X1 MISC Registers. */
#define MISC_BASE (MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MISC))
#define MAKE_MISC_REG(n) MAKE_REG32(MISC_BASE + n)
#define APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 MAKE_MISC_REG(0x0C00)
#define APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 MAKE_MISC_REG(0x0C04)
#define APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 MAKE_MISC_REG(0x0C08)
#define PINMUX_AUX_GEN1_I2C_SCL_0 MAKE_MISC_REG(0x30BC)
#define PINMUX_AUX_GEN1_I2C_SDA_0 MAKE_MISC_REG(0x30C0)
#define PINMUX_AUX_UARTn_TX_0(n) MAKE_MISC_REG(0x30E4 + 0x10 * (n))
#define PINMUX_AUX_UARTn_RX_0(n) MAKE_MISC_REG(0x30E8 + 0x10 * (n))
#define PINMUX_AUX_UARTn_RTS_0(n) MAKE_MISC_REG(0x30EC + 0x10 * (n))
#define PINMUX_AUX_UARTn_CTS_0(n) MAKE_MISC_REG(0x30F0 + 0x10 * (n))
#endif

View File

@@ -43,7 +43,8 @@ static const uint8_t new_device_key_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10]
{0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */
{0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17}, /* 6.2.0 New Device Key Source. */
{0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D}, /* 7.0.0 New Device Key Source. */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 8.1.0 New Device Key Source to be added on next change-of-keys. */
{0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE}, /* 8.1.0 New Device Key Source. */
{0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49}, /* 9.0.0 New Device Key Source. */
};
static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
@@ -52,7 +53,8 @@ static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x
{0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF}, /* 6.x New Device Keygen Source. */
{0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB}, /* 6.2.0 New Device Keygen Source. */
{0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E}, /* 7.0.0 New Device Keygen Source. */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 8.1.0 New Device Key Source to be added on next change-of-keys. */
{0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D}, /* 8.1.0 New Device Keygen Source. */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 9.0.0 New Device Keygen Source to be added on next change-of-keys. */
};
static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
@@ -61,7 +63,8 @@ static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS
{0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5}, /* 6.x New Device Keygen Source. */
{0x20, 0xAB, 0xF2, 0x0F, 0x05, 0xE3, 0xDE, 0x2E, 0xA1, 0xFB, 0x37, 0x5E, 0x8B, 0x22, 0x1A, 0x38}, /* 6.2.0 New Device Keygen Source. */
{0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE}, /* 7.0.0 New Device Keygen Source. */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 8.1.0 New Device Key Source to be added on next change-of-keys. */
{0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87}, /* 8.1.0 New Device Keygen Source. */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 9.0.0 New Device Keygen Source to be added on next change-of-keys. */
};
static void derive_new_device_keys(unsigned int keygen_keyslot) {
@@ -141,6 +144,7 @@ static void setup_se(void) {
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900:
derive_new_device_keys(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY);
break;
}
@@ -330,7 +334,7 @@ static bool validate_package2_metadata(package2_meta_t *metadata) {
/* Perform version checks. */
/* We will be compatible with all package2s released before current, but not newer ones. */
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_810_CURRENT) {
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_900_CURRENT) {
return true;
}
@@ -456,6 +460,7 @@ static void copy_warmboot_bin_to_dram() {
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900:
warmboot_src = (uint8_t *)0x4003E000;
break;
}
@@ -532,6 +537,9 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
case ATMOSPHERE_TARGET_FIRMWARE_810:
MAKE_REG32(PMC_BASE + 0x360) = 0x14A;
break;
case ATMOSPHERE_TARGET_FIRMWARE_900:
MAKE_REG32(PMC_BASE + 0x360) = 0x16B;
break;
}
}

View File

@@ -71,7 +71,8 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(unsigned int targetfw) {
#define PACKAGE2_MAXVER_600_610 0x8
#define PACKAGE2_MAXVER_620 0x9
#define PACKAGE2_MAXVER_700_800 0xA
#define PACKAGE2_MAXVER_810_CURRENT 0xB
#define PACKAGE2_MAXVER_810 0xB
#define PACKAGE2_MAXVER_900_CURRENT 0xC
#define PACKAGE2_MINVER_100 0x3
#define PACKAGE2_MINVER_200 0x4
@@ -82,7 +83,8 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(unsigned int targetfw) {
#define PACKAGE2_MINVER_600_610 0x9
#define PACKAGE2_MINVER_620 0xA
#define PACKAGE2_MINVER_700_800 0xB
#define PACKAGE2_MINVER_810_CURRENT 0xC
#define PACKAGE2_MINVER_810 0xC
#define PACKAGE2_MINVER_900_CURRENT 0xD
typedef struct {
union {

214
exosphere/src/pinmux.h Normal file
View File

@@ -0,0 +1,214 @@
/*
* Copyright (c) 2018-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/>.
*/
#ifndef EXOSPHERE_PINMUX_H
#define EXOSPHERE_PINMUX_H
#include <stdint.h>
#include "memory_map.h"
#define PINMUX_BASE (MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MISC) + 0x3000)
#define MAKE_PINMUX_REG(n) MAKE_REG32(PINMUX_BASE + n)
#define PINMUX_TRISTATE (1 << 4)
#define PINMUX_PARKED (1 << 5)
#define PINMUX_INPUT (1 << 6)
#define PINMUX_PULL_NONE (0 << 2)
#define PINMUX_PULL_DOWN (1 << 2)
#define PINMUX_PULL_UP (2 << 2)
#define PINMUX_SELECT_FUNCTION0 0
#define PINMUX_SELECT_FUNCTION1 1
#define PINMUX_SELECT_FUNCTION2 2
#define PINMUX_SELECT_FUNCTION3 3
#define PINMUX_DRIVE_1X (0 << 13)
#define PINMUX_DRIVE_2X (1 << 13)
#define PINMUX_DRIVE_3X (2 << 13)
#define PINMUX_DRIVE_4X (3 << 13)
typedef struct {
uint32_t sdmmc1_clk;
uint32_t sdmmc1_cmd;
uint32_t sdmmc1_dat3;
uint32_t sdmmc1_dat2;
uint32_t sdmmc1_dat1;
uint32_t sdmmc1_dat0;
uint32_t _r18;
uint32_t sdmmc3_clk;
uint32_t sdmmc3_cmd;
uint32_t sdmmc3_dat0;
uint32_t sdmmc3_dat1;
uint32_t sdmmc3_dat2;
uint32_t sdmmc3_dat3;
uint32_t _r34;
uint32_t pex_l0_rst_n;
uint32_t pex_l0_clkreq_n;
uint32_t pex_wake_n;
uint32_t pex_l1_rst_n;
uint32_t pex_l1_clkreq_n;
uint32_t sata_led_active;
uint32_t spi1_mosi;
uint32_t spi1_miso;
uint32_t spi1_sck;
uint32_t spi1_cs0;
uint32_t spi1_cs1;
uint32_t spi2_mosi;
uint32_t spi2_miso;
uint32_t spi2_sck;
uint32_t spi2_cs0;
uint32_t spi2_cs1;
uint32_t spi4_mosi;
uint32_t spi4_miso;
uint32_t spi4_sck;
uint32_t spi4_cs0;
uint32_t qspi_sck;
uint32_t qspi_cs_n;
uint32_t qspi_io0;
uint32_t qspi_io1;
uint32_t qspi_io2;
uint32_t qspi_io3;
uint32_t _ra0;
uint32_t dmic1_clk;
uint32_t dmic1_dat;
uint32_t dmic2_clk;
uint32_t dmic2_dat;
uint32_t dmic3_clk;
uint32_t dmic3_dat;
uint32_t gen1_i2c_scl;
uint32_t gen1_i2c_sda;
uint32_t gen2_i2c_scl;
uint32_t gen2_i2c_sda;
uint32_t gen3_i2c_scl;
uint32_t gen3_i2c_sda;
uint32_t cam_i2c_scl;
uint32_t cam_i2c_sda;
uint32_t pwr_i2c_scl;
uint32_t pwr_i2c_sda;
uint32_t uart1_tx;
uint32_t uart1_rx;
uint32_t uart1_rts;
uint32_t uart1_cts;
uint32_t uart2_tx;
uint32_t uart2_rx;
uint32_t uart2_rts;
uint32_t uart2_cts;
uint32_t uart3_tx;
uint32_t uart3_rx;
uint32_t uart3_rts;
uint32_t uart3_cts;
uint32_t uart4_tx;
uint32_t uart4_rx;
uint32_t uart4_rts;
uint32_t uart4_cts;
uint32_t dap1_fs;
uint32_t dap1_din;
uint32_t dap1_dout;
uint32_t dap1_sclk;
uint32_t dap2_fs;
uint32_t dap2_din;
uint32_t dap2_dout;
uint32_t dap2_sclk;
uint32_t dap4_fs;
uint32_t dap4_din;
uint32_t dap4_dout;
uint32_t dap4_sclk;
uint32_t cam1_mclk;
uint32_t cam2_mclk;
uint32_t jtag_rtck;
uint32_t clk_32k_in;
uint32_t clk_32k_out;
uint32_t batt_bcl;
uint32_t clk_req;
uint32_t cpu_pwr_req;
uint32_t pwr_int_n;
uint32_t shutdown;
uint32_t core_pwr_req;
uint32_t aud_mclk;
uint32_t dvfs_pwm;
uint32_t dvfs_clk;
uint32_t gpio_x1_aud;
uint32_t gpio_x3_aud;
uint32_t pcc7;
uint32_t hdmi_cec;
uint32_t hdmi_int_dp_hpd;
uint32_t spdif_out;
uint32_t spdif_in;
uint32_t usb_vbus_en0;
uint32_t usb_vbus_en1;
uint32_t dp_hpd0;
uint32_t wifi_en;
uint32_t wifi_rst;
uint32_t wifi_wake_ap;
uint32_t ap_wake_bt;
uint32_t bt_rst;
uint32_t bt_wake_ap;
uint32_t ap_wake_nfc;
uint32_t nfc_en;
uint32_t nfc_int;
uint32_t gps_en;
uint32_t gps_rst;
uint32_t cam_rst;
uint32_t cam_af_en;
uint32_t cam_flash_en;
uint32_t cam1_pwdn;
uint32_t cam2_pwdn;
uint32_t cam1_strobe;
uint32_t lcd_te;
uint32_t lcd_bl_pwm;
uint32_t lcd_bl_en;
uint32_t lcd_rst;
uint32_t lcd_gpio1;
uint32_t lcd_gpio2;
uint32_t ap_ready;
uint32_t touch_rst;
uint32_t touch_clk;
uint32_t modem_wake_ap;
uint32_t touch_int;
uint32_t motion_int;
uint32_t als_prox_int;
uint32_t temp_alert;
uint32_t button_power_on;
uint32_t button_vol_up;
uint32_t button_vol_down;
uint32_t button_slide_sw;
uint32_t button_home;
uint32_t pa6;
uint32_t pe6;
uint32_t pe7;
uint32_t ph6;
uint32_t pk0;
uint32_t pk1;
uint32_t pk2;
uint32_t pk3;
uint32_t pk4;
uint32_t pk5;
uint32_t pk6;
uint32_t pk7;
uint32_t pl0;
uint32_t pl1;
uint32_t pz0;
uint32_t pz1;
uint32_t pz2;
uint32_t pz3;
uint32_t pz4;
uint32_t pz5;
} tegra_pinmux_t;
static inline volatile tegra_pinmux_t *pinmux_get_regs(void)
{
return (volatile tegra_pinmux_t *)PINMUX_BASE;
}
#endif

View File

@@ -13,7 +13,7 @@
* 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 <stdint.h>
#include <stdbool.h>
#include <string.h>
@@ -77,6 +77,7 @@ static void enable_lp0_wake_events(void) {
static void notify_pmic_shutdown(void) {
clkrst_reboot(CARDEVICE_I2C5);
i2c_init(I2C_5);
if (fuse_get_bootrom_patch_version() >= 0x7F) {
i2c_send_pmic_cpu_shutdown_cmd();
}
@@ -132,7 +133,7 @@ static void setup_bpmp_sc7_firmware(void) {
BPMP_VECTOR_UNK = 0x40003004; /* Reboot. */
BPMP_VECTOR_IRQ = 0x40003004; /* Reboot. */
BPMP_VECTOR_FIQ = 0x40003004; /* Reboot. */
/* Hold the BPMP in reset. */
MAKE_CAR_REG(0x300) = 2;
@@ -141,7 +142,7 @@ static void setup_bpmp_sc7_firmware(void) {
for (unsigned int i = 0; i < sc7fw_bin_size; i += 4) {
write32le(lp0_entry_code, i, read32le(sc7fw_bin, i));
}
flush_dcache_range(lp0_entry_code, lp0_entry_code + sc7fw_bin_size);
/* Take the BPMP out of reset. */
@@ -181,7 +182,7 @@ static void save_tzram_state(void) {
flush_dcache_range(tzram_encryption_dst, tzram_encryption_dst + LP0_TZRAM_SAVE_SIZE);
flush_dcache_range(tzram_encryption_src, tzram_encryption_src + LP0_TZRAM_SAVE_SIZE);
/* Use the all-zero cmac buffer as an IV. */
/* Use the all-zero cmac buffer as an IV. */
se_aes_256_cbc_encrypt(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_encryption_dst, LP0_TZRAM_SAVE_SIZE, tzram_encryption_src, LP0_TZRAM_SAVE_SIZE, tzram_cmac);
flush_dcache_range(tzram_encryption_dst, tzram_encryption_dst + LP0_TZRAM_SAVE_SIZE);
@@ -189,12 +190,12 @@ static void save_tzram_state(void) {
for (unsigned int i = 0; i < LP0_TZRAM_SAVE_SIZE; i += 4) {
write32le(tzram_store_address, i, read32le(tzram_encryption_dst, i));
}
flush_dcache_range(tzram_store_address, tzram_store_address + LP0_TZRAM_SAVE_SIZE);
/* Compute CMAC. */
se_compute_aes_256_cmac(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_cmac, sizeof(tzram_cmac), tzram_encryption_src, LP0_TZRAM_SAVE_SIZE);
/* Write CMAC, lock registers. */
APBDEV_PMC_SECURE_SCRATCH112_0 = tzram_cmac[0];
APBDEV_PMC_SECURE_SCRATCH113_0 = tzram_cmac[1];
@@ -240,7 +241,7 @@ void save_se_and_power_down_cpu(void) {
/* Save context for warmboot to restore. */
save_tzram_state();
save_se_state();
/* Patch the bootrom to disable warmboot signature checks. */
MAKE_REG32(PMC_BASE + 0x118) = 0x2202E012;
MAKE_REG32(PMC_BASE + 0x11C) = 0x6001DC28;
@@ -248,14 +249,14 @@ void save_se_and_power_down_cpu(void) {
if (!configitem_is_retail()) {
uart_send(UART_A, "OYASUMI", 8);
}
finalize_powerdown();
}
uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argument) {
/* TODO: 6.0.0 introduces heavy deja vu mitigations. */
/* Exosphere may want to implement these. */
/* Ensure SMC call is to enter deep sleep. */
if ((power_state & 0x17FFF) != 0x1001B) {
return 0xFFFFFFFD;
@@ -285,7 +286,7 @@ uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argumen
/* Prepare the current core for sleep. */
configure_flow_regs_for_sleep();
/* Save core context. */
set_core_entrypoint_and_argument(get_core_id(), entrypoint, argument);
save_current_core_context();

View File

@@ -186,6 +186,7 @@ void set_version_specific_smcs(void) {
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900:
/* No more LoadSecureExpModKey. */
g_smc_user_table[0xE].handler = NULL;
g_smc_user_table[0xC].id = 0xC300D60C;

View File

@@ -53,6 +53,7 @@ static bool is_user_keyslot_valid(unsigned int keyslot) {
case ATMOSPHERE_TARGET_FIRMWARE_700:
case ATMOSPHERE_TARGET_FIRMWARE_800:
case ATMOSPHERE_TARGET_FIRMWARE_810:
case ATMOSPHERE_TARGET_FIRMWARE_900:
default:
return keyslot <= 5;
}

View File

@@ -15,66 +15,120 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "timers.h"
#include "uart.h"
#include "misc.h"
#include "timers.h"
#include "pinmux.h"
void uart_select(UartDevice dev) {
unsigned int id = (unsigned int)dev;
PINMUX_AUX_UARTn_TX_0(id) = 0; /* UART */
PINMUX_AUX_UARTn_RX_0(id) = 0x48; /* UART, enable, pull up */
PINMUX_AUX_UARTn_RTS_0(id) = 0; /* UART */
PINMUX_AUX_UARTn_CTS_0(id) = 0x44; /* UART, enable, pull down */
static inline void uart_wait_cycles(uint32_t baud, uint32_t num)
{
wait((num * 1000000 + 16 * baud - 1) / (16 * baud));
}
static inline void uart_wait_syms(uint32_t baud, uint32_t num)
{
wait((num * 1000000 + baud - 1) / baud);
}
void uart_config(UartDevice dev) {
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
switch (dev) {
case UART_A:
pinmux->uart1_tx = 0;
pinmux->uart1_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
pinmux->uart1_rts = 0;
pinmux->uart1_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
break;
case UART_B:
pinmux->uart2_tx = 0;
pinmux->uart2_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
pinmux->uart2_rts = 0;
pinmux->uart2_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
break;
case UART_C:
pinmux->uart3_tx = 0;
pinmux->uart3_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
pinmux->uart3_rts = 0;
pinmux->uart3_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
break;
case UART_D:
pinmux->uart4_tx = 0;
pinmux->uart4_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
pinmux->uart4_rts = 0;
pinmux->uart4_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
break;
case UART_E:
/* Unused. */
break;
default: break;
}
}
void uart_init(UartDevice dev, uint32_t baud) {
volatile uart_t *uart = get_uart_device(dev);
volatile tegra_uart_t *uart = uart_get_regs(dev);
/* Set baud rate. */
/* Wait for idle state. */
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE);
/* Calculate baud rate, round to nearest. */
uint32_t rate = (8 * baud + 408000000) / (16 * baud);
uart->UART_LCR = UART_LCR_DLAB; /* Enable DLAB. */
uart->UART_THR_DLAB = (uint8_t)rate; /* Divisor latch LSB. */
uart->UART_IER_DLAB = (uint8_t)(rate >> 8); /* Divisor latch MSB. */
uart->UART_LCR = 0; /* Diable DLAB. */
/* Setup UART in fifo mode. */
/* Setup UART in FIFO mode. */
uart->UART_IER_DLAB = 0;
uart->UART_IIR_FCR = UART_FCR_FCR_EN_FIFO | UART_FCR_RX_CLR | UART_FCR_TX_CLR; /* Enable and clear TX and RX FIFOs. */
uart->UART_LSR;
wait(3 * ((baud + 999999) / baud));
uart->UART_LCR = UART_LCR_WD_LENGTH_8; /* Set word length 8. */
uart->UART_MCR = 0;
uart->UART_MSR = 0;
uart->UART_IRDA_CSR = 0;
uart->UART_RX_FIFO_CFG = 1; /* Set RX_FIFO trigger level */
uart->UART_MIE = 0;
uart->UART_ASR = 0;
uart->UART_LCR = (UART_LCR_DLAB | UART_LCR_WD_LENGTH_8); /* Enable DLAB and set word length 8. */
uart->UART_THR_DLAB = (uint8_t)rate; /* Divisor latch LSB. */
uart->UART_IER_DLAB = (uint8_t)(rate >> 8); /* Divisor latch MSB. */
uart->UART_LCR &= ~(UART_LCR_DLAB); /* Disable DLAB. */
uart->UART_SPR; /* Dummy read. */
uart_wait_syms(baud, 3); /* Wait for 3 symbols at the new baudrate. */
/* Enable FIFO with default settings. */
uart->UART_IIR_FCR = UART_FCR_FCR_EN_FIFO;
uart->UART_SPR; /* Dummy read as mandated by TRM. */
uart_wait_cycles(baud, 3); /* Wait for 3 baud cycles, as mandated by TRM (erratum). */
/* Flush FIFO. */
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE); /* Make sure there's no data being written in TX FIFO (TRM). */
uart->UART_IIR_FCR |= UART_FCR_RX_CLR | UART_FCR_TX_CLR; /* Clear TX and RX FIFOs. */
uart_wait_cycles(baud, 32); /* Wait for 32 baud cycles (TRM, erratum). */
/* Wait for idle state (TRM). */
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE | UART_VENDOR_STATE_RX_IDLE);
}
/* This function blocks until the UART device (dev) is in the desired state (status). Make sure the desired state can be reached! */
/* This function blocks until the UART device is in the desired state. */
void uart_wait_idle(UartDevice dev, UartVendorStatus status) {
while (!(get_uart_device(dev)->UART_VENDOR_STATUS & status)) {
/* Wait */
volatile tegra_uart_t *uart = uart_get_regs(dev);
if (status & UART_VENDOR_STATE_TX_IDLE) {
while (!(uart->UART_LSR & UART_LSR_TMTY)) {
/* Wait */
}
}
if (status & UART_VENDOR_STATE_RX_IDLE) {
while (uart->UART_LSR & UART_LSR_RDR) {
/* Wait */
}
}
}
void uart_send(UartDevice dev, const void *buf, size_t len) {
volatile uart_t *uart = get_uart_device(dev);
volatile tegra_uart_t *uart = uart_get_regs(dev);
for (size_t i = 0; i < len; i++) {
while (uart->UART_LSR & UART_LSR_TX_FIFO_FULL) {
/* Wait until the TX FIFO isn't full */
while (!(uart->UART_LSR & UART_LSR_THRE)) {
/* Wait until it's possible to send data. */
}
uart->UART_THR_DLAB = *((const uint8_t *)buf + i);
}
}
void uart_recv(UartDevice dev, void *buf, size_t len) {
volatile uart_t *uart = get_uart_device(dev);
volatile tegra_uart_t *uart = uart_get_regs(dev);
for (size_t i = 0; i < len; i++) {
while (uart->UART_LSR & UART_LSR_RX_FIFO_EMPTY) {
/* Wait until the RX FIFO isn't empty */
while (!(uart->UART_LSR & UART_LSR_RDR)) {
/* Wait until it's possible to receive data. */
}
*((uint8_t *)buf + i) = uart->UART_THR_DLAB;
}

View File

@@ -31,7 +31,7 @@ static inline uintptr_t get_uart_base(void) {
#define BAUD_115200 115200
/* Exosphère: add the clkreset values for UART C,D,E */
/* UART devices */
typedef enum {
UART_A = 0,
UART_B = 1,
@@ -148,31 +148,31 @@ typedef enum {
} UartInterruptIdentification;
typedef struct {
/* 0x00 */ uint32_t UART_THR_DLAB;
/* 0x04 */ uint32_t UART_IER_DLAB;
/* 0x08 */ uint32_t UART_IIR_FCR;
/* 0x0C */ uint32_t UART_LCR;
/* 0x10 */ uint32_t UART_MCR;
/* 0x14 */ uint32_t UART_LSR;
/* 0x18 */ uint32_t UART_MSR;
/* 0x1C */ uint32_t UART_SPR;
/* 0x20 */ uint32_t UART_IRDA_CSR;
/* 0x24 */ uint32_t UART_RX_FIFO_CFG;
/* 0x28 */ uint32_t UART_MIE;
/* 0x2C */ uint32_t UART_VENDOR_STATUS;
/* 0x30 */ uint8_t _pad_30[0x0C];
/* 0x3C */ uint32_t UART_ASR;
} uart_t;
uint32_t UART_THR_DLAB;
uint32_t UART_IER_DLAB;
uint32_t UART_IIR_FCR;
uint32_t UART_LCR;
uint32_t UART_MCR;
uint32_t UART_LSR;
uint32_t UART_MSR;
uint32_t UART_SPR;
uint32_t UART_IRDA_CSR;
uint32_t UART_RX_FIFO_CFG;
uint32_t UART_MIE;
uint32_t UART_VENDOR_STATUS;
uint8_t _0x30[0x0C];
uint32_t UART_ASR;
} tegra_uart_t;
void uart_select(UartDevice dev);
void uart_config(UartDevice dev);
void uart_init(UartDevice dev, uint32_t baud);
void uart_wait_idle(UartDevice dev, UartVendorStatus status);
void uart_send(UartDevice dev, const void *buf, size_t len);
void uart_recv(UartDevice dev, void *buf, size_t len);
static inline volatile uart_t *get_uart_device(UartDevice dev) {
static inline volatile tegra_uart_t *uart_get_regs(UartDevice dev) {
static const size_t offsets[] = {0, 0x40, 0x200, 0x300, 0x400};
return (volatile uart_t *)(UART_BASE + offsets[dev]);
return (volatile tegra_uart_t *)(UART_BASE + offsets[dev]);
}
#endif

View File

@@ -24,7 +24,6 @@
#include "bootup.h"
#include "smc_api.h"
#include "exocfg.h"
#include "se.h"
#include "mc.h"
#include "car.h"
@@ -32,7 +31,6 @@
#include "misc.h"
#include "uart.h"
#include "interrupt.h"
#include "pmc.h"
uintptr_t get_warmboot_main_stack_address(void) {
@@ -41,8 +39,7 @@ uintptr_t get_warmboot_main_stack_address(void) {
static void warmboot_configure_hiz_mode(void) {
/* Enable input to I2C1 */
PINMUX_AUX_GEN1_I2C_SCL_0 = 0x40;
PINMUX_AUX_GEN1_I2C_SDA_0 = 0x40;
i2c_config(I2C_1);
clkrst_reboot(CARDEVICE_I2C1);
i2c_init(0);
@@ -69,7 +66,7 @@ void __attribute__((noreturn)) warmboot_main(void) {
if (VIRT_MC_SECURITY_CFG3 == 0) {
/* N only does this on dev units, but we will do it unconditionally. */
{
uart_select(UART_A);
uart_config(UART_A);
clkrst_reboot(CARDEVICE_UARTA);
uart_init(UART_A, 115200);
}

View File

@@ -1,4 +1,4 @@
SUBFOLDERS := fusee-primary fusee-secondary
SUBFOLDERS := fusee-primary fusee-mtc fusee-secondary
TOPTARGETS := all clean

163
fusee/fusee-mtc/Makefile Normal file
View File

@@ -0,0 +1,163 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
TOPDIR ?= $(CURDIR)
AMS := $(TOPDIR)/../../
include $(DEVKITARM)/base_rules
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
AMSREV := $(AMSREV)-dirty
endif
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := src src/lib src/display
DATA := data
INCLUDES := include
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
CFLAGS := \
-g \
-O2 \
-fomit-frame-pointer \
-ffunction-sections \
-fdata-sections \
-std=gnu11 \
-Werror \
-Wall \
-fstrict-volatile-bitfields \
$(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS :=
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS :=
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
.PHONY: $(BUILD) clean all
#---------------------------------------------------------------------------------
all: $(BUILD)
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
#---------------------------------------------------------------------------------
else
.PHONY: all
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
all : $(OUTPUT).bin
$(OUTPUT).bin : $(OUTPUT).elf
$(OBJCOPY) -S -O binary $< $@
@echo built ... $(notdir $@)
$(OUTPUT).elf : $(OFILES)
%.elf: $(OFILES)
@echo linking $(notdir $@)
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
@$(NM) -CSn $@ > $(notdir $*.lst)
$(OFILES_SRC) : $(HFILES_BIN)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o %_bin.h: %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

170
fusee/fusee-mtc/linker.ld Normal file
View File

@@ -0,0 +1,170 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
PHDRS
{
crt0 PT_LOAD;
main PT_LOAD;
}
/* Mostly copied from https://github.com/devkitPro/buildscripts/blob/master/dkarm-eabi/crtls/3dsx.ld */
MEMORY
{
NULL : ORIGIN = 0x00000000, LENGTH = 0x1000
main : ORIGIN = 0xF0000000, LENGTH = 0x10000000
}
SECTIONS
{
PROVIDE(__start__ = 0xF0000000);
PROVIDE(__stack_bottom__ = 0x90010000);
PROVIDE(__stack_top__ = 0x90020000);
PROVIDE(__heap_start__ = 0x90020000);
PROVIDE(__heap_end__ = 0xA0020000);
. = __start__;
.crt0 :
{
KEEP( *(.text.start) )
KEEP( *(.init) )
. = ALIGN(32);
} >main :crt0
.text :
{
. = ALIGN(32);
/* .text */
*(.text)
*(.text.*)
*(.glue_7)
*(.glue_7t)
*(.stub)
*(.gnu.warning)
*(.gnu.linkonce.t*)
/* .fini */
KEEP( *(.fini) )
. = ALIGN(8);
} >main :main
.rodata :
{
*(.rodata)
*(.roda)
*(.rodata.*)
*all.rodata*(*)
*(.gnu.linkonce.r*)
SORT(CONSTRUCTORS)
. = ALIGN(8);
} >main
.preinit_array :
{
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
} >main
.init_array ALIGN(4) :
{
PROVIDE (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
} >main
.fini_array ALIGN(4) :
{
PROVIDE (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE (__fini_array_end = .);
} >main
.ctors ALIGN(4) :
{
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >main
.dtors ALIGN(4) :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >main
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) __exidx_start = ABSOLUTE(.);} >main
ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = ABSOLUTE(.);} >main
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
. = ALIGN(32);
} >main
.bss (NOLOAD) :
{
. = ALIGN(32);
PROVIDE (__bss_start__ = ABSOLUTE(.));
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b*)
*(COMMON)
. = ALIGN(32);
PROVIDE (__bss_end__ = ABSOLUTE(.));
} >main :NONE
__end__ = ABSOLUTE(.) ;
/* ==================
==== Metadata ====
================== */
/* Discard sections that difficult post-processing */
/DISCARD/ : { *(.group .comment .note) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}

View File

@@ -0,0 +1,7 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /linker.ld) --nmagic --gc-sections
*startfile:
crti%O%s crtbegin%O%s

139
fusee/fusee-mtc/src/car.c Normal file
View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2018-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 "car.h"
#include "timers.h"
#include "utils.h"
static inline uint32_t get_clk_source_reg(CarDevice dev) {
switch (dev) {
case CARDEVICE_UARTA: return 0x178;
case CARDEVICE_UARTB: return 0x17C;
case CARDEVICE_UARTC: return 0x1A0;
case CARDEVICE_I2C1: return 0x124;
case CARDEVICE_I2C5: return 0x128;
case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0x42C;
case CARDEVICE_HOST1X: return 0x180;
case CARDEVICE_TSEC: return 0x1F4;
case CARDEVICE_SOR_SAFE: return 0;
case CARDEVICE_SOR0: return 0;
case CARDEVICE_SOR1: return 0x410;
case CARDEVICE_KFUSE: return 0;
case CARDEVICE_CL_DVFS: return 0;
case CARDEVICE_CORESIGHT: return 0x1D4;
case CARDEVICE_ACTMON: return 0x3E8;
case CARDEVICE_BPMP: return 0;
default: generic_panic();
}
}
static inline uint32_t get_clk_source_val(CarDevice dev) {
switch (dev) {
case CARDEVICE_UARTA: return 0;
case CARDEVICE_UARTB: return 0;
case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 6;
case CARDEVICE_I2C5: return 6;
case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 4;
case CARDEVICE_TSEC: return 0;
case CARDEVICE_SOR_SAFE: return 0;
case CARDEVICE_SOR0: return 0;
case CARDEVICE_SOR1: return 0;
case CARDEVICE_KFUSE: return 0;
case CARDEVICE_CL_DVFS: return 0;
case CARDEVICE_CORESIGHT: return 0;
case CARDEVICE_ACTMON: return 6;
case CARDEVICE_BPMP: return 0;
default: generic_panic();
}
}
static inline uint32_t get_clk_source_div(CarDevice dev) {
switch (dev) {
case CARDEVICE_UARTA: return 0;
case CARDEVICE_UARTB: return 0;
case CARDEVICE_UARTC: return 0;
case CARDEVICE_I2C1: return 0;
case CARDEVICE_I2C5: return 0;
case CARDEVICE_TZRAM: return 0;
case CARDEVICE_SE: return 0;
case CARDEVICE_HOST1X: return 3;
case CARDEVICE_TSEC: return 2;
case CARDEVICE_SOR_SAFE: return 0;
case CARDEVICE_SOR0: return 0;
case CARDEVICE_SOR1: return 2;
case CARDEVICE_KFUSE: return 0;
case CARDEVICE_CL_DVFS: return 0;
case CARDEVICE_CORESIGHT: return 4;
case CARDEVICE_ACTMON: return 0;
case CARDEVICE_BPMP: return 0;
default: generic_panic();
}
}
static uint32_t g_clk_reg_offsets[NUM_CAR_BANKS] = {0x010, 0x014, 0x018, 0x360, 0x364, 0x280, 0x298};
static uint32_t g_rst_reg_offsets[NUM_CAR_BANKS] = {0x004, 0x008, 0x00C, 0x358, 0x35C, 0x28C, 0x2A4};
void clk_enable(CarDevice dev) {
uint32_t clk_source_reg;
if ((clk_source_reg = get_clk_source_reg(dev))) {
MAKE_CAR_REG(clk_source_reg) = (get_clk_source_val(dev) << 29) | get_clk_source_div(dev);
}
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
}
void clk_disable(CarDevice dev) {
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
}
void rst_enable(CarDevice dev) {
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
}
void rst_disable(CarDevice dev) {
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
}
void clkrst_enable(CarDevice dev) {
clk_enable(dev);
rst_disable(dev);
}
void clkrst_disable(CarDevice dev) {
rst_enable(dev);
clk_disable(dev);
}
void clkrst_reboot(CarDevice dev) {
clkrst_disable(dev);
if (dev == CARDEVICE_KFUSE) {
/* Workaround for KFUSE clock. */
clk_enable(dev);
udelay(100);
rst_disable(dev);
udelay(200);
} else {
clkrst_enable(dev);
}
}
void clkrst_enable_fuse_regs(bool enable) {
volatile tegra_car_t *car = car_get_regs();
car->misc_clk_enb = ((car->misc_clk_enb & 0xEFFFFFFF) | ((enable & 1) << 28));
}

505
fusee/fusee-mtc/src/car.h Normal file
View File

@@ -0,0 +1,505 @@
/*
* Copyright (c) 2018-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/>.
*/
#ifndef FUSEE_CAR_H
#define FUSEE_CAR_H
#include <stdint.h>
#include <stdbool.h>
#define CAR_BASE 0x60006000
#define MAKE_CAR_REG(n) MAKE_REG32(CAR_BASE + n)
#define CLK_L_SDMMC1 (1 << 14)
#define CLK_L_SDMMC2 (1 << 9)
#define CLK_U_SDMMC3 (1 << 5)
#define CLK_L_SDMMC4 (1 << 15)
#define CLK_SOURCE_MASK (0b111 << 29)
#define CLK_SOURCE_FIRST (0b000 << 29)
#define CLK_DIVIDER_MASK (0xff << 0)
#define CLK_DIVIDER_UNITY (0x00 << 0)
#define NUM_CAR_BANKS 7
/* Clock and reset devices. */
typedef enum {
CARDEVICE_UARTA = ((0 << 5) | 0x6),
CARDEVICE_UARTB = ((0 << 5) | 0x7),
CARDEVICE_UARTC = ((1 << 5) | 0x17),
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
CARDEVICE_SE = ((3 << 5) | 0x1F),
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
CARDEVICE_TSEC = ((2 << 5) | 0x13),
CARDEVICE_SOR_SAFE = ((6 << 5) | 0x1E),
CARDEVICE_SOR0 = ((5 << 5) | 0x16),
CARDEVICE_SOR1 = ((5 << 5) | 0x17),
CARDEVICE_KFUSE = ((1 << 5) | 0x8),
CARDEVICE_CL_DVFS = ((4 << 5) | 0x1B),
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
CARDEVICE_BPMP = ((0 << 5) | 0x1)
} CarDevice;
/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
typedef struct {
uint32_t rst_src; /* _RST_SOURCE_0, 0x00 */
/* _RST_DEVICES_L/H/U_0 0x4-0xc */
uint32_t rst_dev_l;
uint32_t rst_dev_h;
uint32_t rst_dev_u;
/* _CLK_OUT_ENB_L/H/U_0 0x10-0x18 */
uint32_t clk_out_enb_l;
uint32_t clk_out_enb_h;
uint32_t clk_out_enb_u;
uint32_t _0x1C;
uint32_t cclk_brst_pol; /* _CCLK_BURST_POLICY_0, 0x20 */
uint32_t super_cclk_div; /* _SUPER_CCLK_DIVIDER_0, 0x24 */
uint32_t sclk_brst_pol; /* _SCLK_BURST_POLICY_0, 0x28 */
uint32_t super_sclk_div; /* _SUPER_SCLK_DIVIDER_0, 0x2c */
uint32_t clk_sys_rate; /* _CLK_SYSTEM_RATE_0, 0x30 */
uint32_t prog_dly_clk; /* _PROG_DLY_CLK_0, 0x34 */
uint32_t aud_sync_clk_rate; /* _AUDIO_SYNC_CLK_RATE_0, 0x38 */
uint32_t _0x3C;
uint32_t cop_clk_skip_plcy; /* _COP_CLK_SKIP_POLICY_0, 0x40 */
uint32_t clk_mask_arm; /* _CLK_MASK_ARM_0, 0x44 */
uint32_t misc_clk_enb; /* _MISC_CLK_ENB_0, 0x48 */
uint32_t clk_cpu_cmplx; /* _CLK_CPU_CMPLX_0, 0x4c */
uint32_t osc_ctrl; /* _OSC_CTRL_0, 0x50 */
uint32_t pll_lfsr; /* _PLL_LFSR_0, 0x54 */
uint32_t osc_freq_det; /* _OSC_FREQ_DET_0, 0x58 */
uint32_t osc_freq_det_stat; /* _OSC_FREQ_DET_STATUS_0, 0x5c */
uint32_t _0x60[2];
uint32_t plle_ss_cntl; /* _PLLE_SS_CNTL_0, 0x68 */
uint32_t plle_misc1; /* _PLLE_MISC1_0, 0x6c */
uint32_t _0x70[4];
/* PLLC 0x80-0x8c */
uint32_t pllc_base;
uint32_t pllc_out;
uint32_t pllc_misc0;
uint32_t pllc_misc1;
/* PLLM 0x90-0x9c */
uint32_t pllm_base;
uint32_t pllm_out;
uint32_t pllm_misc1;
uint32_t pllm_misc2;
/* PLLP 0xa0-0xac */
uint32_t pllp_base;
uint32_t pllp_outa;
uint32_t pllp_outb;
uint32_t pllp_misc;
/* PLLA 0xb0-0xbc */
uint32_t plla_base;
uint32_t plla_out;
uint32_t plla_misc0;
uint32_t plla_misc1;
/* PLLU 0xc0-0xcc */
uint32_t pllu_base;
uint32_t pllu_out;
uint32_t pllu_misc1;
uint32_t pllu_misc2;
/* PLLD 0xd0-0xdc */
uint32_t plld_base;
uint32_t plld_out;
uint32_t plld_misc1;
uint32_t plld_misc2;
/* PLLX 0xe0-0xe4 */
uint32_t pllx_base;
uint32_t pllx_misc;
/* PLLE 0xe8-0xf4 */
uint32_t plle_base;
uint32_t plle_misc;
uint32_t plle_ss_cntl1;
uint32_t plle_ss_cntl2;
uint32_t lvl2_clk_gate_ovra; /* _LVL2_CLK_GATE_OVRA_0, 0xf8 */
uint32_t lvl2_clk_gate_ovrb; /* _LVL2_CLK_GATE_OVRB_0, 0xfc */
uint32_t clk_source_i2s2; /* _CLK_SOURCE_I2S2_0, 0x100 */
uint32_t clk_source_i2s3; /* _CLK_SOURCE_I2S3_0, 0x104 */
uint32_t clk_source_spdif_out; /* _CLK_SOURCE_SPDIF_OUT_0, 0x108 */
uint32_t clk_source_spdif_in; /* _CLK_SOURCE_SPDIF_IN_0, 0x10c */
uint32_t clk_source_pwm; /* _CLK_SOURCE_PWM_0, 0x110 */
uint32_t _0x114;
uint32_t clk_source_spi2; /* _CLK_SOURCE_SPI2_0, 0x118 */
uint32_t clk_source_spi3; /* _CLK_SOURCE_SPI3_0, 0x11c */
uint32_t _0x120;
uint32_t clk_source_i2c1; /* _CLK_SOURCE_I2C1_0, 0x124 */
uint32_t clk_source_i2c5; /* _CLK_SOURCE_I2C5_0, 0x128 */
uint32_t _0x12c[2];
uint32_t clk_source_spi1; /* _CLK_SOURCE_SPI1_0, 0x134 */
uint32_t clk_source_disp1; /* _CLK_SOURCE_DISP1_0, 0x138 */
uint32_t clk_source_disp2; /* _CLK_SOURCE_DISP2_0, 0x13c */
uint32_t _0x140;
uint32_t clk_source_isp; /* _CLK_SOURCE_ISP_0, 0x144 */
uint32_t clk_source_vi; /* _CLK_SOURCE_VI_0, 0x148 */
uint32_t _0x14c;
uint32_t clk_source_sdmmc1; /* _CLK_SOURCE_SDMMC1_0, 0x150 */
uint32_t clk_source_sdmmc2; /* _CLK_SOURCE_SDMMC2_0, 0x154 */
uint32_t _0x158[3];
uint32_t clk_source_sdmmc4; /* _CLK_SOURCE_SDMMC4_0, 0x164 */
uint32_t _0x168[4];
uint32_t clk_source_uarta; /* _CLK_SOURCE_UARTA_0, 0x178 */
uint32_t clk_source_uartb; /* _CLK_SOURCE_UARTB_0, 0x17c */
uint32_t clk_source_host1x; /* _CLK_SOURCE_HOST1X_0, 0x180 */
uint32_t _0x184[5];
uint32_t clk_source_i2c2; /* _CLK_SOURCE_I2C2_0, 0x198 */
uint32_t clk_source_emc; /* _CLK_SOURCE_EMC_0, 0x19c */
uint32_t clk_source_uartc; /* _CLK_SOURCE_UARTC_0, 0x1a0 */
uint32_t _0x1a4;
uint32_t clk_source_vi_sensor; /* _CLK_SOURCE_VI_SENSOR_0, 0x1a8 */
uint32_t _0x1ac[2];
uint32_t clk_source_spi4; /* _CLK_SOURCE_SPI4_0, 0x1b4 */
uint32_t clk_source_i2c3; /* _CLK_SOURCE_I2C3_0, 0x1b8 */
uint32_t clk_source_sdmmc3; /* _CLK_SOURCE_SDMMC3_0, 0x1bc */
uint32_t clk_source_uartd; /* _CLK_SOURCE_UARTD_0, 0x1c0 */
uint32_t _0x1c4[2];
uint32_t clk_source_owr; /* _CLK_SOURCE_OWR_0, 0x1cc */
uint32_t _0x1d0;
uint32_t clk_source_csite; /* _CLK_SOURCE_CSITE_0, 0x1d4 */
uint32_t clk_source_i2s1; /* _CLK_SOURCE_I2S1_0, 0x1d8 */
uint32_t clk_source_dtv; /* _CLK_SOURCE_DTV_0, 0x1dc */
uint32_t _0x1e0[5];
uint32_t clk_source_tsec; /* _CLK_SOURCE_TSEC_0, 0x1f4 */
uint32_t _0x1f8;
uint32_t clk_spare2; /* _CLK_SPARE2_0, 0x1fc */
uint32_t _0x200[32];
uint32_t clk_out_enb_x; /* _CLK_OUT_ENB_X_0, 0x280 */
uint32_t clk_enb_x_set; /* _CLK_ENB_X_SET_0, 0x284 */
uint32_t clk_enb_x_clr; /* _CLK_ENB_X_CLR_0, 0x288 */
uint32_t rst_devices_x; /* _RST_DEVICES_X_0, 0x28c */
uint32_t rst_dev_x_set; /* _RST_DEV_X_SET_0, 0x290 */
uint32_t rst_dev_x_clr; /* _RST_DEV_X_CLR_0, 0x294 */
uint32_t clk_out_enb_y; /* _CLK_OUT_ENB_Y_0, 0x298 */
uint32_t clk_enb_y_set; /* _CLK_ENB_Y_SET_0, 0x29c */
uint32_t clk_enb_y_clr; /* _CLK_ENB_Y_CLR_0, 0x2a0 */
uint32_t rst_devices_y; /* _RST_DEVICES_Y_0, 0x2a4 */
uint32_t rst_dev_y_set; /* _RST_DEV_Y_SET_0, 0x2a8 */
uint32_t rst_dev_y_clr; /* _RST_DEV_Y_CLR_0, 0x2ac */
uint32_t _0x2b0[17];
uint32_t dfll_base; /* _DFLL_BASE_0, 0x2f4 */
uint32_t _0x2f8[2];
/* _RST_DEV_L/H/U_SET_0 0x300-0x314 */
uint32_t rst_dev_l_set;
uint32_t rst_dev_l_clr;
uint32_t rst_dev_h_set;
uint32_t rst_dev_h_clr;
uint32_t rst_dev_u_set;
uint32_t rst_dev_u_clr;
uint32_t _0x318[2];
/* _CLK_ENB_L/H/U_CLR_0 0x320-0x334 */
uint32_t clk_enb_l_set;
uint32_t clk_enb_l_clr;
uint32_t clk_enb_h_set;
uint32_t clk_enb_h_clr;
uint32_t clk_enb_u_set;
uint32_t clk_enb_u_clr;
uint32_t _0x338;
uint32_t ccplex_pg_sm_ovrd; /* _CCPLEX_PG_SM_OVRD_0, 0x33c */
uint32_t rst_cpu_cmplx_set; /* _RST_CPU_CMPLX_SET_0, 0x340 */
uint32_t rst_cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR_0, 0x344 */
/* Additional (T30) registers */
uint32_t clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET_0, 0x348 */
uint32_t clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET_0, 0x34c */
uint32_t _0x350[2];
uint32_t rst_dev_v; /* _RST_DEVICES_V_0, 0x358 */
uint32_t rst_dev_w; /* _RST_DEVICES_W_0, 0x35c */
uint32_t clk_out_enb_v; /* _CLK_OUT_ENB_V_0, 0x360 */
uint32_t clk_out_enb_w; /* _CLK_OUT_ENB_W_0, 0x364 */
uint32_t cclkg_brst_pol; /* _CCLKG_BURST_POLICY_0, 0x368 */
uint32_t super_cclkg_div; /* _SUPER_CCLKG_DIVIDER_0, 0x36c */
uint32_t cclklp_brst_pol; /* _CCLKLP_BURST_POLICY_0, 0x370 */
uint32_t super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER_0, 0x374 */
uint32_t clk_cpug_cmplx; /* _CLK_CPUG_CMPLX_0, 0x378 */
uint32_t clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX_0, 0x37c */
uint32_t cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL_0, 0x380 */
uint32_t cpu_softrst_ctrl1; /* _CPU_SOFTRST_CTRL1_0, 0x384 */
uint32_t cpu_softrst_ctrl2; /* _CPU_SOFTRST_CTRL2_0, 0x388 */
uint32_t _0x38c[5];
uint32_t lvl2_clk_gate_ovrc; /* _LVL2_CLK_GATE_OVRC, 0x3a0 */
uint32_t lvl2_clk_gate_ovrd; /* _LVL2_CLK_GATE_OVRD, 0x3a4 */
uint32_t _0x3a8[2];
uint32_t _0x3b0;
uint32_t clk_source_mselect; /* _CLK_SOURCE_MSELECT_0, 0x3b4 */
uint32_t clk_source_tsensor; /* _CLK_SOURCE_TSENSOR_0, 0x3b8 */
uint32_t clk_source_i2s4; /* _CLK_SOURCE_I2S4_0, 0x3bc */
uint32_t clk_source_i2s5; /* _CLK_SOURCE_I2S5_0, 0x3c0 */
uint32_t clk_source_i2c4; /* _CLK_SOURCE_I2C4_0, 0x3c4 */
uint32_t _0x3c8[2];
uint32_t clk_source_ahub; /* _CLK_SOURCE_AHUB_0, 0x3d0 */
uint32_t _0x3d4[4];
uint32_t clk_source_hda2codec_2x; /* _CLK_SOURCE_HDA2CODEC_2X_0, 0x3e4 */
uint32_t clk_source_actmon; /* _CLK_SOURCE_ACTMON_0, 0x3e8 */
uint32_t clk_source_extperiph1; /* _CLK_SOURCE_EXTPERIPH1_0, 0x3ec */
uint32_t clk_source_extperiph2; /* _CLK_SOURCE_EXTPERIPH2_0, 0x3f0 */
uint32_t clk_source_extperiph3; /* _CLK_SOURCE_EXTPERIPH3_0, 0x3f4 */
uint32_t _0x3f8;
uint32_t clk_source_i2c_slow; /* _CLK_SOURCE_I2C_SLOW_0, 0x3fc */
uint32_t clk_source_sys; /* _CLK_SOURCE_SYS_0, 0x400 */
uint32_t clk_source_ispb; /* _CLK_SOURCE_ISPB_0, 0x404 */
uint32_t _0x408[2];
uint32_t clk_source_sor1; /* _CLK_SOURCE_SOR1_0, 0x410 */
uint32_t clk_source_sor0; /* _CLK_SOURCE_SOR0_0, 0x414 */
uint32_t _0x418[2];
uint32_t clk_source_sata_oob; /* _CLK_SOURCE_SATA_OOB_0, 0x420 */
uint32_t clk_source_sata; /* _CLK_SOURCE_SATA_0, 0x424 */
uint32_t clk_source_hda; /* _CLK_SOURCE_HDA_0, 0x428 */
uint32_t _0x42c;
/* _RST_DEV_V/W_SET_0 0x430-0x43c */
uint32_t rst_dev_v_set;
uint32_t rst_dev_v_clr;
uint32_t rst_dev_w_set;
uint32_t rst_dev_w_clr;
/* _CLK_ENB_V/W_CLR_0 0x440-0x44c */
uint32_t clk_enb_v_set;
uint32_t clk_enb_v_clr;
uint32_t clk_enb_w_set;
uint32_t clk_enb_w_clr;
/* Additional (T114+) registers */
uint32_t rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET_0, 0x450 */
uint32_t rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR_0, 0x454 */
uint32_t rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET_0, 0x458 */
uint32_t rst_cpulp_cmplx_clr; /* _RST_CPULP_CMPLX_CLR_0, 0x45c */
uint32_t clk_cpug_cmplx_set; /* _CLK_CPUG_CMPLX_SET_0, 0x460 */
uint32_t clk_cpug_cmplx_clr; /* _CLK_CPUG_CMPLX_CLR_0, 0x464 */
uint32_t clk_cpulp_cmplx_set; /* _CLK_CPULP_CMPLX_SET_0, 0x468 */
uint32_t clk_cpulp_cmplx_clr; /* _CLK_CPULP_CMPLX_CLR_0, 0x46c */
uint32_t cpu_cmplx_status; /* _CPU_CMPLX_STATUS_0, 0x470 */
uint32_t _0x474;
uint32_t intstatus; /* _INTSTATUS_0, 0x478 */
uint32_t intmask; /* _INTMASK_0, 0x47c */
uint32_t utmip_pll_cfg0; /* _UTMIP_PLL_CFG0_0, 0x480 */
uint32_t utmip_pll_cfg1; /* _UTMIP_PLL_CFG1_0, 0x484 */
uint32_t utmip_pll_cfg2; /* _UTMIP_PLL_CFG2_0, 0x488 */
uint32_t plle_aux; /* _PLLE_AUX_0, 0x48c */
uint32_t sata_pll_cfg0; /* _SATA_PLL_CFG0_0, 0x490 */
uint32_t sata_pll_cfg1; /* _SATA_PLL_CFG1_0, 0x494 */
uint32_t pcie_pll_cfg0; /* _PCIE_PLL_CFG0_0, 0x498 */
uint32_t prog_audio_dly_clk; /* _PROG_AUDIO_DLY_CLK_0, 0x49c */
uint32_t audio_sync_clk_i2s0; /* _AUDIO_SYNC_CLK_I2S0_0, 0x4a0 */
uint32_t audio_sync_clk_i2s1; /* _AUDIO_SYNC_CLK_I2S1_0, 0x4a4 */
uint32_t audio_sync_clk_i2s2; /* _AUDIO_SYNC_CLK_I2S2_0, 0x4a8 */
uint32_t audio_sync_clk_i2s3; /* _AUDIO_SYNC_CLK_I2S3_0, 0x4ac */
uint32_t audio_sync_clk_i2s4; /* _AUDIO_SYNC_CLK_I2S4_0, 0x4b0 */
uint32_t audio_sync_clk_spdif; /* _AUDIO_SYNC_CLK_SPDIF_0, 0x4b4 */
uint32_t plld2_base; /* _PLLD2_BASE_0, 0x4b8 */
uint32_t plld2_misc; /* _PLLD2_MISC_0, 0x4bc */
uint32_t utmip_pll_cfg3; /* _UTMIP_PLL_CFG3_0, 0x4c0 */
uint32_t pllrefe_base; /* _PLLREFE_BASE_0, 0x4c4 */
uint32_t pllrefe_misc; /* _PLLREFE_MISC_0, 0x4c8 */
uint32_t pllrefe_out; /* _PLLREFE_OUT_0, 0x4cc */
uint32_t cpu_finetrim_byp; /* _CPU_FINETRIM_BYP_0, 0x4d0 */
uint32_t cpu_finetrim_select; /* _CPU_FINETRIM_SELECT_0, 0x4d4 */
uint32_t cpu_finetrim_dr; /* _CPU_FINETRIM_DR_0, 0x4d8 */
uint32_t cpu_finetrim_df; /* _CPU_FINETRIM_DF_0, 0x4dc */
uint32_t cpu_finetrim_f; /* _CPU_FINETRIM_F_0, 0x4e0 */
uint32_t cpu_finetrim_r; /* _CPU_FINETRIM_R_0, 0x4e4 */
uint32_t pllc2_base; /* _PLLC2_BASE_0, 0x4e8 */
uint32_t pllc2_misc0; /* _PLLC2_MISC_0_0, 0x4ec */
uint32_t pllc2_misc1; /* _PLLC2_MISC_1_0, 0x4f0 */
uint32_t pllc2_misc2; /* _PLLC2_MISC_2_0, 0x4f4 */
uint32_t pllc2_misc3; /* _PLLC2_MISC_3_0, 0x4f8 */
uint32_t pllc3_base; /* _PLLC3_BASE_0, 0x4fc */
uint32_t pllc3_misc0; /* _PLLC3_MISC_0_0, 0x500 */
uint32_t pllc3_misc1; /* _PLLC3_MISC_1_0, 0x504 */
uint32_t pllc3_misc2; /* _PLLC3_MISC_2_0, 0x508 */
uint32_t pllc3_misc3; /* _PLLC3_MISC_3_0, 0x50c */
uint32_t pllx_misc1; /* _PLLX_MISC_1_0, 0x510 */
uint32_t pllx_misc2; /* _PLLX_MISC_2_0, 0x514 */
uint32_t pllx_misc3; /* _PLLX_MISC_3_0, 0x518 */
uint32_t xusbio_pll_cfg0; /* _XUSBIO_PLL_CFG0_0, 0x51c */
uint32_t xusbio_pll_cfg1; /* _XUSBIO_PLL_CFG0_1, 0x520 */
uint32_t plle_aux1; /* _PLLE_AUX1_0, 0x524 */
uint32_t pllp_reshift; /* _PLLP_RESHIFT_0, 0x528 */
uint32_t utmipll_hw_pwrdn_cfg0; /* _UTMIPLL_HW_PWRDN_CFG0_0, 0x52c */
uint32_t pllu_hw_pwrdn_cfg0; /* _PLLU_HW_PWRDN_CFG0_0, 0x530 */
uint32_t xusb_pll_cfg0; /* _XUSB_PLL_CFG0_0, 0x534 */
uint32_t _0x538;
uint32_t clk_cpu_misc; /* _CLK_CPU_MISC_0, 0x53c */
uint32_t clk_cpug_misc; /* _CLK_CPUG_MISC_0, 0x540 */
uint32_t clk_cpulp_misc; /* _CLK_CPULP_MISC_0, 0x544 */
uint32_t pllx_hw_ctrl_cfg; /* _PLLX_HW_CTRL_CFG_0, 0x548 */
uint32_t pllx_sw_ramp_cfg; /* _PLLX_SW_RAMP_CFG_0, 0x54c */
uint32_t pllx_hw_ctrl_status; /* _PLLX_HW_CTRL_STATUS_0, 0x550 */
uint32_t lvl2_clk_gate_ovre; /* _LVL2_CLK_GATE_OVRE, 0x554 */
uint32_t super_gr3d_clk_div; /* _SUPER_GR3D_CLK_DIVIDER_0, 0x558 */
uint32_t spare_reg0; /* _SPARE_REG0_0, 0x55c */
uint32_t audio_sync_clk_dmic1; /* _AUDIO_SYNC_CLK_DMIC1_0, 0x560 */
uint32_t audio_sync_clk_dmic2; /* _AUDIO_SYNC_CLK_DMIC2_0, 0x564 */
uint32_t _0x568[2];
uint32_t plld2_ss_cfg; /* _PLLD2_SS_CFG, 0x570 */
uint32_t plld2_ss_ctrl1; /* _PLLD2_SS_CTRL1_0, 0x574 */
uint32_t plld2_ss_ctrl2; /* _PLLD2_SS_CTRL2_0, 0x578 */
uint32_t _0x57c[5];
uint32_t plldp_base; /* _PLLDP_BASE, 0x590*/
uint32_t plldp_misc; /* _PLLDP_MISC, 0x594 */
uint32_t plldp_ss_cfg; /* _PLLDP_SS_CFG, 0x598 */
uint32_t plldp_ss_ctrl1; /* _PLLDP_SS_CTRL1_0, 0x59c */
uint32_t plldp_ss_ctrl2; /* _PLLDP_SS_CTRL2_0, 0x5a0 */
uint32_t pllc4_base; /* _PLLC4_BASE_0, 0x5a4 */
uint32_t pllc4_misc; /* _PLLC4_MISC_0, 0x5a8 */
uint32_t _0x5ac[6];
uint32_t clk_spare0; /* _CLK_SPARE0_0, 0x5c4 */
uint32_t clk_spare1; /* _CLK_SPARE1_0, 0x5c8 */
uint32_t gpu_isob_ctrl; /* _GPU_ISOB_CTRL_0, 0x5cc */
uint32_t pllc_misc2; /* _PLLC_MISC_2_0, 0x5d0 */
uint32_t pllc_misc3; /* _PLLC_MISC_3_0, 0x5d4 */
uint32_t plla_misc2; /* _PLLA_MISC2_0, 0x5d8 */
uint32_t _0x5dc[2];
uint32_t pllc4_out; /* _PLLC4_OUT_0, 0x5e4 */
uint32_t pllmb_base; /* _PLLMB_BASE_0, 0x5e8 */
uint32_t pllmb_misc1; /* _PLLMB_MISC1_0, 0x5ec */
uint32_t pllx_misc4; /* _PLLX_MISC_4_0, 0x5f0 */
uint32_t pllx_misc5; /* _PLLX_MISC_5_0, 0x5f4 */
uint32_t _0x5f8[2];
uint32_t clk_source_xusb_core_host; /* _CLK_SOURCE_XUSB_CORE_HOST_0, 0x600 */
uint32_t clk_source_xusb_falcon; /* _CLK_SOURCE_XUSB_FALCON_0, 0x604 */
uint32_t clk_source_xusb_fs; /* _CLK_SOURCE_XUSB_FS_0, 0x608 */
uint32_t clk_source_xusb_core_dev; /* _CLK_SOURCE_XUSB_CORE_DEV_0, 0x60c */
uint32_t clk_source_xusb_ss; /* _CLK_SOURCE_XUSB_SS_0, 0x610 */
uint32_t clk_source_cilab; /* _CLK_SOURCE_CILAB_0, 0x614 */
uint32_t clk_source_cilcd; /* _CLK_SOURCE_CILCD_0, 0x618 */
uint32_t clk_source_cilef; /* _CLK_SOURCE_CILEF_0, 0x61c */
uint32_t clk_source_dsia_lp; /* _CLK_SOURCE_DSIA_LP_0, 0x620 */
uint32_t clk_source_dsib_lp; /* _CLK_SOURCE_DSIB_LP_0, 0x624 */
uint32_t clk_source_entropy; /* _CLK_SOURCE_ENTROPY_0, 0x628 */
uint32_t clk_source_dvfs_ref; /* _CLK_SOURCE_DVFS_REF_0, 0x62c */
uint32_t clk_source_dvfs_soc; /* _CLK_SOURCE_DVFS_SOC_0, 0x630 */
uint32_t _0x634[3];
uint32_t clk_source_emc_latency; /* _CLK_SOURCE_EMC_LATENCY_0, 0x640 */
uint32_t clk_source_soc_therm; /* _CLK_SOURCE_SOC_THERM_0, 0x644 */
uint32_t _0x648;
uint32_t clk_source_dmic1; /* _CLK_SOURCE_DMIC1_0, 0x64c */
uint32_t clk_source_dmic2; /* _CLK_SOURCE_DMIC2_0, 0x650 */
uint32_t _0x654;
uint32_t clk_source_vi_sensor2; /* _CLK_SOURCE_VI_SENSOR2_0, 0x658 */
uint32_t clk_source_i2c6; /* _CLK_SOURCE_I2C6_0, 0x65c */
uint32_t clk_source_mipibif; /* _CLK_SOURCE_MIPIBIF_0, 0x660 */
uint32_t clk_source_emc_dll; /* _CLK_SOURCE_EMC_DLL_0, 0x664 */
uint32_t _0x668;
uint32_t clk_source_uart_fst_mipi_cal; /* _CLK_SOURCE_UART_FST_MIPI_CAL_0, 0x66c */
uint32_t _0x670[2];
uint32_t clk_source_vic; /* _CLK_SOURCE_VIC_0, 0x678 */
uint32_t pllp_outc; /* _PLLP_OUTC_0, 0x67c */
uint32_t pllp_misc1; /* _PLLP_MISC1_0, 0x680 */
uint32_t _0x684[2];
uint32_t emc_div_clk_shaper_ctrl; /* _EMC_DIV_CLK_SHAPER_CTRL_0, 0x68c */
uint32_t emc_pllc_shaper_ctrl; /* _EMC_PLLC_SHAPER_CTRL_0, 0x690 */
uint32_t clk_source_sdmmc_legacy_tm; /* _CLK_SOURCE_SDMMC_LEGACY_TM_0, 0x694 */
uint32_t clk_source_nvdec; /* _CLK_SOURCE_NVDEC_0, 0x698 */
uint32_t clk_source_nvjpg; /* _CLK_SOURCE_NVJPG_0, 0x69c */
uint32_t clk_source_nvenc; /* _CLK_SOURCE_NVENC_0, 0x6a0 */
uint32_t plla1_base; /* _PLLA1_BASE_0, 0x6a4 */
uint32_t plla1_misc0; /* _PLLA1_MISC_0_0, 0x6a8 */
uint32_t plla1_misc1; /* _PLLA1_MISC_1_0, 0x6ac */
uint32_t plla1_misc2; /* _PLLA1_MISC_2_0, 0x6b0 */
uint32_t plla1_misc3; /* _PLLA1_MISC_3_0, 0x6b4 */
uint32_t audio_sync_clk_dmic3; /* _AUDIO_SYNC_CLK_DMIC3_0, 0x6b8 */
uint32_t clk_source_dmic3; /* _CLK_SOURCE_DMIC3_0, 0x6bc */
uint32_t clk_source_ape; /* _CLK_SOURCE_APE_0, 0x6c0 */
uint32_t clk_source_qspi; /* _CLK_SOURCE_QSPI_0, 0x6c4 */
uint32_t clk_source_vi_i2c; /* _CLK_SOURCE_VI_I2C_0, 0x6c8 */
uint32_t clk_source_usb2_hsic_trk; /* _CLK_SOURCE_USB2_HSIC_TRK_0, 0x6cc */
uint32_t clk_source_pex_sata_usb_rx_byp; /* _CLK_SOURCE_PEX_SATA_USB_RX_BYP_0, 0x6d0 */
uint32_t clk_source_maud; /* _CLK_SOURCE_MAUD_0, 0x6d4 */
uint32_t clk_source_tsecb; /* _CLK_SOURCE_TSECB_0, 0x6d8 */
uint32_t clk_cpug_misc1; /* _CLK_CPUG_MISC1_0, 0x6dc */
uint32_t aclk_burst_policy; /* _ACLK_BURST_POLICY_0, 0x6e0 */
uint32_t super_aclk_divider; /* _SUPER_ACLK_DIVIDER_0, 0x6e4 */
uint32_t nvenc_super_clk_divider; /* _NVENC_SUPER_CLK_DIVIDER_0, 0x6e8 */
uint32_t vi_super_clk_divider; /* _VI_SUPER_CLK_DIVIDER_0, 0x6ec */
uint32_t vic_super_clk_divider; /* _VIC_SUPER_CLK_DIVIDER_0, 0x6f0 */
uint32_t nvdec_super_clk_divider; /* _NVDEC_SUPER_CLK_DIVIDER_0, 0x6f4 */
uint32_t isp_super_clk_divider; /* _ISP_SUPER_CLK_DIVIDER_0, 0x6f8 */
uint32_t ispb_super_clk_divider; /* _ISPB_SUPER_CLK_DIVIDER_0, 0x6fc */
uint32_t nvjpg_super_clk_divider; /* _NVJPG_SUPER_CLK_DIVIDER_0, 0x700 */
uint32_t se_super_clk_divider; /* _SE_SUPER_CLK_DIVIDER_0, 0x704 */
uint32_t tsec_super_clk_divider; /* _TSEC_SUPER_CLK_DIVIDER_0, 0x708 */
uint32_t tsecb_super_clk_divider; /* _TSECB_SUPER_CLK_DIVIDER_0, 0x70c */
uint32_t clk_source_uartape; /* _CLK_SOURCE_UARTAPE_0, 0x710 */
uint32_t clk_cpug_misc2; /* _CLK_CPUG_MISC2_0, 0x714 */
uint32_t clk_source_dbgapb; /* _CLK_SOURCE_DBGAPB_0, 0x718 */
uint32_t clk_ccplex_cc4_ret_clk_enb; /* _CLK_CCPLEX_CC4_RET_CLK_ENB_0, 0x71c */
uint32_t actmon_cpu_clk; /* _ACTMON_CPU_CLK_0, 0x720 */
uint32_t clk_source_emc_safe; /* _CLK_SOURCE_EMC_SAFE_0, 0x724 */
uint32_t sdmmc2_pllc4_out0_shaper_ctrl; /* _SDMMC2_PLLC4_OUT0_SHAPER_CTRL_0, 0x728 */
uint32_t sdmmc2_pllc4_out1_shaper_ctrl; /* _SDMMC2_PLLC4_OUT1_SHAPER_CTRL_0, 0x72c */
uint32_t sdmmc2_pllc4_out2_shaper_ctrl; /* _SDMMC2_PLLC4_OUT2_SHAPER_CTRL_0, 0x730 */
uint32_t sdmmc2_div_clk_shaper_ctrl; /* _SDMMC2_DIV_CLK_SHAPER_CTRL_0, 0x734 */
uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
uint32_t sdmmc4_pllc4_out1_shaper_ctrl; /* _SDMMC4_PLLC4_OUT1_SHAPER_CTRL_0, 0x73c */
uint32_t sdmmc4_pllc4_out2_shaper_ctrl; /* _SDMMC4_PLLC4_OUT2_SHAPER_CTRL_0, 0x740 */
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
} tegra_car_t;
static inline volatile tegra_car_t *car_get_regs(void) {
return (volatile tegra_car_t *)CAR_BASE;
}
void clk_enable(CarDevice dev);
void clk_disable(CarDevice dev);
void rst_enable(CarDevice dev);
void rst_disable(CarDevice dev);
void clkrst_enable(CarDevice dev);
void clkrst_disable(CarDevice dev);
void clkrst_reboot(CarDevice dev);
void clkrst_enable_fuse_regs(bool enable);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
/*
* (C) Copyright 1997-2002 ELTEC Elektronik AG
* Frank Gottschling <fgottschling@eltec.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _VIDEO_FB_H_
#define _VIDEO_FB_H_
#define CONSOLE_BG_COL 0x00
#define CONSOLE_FG_COL 0xa0
/* Try using the small font */
#define CONFIG_VIDEO_FONT_SMALL
/*
* Graphic Data Format (GDF) bits for VIDEO_DATA_FORMAT
*/
#define GDF__8BIT_INDEX 0
#define GDF_15BIT_555RGB 1
#define GDF_16BIT_565RGB 2
#define GDF_32BIT_X888RGB 3
#define GDF_24BIT_888RGB 4
#define GDF__8BIT_332RGB 5
#define CONFIG_VIDEO_FB_LITTLE_ENDIAN
#define CONFIG_VIDEO_VISIBLE_COLS 720
#define CONFIG_VIDEO_VISIBLE_ROWS 1280
#define CONFIG_VIDEO_COLS 768
#define CONFIG_VIDEO_PIXEL_SIZE 4
#define CONFIG_VIDEO_DATA_FORMAT GDF_32BIT_X888RGB /* BGR actually, but w/e */
int video_get_col(void);
int video_get_row(void);
int video_init(void *fb);
int video_resume(void *fb, int row, int col);
void video_puts(const char *s);
#endif /*_VIDEO_FB_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1089
fusee/fusee-mtc/src/emc.h Normal file

File diff suppressed because it is too large Load Diff

260
fusee/fusee-mtc/src/fuse.c Normal file
View File

@@ -0,0 +1,260 @@
/*
* Copyright (c) 2018-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 <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "car.h"
#include "fuse.h"
#include "timers.h"
/* Prototypes for internal commands. */
void fuse_make_regs_visible(void);
void fuse_enable_power(void);
void fuse_disable_power(void);
void fuse_wait_idle(void);
/* Initialize the fuse driver */
void fuse_init(void) {
fuse_make_regs_visible();
fuse_secondary_private_key_disable();
fuse_disable_programming();
/* TODO: Overrides (iROM patches) and various reads happen here */
}
/* Make all fuse registers visible */
void fuse_make_regs_visible(void) {
clkrst_enable_fuse_regs(true);
}
/* Enable power to the fuse hardware array */
void fuse_enable_power(void) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
fuse->FUSE_PWR_GOOD_SW = 1;
udelay(1);
}
/* Disable power to the fuse hardware array */
void fuse_disable_power(void) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
fuse->FUSE_PWR_GOOD_SW = 0;
udelay(1);
}
/* Wait for the fuse driver to go idle */
void fuse_wait_idle(void) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
uint32_t ctrl_val = 0;
/* Wait for STATE_IDLE */
while ((ctrl_val & (0xF0000)) != 0x40000)
{
udelay(1);
ctrl_val = fuse->FUSE_CTRL;
}
}
/* Read a fuse from the hardware array */
uint32_t fuse_hw_read(uint32_t addr) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
fuse_wait_idle();
/* Program the target address */
fuse->FUSE_REG_ADDR = addr;
/* Enable read operation in control register */
uint32_t ctrl_val = fuse->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x1; /* Set FUSE_READ command */
fuse->FUSE_CTRL = ctrl_val;
fuse_wait_idle();
return fuse->FUSE_REG_READ;
}
/* Write a fuse in the hardware array */
void fuse_hw_write(uint32_t value, uint32_t addr) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
fuse_wait_idle();
/* Program the target address and value */
fuse->FUSE_REG_ADDR = addr;
fuse->FUSE_REG_WRITE = value;
/* Enable write operation in control register */
uint32_t ctrl_val = fuse->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x2; /* Set FUSE_WRITE command */
fuse->FUSE_CTRL = ctrl_val;
fuse_wait_idle();
}
/* Sense the fuse hardware array into the shadow cache */
void fuse_hw_sense(void) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
fuse_wait_idle();
/* Enable sense operation in control register */
uint32_t ctrl_val = fuse->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x3; /* Set FUSE_SENSE command */
fuse->FUSE_CTRL = ctrl_val;
fuse_wait_idle();
}
/* Disables all fuse programming. */
void fuse_disable_programming(void) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
fuse->FUSE_DIS_PGM = 1;
}
/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */
void fuse_secondary_private_key_disable(void) {
volatile tegra_fuse_t *fuse = fuse_get_regs();
fuse->FUSE_PRIVATEKEYDISABLE = 0x10;
}
/* Read the SKU info register from the shadow cache */
uint32_t fuse_get_sku_info(void) {
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
return fuse_chip->FUSE_SKU_INFO;
}
/* Read the bootrom patch version from a register in the shadow cache */
uint32_t fuse_get_bootrom_patch_version(void) {
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
return fuse_chip->FUSE_SOC_SPEEDO_1;
}
/* Read a spare bit register from the shadow cache */
uint32_t fuse_get_spare_bit(uint32_t idx) {
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
if (idx >= 32) {
return 0;
}
return fuse_chip->FUSE_SPARE_BIT[idx];
}
/* Read a reserved ODM register from the shadow cache */
uint32_t fuse_get_reserved_odm(uint32_t idx) {
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
if (idx >= 8) {
return 0;
}
return fuse_chip->FUSE_RESERVED_ODM[idx];
}
/* Derive the Device ID using values in the shadow cache */
uint64_t fuse_get_device_id(void) {
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
uint64_t device_id = 0;
uint64_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
uint64_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
uint64_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
uint32_t lot_code = fuse_chip->FUSE_LOT_CODE_0;
uint64_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
uint64_t derived_lot_code = 0;
for (unsigned int i = 0; i < 5; i++) {
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
}
derived_lot_code &= 0x03FFFFFF;
device_id |= y_coord << 0;
device_id |= x_coord << 9;
device_id |= wafer_id << 18;
device_id |= derived_lot_code << 24;
device_id |= fab_code << 50;
return device_id;
}
/* Get the DRAM ID using values in the shadow cache */
uint32_t fuse_get_dram_id(void) {
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
return (fuse_chip->FUSE_RESERVED_ODM[4] >> 3) & 0x7;
}
/* Derive the Hardware Type using values in the shadow cache */
uint32_t fuse_get_hardware_type(void) {
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
/* This function is very different between 4.x and < 4.x */
uint32_t hardware_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((fuse_chip->FUSE_RESERVED_ODM[4] >> 2) & 1);
/* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) {
static const uint32_t types[] = {0,1,4,3};
hardware_type |= (fuse_chip->FUSE_RESERVED_ODM[4] >> 14) & 0x3C;
hardware_type--;
return hardware_type > 3 ? 4 : types[hardware_type];
} else {*/
if (hardware_type >= 1) {
return hardware_type > 2 ? 3 : hardware_type - 1;
} else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) {
return 0;
} else {
return 3;
}
// }
}
/* Derive the Retail Type using values in the shadow cache */
uint32_t fuse_get_retail_type(void) {
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
/* Retail type = IS_RETAIL | UNIT_TYPE */
uint32_t retail_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 4) | (fuse_chip->FUSE_RESERVED_ODM[4] & 3);
if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */
return 1;
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
return 0;
}
return 2; /* IS_RETAIL | DEV_UNIT */
}
/* Derive the 16-byte Hardware Info using values in the shadow cache, and copy to output buffer. */
void fuse_get_hardware_info(void *dst) {
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
uint32_t hw_info[0x4];
uint32_t unk_hw_fuse = fuse_chip->_0x120 & 0x3F;
uint32_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
uint32_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
uint32_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
uint32_t lot_code_0 = fuse_chip->FUSE_LOT_CODE_0;
uint32_t lot_code_1 = fuse_chip->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
uint32_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
uint32_t vendor_code = fuse_chip->FUSE_VENDOR_CODE & 0xF;
/* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse));
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
hw_info[3] = (uint32_t)(vendor_code);
memcpy(dst, hw_info, 0x10);
}

213
fusee/fusee-mtc/src/fuse.h Normal file
View File

@@ -0,0 +1,213 @@
/*
* Copyright (c) 2018-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/>.
*/
#ifndef FUSEE_FUSE_H
#define FUSEE_FUSE_H
#define FUSE_BASE 0x7000F800
#define FUSE_CHIP_BASE (FUSE_BASE + 0x100)
#define MAKE_FUSE_REG(n) MAKE_REG32(FUSE_BASE + n)
#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
typedef struct {
uint32_t FUSE_CTRL;
uint32_t FUSE_REG_ADDR;
uint32_t FUSE_REG_READ;
uint32_t FUSE_REG_WRITE;
uint32_t FUSE_TIME_RD1;
uint32_t FUSE_TIME_RD2;
uint32_t FUSE_TIME_PGM1;
uint32_t FUSE_TIME_PGM2;
uint32_t FUSE_PRIV2INTFC;
uint32_t FUSE_FUSEBYPASS;
uint32_t FUSE_PRIVATEKEYDISABLE;
uint32_t FUSE_DIS_PGM;
uint32_t FUSE_WRITE_ACCESS;
uint32_t FUSE_PWR_GOOD_SW;
uint32_t _0x38[0x32];
} tegra_fuse_t;
typedef struct {
uint32_t FUSE_PRODUCTION_MODE;
uint32_t _0x4;
uint32_t _0x8;
uint32_t _0xC;
uint32_t FUSE_SKU_INFO;
uint32_t FUSE_CPU_SPEEDO_0;
uint32_t FUSE_CPU_IDDQ;
uint32_t _0x1C;
uint32_t _0x20;
uint32_t _0x24;
uint32_t FUSE_FT_REV;
uint32_t FUSE_CPU_SPEEDO_1;
uint32_t FUSE_CPU_SPEEDO_2;
uint32_t FUSE_SOC_SPEEDO_0;
uint32_t FUSE_SOC_SPEEDO_1;
uint32_t FUSE_SOC_SPEEDO_2;
uint32_t FUSE_SOC_IDDQ;
uint32_t _0x44;
uint32_t FUSE_FA;
uint32_t _0x4C;
uint32_t _0x50;
uint32_t _0x54;
uint32_t _0x58;
uint32_t _0x5C;
uint32_t _0x60;
uint32_t FUSE_PUBLIC_KEY[0x8];
uint32_t FUSE_TSENSOR_1;
uint32_t FUSE_TSENSOR_2;
uint32_t _0x8C;
uint32_t FUSE_CP_REV;
uint32_t _0x94;
uint32_t FUSE_TSENSOR_0;
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG;
uint32_t FUSE_SECURITY_MODE;
uint32_t FUSE_PRIVATE_KEY[0x4];
uint32_t FUSE_DEVICE_KEY;
uint32_t _0xB8;
uint32_t _0xBC;
uint32_t FUSE_RESERVED_SW;
uint32_t FUSE_VP8_ENABLE;
uint32_t FUSE_RESERVED_ODM[0x8];
uint32_t _0xE8;
uint32_t _0xEC;
uint32_t FUSE_SKU_USB_CALIB;
uint32_t FUSE_SKU_DIRECT_CONFIG;
uint32_t _0xF8;
uint32_t _0xFC;
uint32_t FUSE_VENDOR_CODE;
uint32_t FUSE_FAB_CODE;
uint32_t FUSE_LOT_CODE_0;
uint32_t FUSE_LOT_CODE_1;
uint32_t FUSE_WAFER_ID;
uint32_t FUSE_X_COORDINATE;
uint32_t FUSE_Y_COORDINATE;
uint32_t _0x11C;
uint32_t _0x120;
uint32_t FUSE_SATA_CALIB;
uint32_t FUSE_GPU_IDDQ;
uint32_t FUSE_TSENSOR_3;
uint32_t _0x130;
uint32_t _0x134;
uint32_t _0x138;
uint32_t _0x13C;
uint32_t _0x140;
uint32_t _0x144;
uint32_t FUSE_OPT_SUBREVISION;
uint32_t _0x14C;
uint32_t _0x150;
uint32_t FUSE_TSENSOR_4;
uint32_t FUSE_TSENSOR_5;
uint32_t FUSE_TSENSOR_6;
uint32_t FUSE_TSENSOR_7;
uint32_t FUSE_OPT_PRIV_SEC_DIS;
uint32_t FUSE_PKC_DISABLE;
uint32_t _0x16C;
uint32_t _0x170;
uint32_t _0x174;
uint32_t _0x178;
uint32_t _0x17C;
uint32_t FUSE_TSENSOR_COMMON;
uint32_t _0x184;
uint32_t _0x188;
uint32_t _0x18C;
uint32_t _0x190;
uint32_t _0x194;
uint32_t _0x198;
uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
uint32_t _0x1A0;
uint32_t _0x1A4;
uint32_t _0x1A8;
uint32_t _0x1AC;
uint32_t _0x1B0;
uint32_t _0x1B4;
uint32_t _0x1B8;
uint32_t _0x1BC;
uint32_t _0x1D0;
uint32_t FUSE_TSENSOR_8;
uint32_t _0x1D8;
uint32_t _0x1DC;
uint32_t _0x1E0;
uint32_t _0x1E4;
uint32_t _0x1E8;
uint32_t _0x1EC;
uint32_t _0x1F0;
uint32_t _0x1F4;
uint32_t _0x1F8;
uint32_t _0x1FC;
uint32_t _0x200;
uint32_t FUSE_RESERVED_CALIB;
uint32_t _0x208;
uint32_t _0x20C;
uint32_t _0x210;
uint32_t _0x214;
uint32_t _0x218;
uint32_t FUSE_TSENSOR_9;
uint32_t _0x220;
uint32_t _0x224;
uint32_t _0x228;
uint32_t _0x22C;
uint32_t _0x230;
uint32_t _0x234;
uint32_t _0x238;
uint32_t _0x23C;
uint32_t _0x240;
uint32_t _0x244;
uint32_t _0x248;
uint32_t _0x24C;
uint32_t FUSE_USB_CALIB_EXT;
uint32_t _0x254;
uint32_t _0x258;
uint32_t _0x25C;
uint32_t _0x260;
uint32_t _0x264;
uint32_t _0x268;
uint32_t _0x26C;
uint32_t _0x270;
uint32_t _0x274;
uint32_t _0x278;
uint32_t _0x27C;
uint32_t FUSE_SPARE_BIT[0x20];
} tegra_fuse_chip_t;
static inline volatile tegra_fuse_t *fuse_get_regs(void) {
return (volatile tegra_fuse_t *)FUSE_BASE;
}
static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) {
return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE;
}
void fuse_init(void);
uint32_t fuse_hw_read(uint32_t addr);
void fuse_hw_write(uint32_t value, uint32_t addr);
void fuse_hw_sense(void);
void fuse_disable_programming(void);
void fuse_secondary_private_key_disable(void);
uint32_t fuse_get_sku_info(void);
uint32_t fuse_get_spare_bit(uint32_t idx);
uint32_t fuse_get_reserved_odm(uint32_t idx);
uint32_t fuse_get_bootrom_patch_version(void);
uint64_t fuse_get_device_id(void);
uint32_t fuse_get_dram_id(void);
uint32_t fuse_get_hardware_type(void);
uint32_t fuse_get_retail_type(void);
void fuse_get_hardware_info(void *dst);
#endif

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2018-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 <stdint.h>
#include <stddef.h>
#include <string.h>
#include <malloc.h>
#include <sys/iosupport.h>
#include "stage2.h"
#include "utils.h"
void __libc_init_array(void);
void __libc_fini_array(void);
extern uint8_t __bss_start__[], __bss_end__[];
extern uint8_t __heap_start__[], __heap_end__[];
extern char *fake_heap_start;
extern char *fake_heap_end;
int __program_argc;
void **__program_argv;
void __program_exit(int rc);
static void __program_parse_argc_argv(int argc, char *argdata);
static void __program_cleanup_argv(void);
static void __program_init_heap(void) {
fake_heap_start = (char*)__heap_start__;
fake_heap_end = (char*)__heap_end__;
}
static void __program_init_newlib_hooks(void) {
__syscalls.exit = __program_exit; /* For exit, etc. */
}
void __program_init(int argc, char *argdata) {
/* Zero-fill the .bss section */
memset(__bss_start__, 0, __bss_end__ - __bss_start__);
__program_init_heap();
__program_init_newlib_hooks();
__program_parse_argc_argv(argc, argdata);
__libc_init_array();
}
void __program_exit(int rc) {
__libc_fini_array();
__program_cleanup_argv();
}
static void __program_parse_argc_argv(int argc, char *argdata) {
__program_argc = argc;
__program_argv = malloc(argc * sizeof(void **));
if (__program_argv == NULL) {
generic_panic();
}
__program_argv[0] = malloc(sizeof(stage2_mtc_args_t));
if (__program_argv[0] == NULL) {
generic_panic();
}
memcpy(__program_argv[0], argdata, sizeof(stage2_mtc_args_t));
}
static void __program_cleanup_argv(void) {
for (int i = 0; i < __program_argc; i++) {
free(__program_argv[i]);
__program_argv[i] = NULL;
}
free(__program_argv);
}

View File

@@ -0,0 +1,127 @@
/*
* Copyright (c) 2018-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 "log.h"
#include "../display/video_fb.h"
#include "vsprintf.h"
/* default log level for screen output */
ScreenLogLevel g_screen_log_level = SCREEN_LOG_LEVEL_NONE;
void log_set_log_level(ScreenLogLevel log_level) {
g_screen_log_level = log_level;
}
ScreenLogLevel log_get_log_level() {
return g_screen_log_level;
}
void log_to_uart(const char *message) {
/* TODO: add UART logging */
}
static void print_to_screen(ScreenLogLevel screen_log_level, char *message) {
/* don't print to screen if below log level */
if(screen_log_level > g_screen_log_level) return;
video_puts(message);
}
/**
* vprintk - logs a message and prints it to screen based on its screen_log_level
*
* If the level is below g_screen_log_level it will not be shown but logged to UART
* This text will not be colored or prefixed
* UART is TODO
*/
void vprint(ScreenLogLevel screen_log_level, const char *fmt, va_list args)
{
char buf[PRINT_MESSAGE_MAX_LENGTH];
vsnprintf(buf, PRINT_MESSAGE_MAX_LENGTH, fmt, args);
/* we don't need that flag here, but if it gets used, strip it so we print correctly */
screen_log_level &= ~SCREEN_LOG_LEVEL_NO_PREFIX;
/* log to UART */
log_to_uart(buf);
print_to_screen(screen_log_level, buf);
}
static void add_prefix(ScreenLogLevel screen_log_level, const char *fmt, char *buf) {
char typebuf[] = "[%s] %s";
/* apply prefix and append message format */
/* TODO: add coloring to the output */
switch(screen_log_level)
{
case SCREEN_LOG_LEVEL_ERROR:
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "ERROR", fmt);
break;
case SCREEN_LOG_LEVEL_WARNING:
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "WARNING", fmt);
break;
case SCREEN_LOG_LEVEL_MANDATORY:
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, "%s", fmt);
break;
case SCREEN_LOG_LEVEL_INFO:
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "INFO", fmt);
break;
case SCREEN_LOG_LEVEL_DEBUG:
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "DEBUG", fmt);
break;
default:
break;
}
}
/**
* print - logs a message and prints it to screen based on its screen_log_level
*
* If the level is below g_screen_log_level it will not be shown but logged to UART
* Use SCREEN_LOG_LEVEL_NO_PREFIX if you don't want a prefix to be added
* UART is TODO
*/
void print(ScreenLogLevel screen_log_level, const char * fmt, ...)
{
char buf[PRINT_MESSAGE_MAX_LENGTH] = {};
char message[PRINT_MESSAGE_MAX_LENGTH] = {};
/* TODO: make splash disappear if level > MANDATORY */
/* make prefix free messages with log_level possible */
if(screen_log_level & SCREEN_LOG_LEVEL_NO_PREFIX) {
/* remove the NO_PREFIX flag so the enum can be recognized later on */
screen_log_level &= ~SCREEN_LOG_LEVEL_NO_PREFIX;
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, "%s", fmt);
}
else {
add_prefix(screen_log_level, fmt, buf);
}
/* input arguments */
va_list args;
va_start(args, fmt);
vsnprintf(message, PRINT_MESSAGE_MAX_LENGTH, buf, args);
va_end(args);
/* log to UART */
log_to_uart(message);
print_to_screen(screen_log_level, message);
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2018-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/>.
*/
#ifndef FUSEE_LOG_H
#define FUSEE_LOG_H
#define PRINT_MESSAGE_MAX_LENGTH 512
#include <stdarg.h>
typedef enum {
SCREEN_LOG_LEVEL_NONE = 0,
SCREEN_LOG_LEVEL_ERROR = 1,
SCREEN_LOG_LEVEL_WARNING = 2,
SCREEN_LOG_LEVEL_MANDATORY = 3, /* no log prefix */
SCREEN_LOG_LEVEL_INFO = 4,
SCREEN_LOG_LEVEL_DEBUG = 5,
SCREEN_LOG_LEVEL_NO_PREFIX = 0x100 /* OR this to your LOG_LEVEL to prevent prefix creation */
} ScreenLogLevel;
extern ScreenLogLevel g_screen_log_level;
void log_set_log_level(ScreenLogLevel screen_log_level);
ScreenLogLevel log_get_log_level();
void log_to_uart(const char *message);
void vprint(ScreenLogLevel screen_log_level, const char *fmt, va_list args);
void print(ScreenLogLevel screen_log_level, const char* fmt, ...);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2011 Andrei Warkentin <andrey.warkentin@gmail.com>
*
* This program is free software ; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <stdarg.h>
#include <stdlib.h>
#ifndef VSPRINTF_H
#define VSPRINTF_H
struct va_format {
const char *fmt;
va_list *va;
};
unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base);
int sprintf(char *buf, const char *fmt, ...);
int scnprintf(char *buf, size_t size, const char *fmt, ...);
int snprintf(char *buf, size_t size, const char *fmt, ...);
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
int sscanf(const char *buf, const char *fmt, ...);
#endif /* VSPRINTF_H */

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2018-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 <string.h>
#include "mtc.h"
#include "stage2.h"
#include "display/video_fb.h"
static void *g_framebuffer;
static __attribute__((__aligned__(0x200))) stage2_mtc_args_t g_mtc_args_store;
static stage2_mtc_args_t *g_mtc_args;
/* Allow for main(int argc, void **argv) signature. */
#pragma GCC diagnostic ignored "-Wmain"
int main(int argc, void **argv) {
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
/* Check argc. */
if (argc != MTC_ARGC) {
return 1;
}
/* Extract arguments from argv. */
g_mtc_args = &g_mtc_args_store;
memcpy(g_mtc_args, (stage2_mtc_args_t *)argv[MTC_ARGV_ARGUMENT_STRUCT], sizeof(*g_mtc_args));
log_level = g_mtc_args->log_level;
/* Override the global logging level. */
log_set_log_level(log_level);
if (log_level != SCREEN_LOG_LEVEL_NONE) {
/* Set framebuffer address. */
g_framebuffer = (void *)0xC0000000;
/* Zero-fill the framebuffer and register it as printk provider. */
video_init(g_framebuffer);
}
/* Train DRAM. */
train_dram();
return 0;
}

167
fusee/fusee-mtc/src/mc.c Normal file
View File

@@ -0,0 +1,167 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-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 "mc.h"
#include "car.h"
#include "timers.h"
void mc_config_tsec_carveout(uint32_t bom, uint32_t size1mb, bool lock)
{
MAKE_MC_REG(MC_SEC_CARVEOUT_BOM) = bom;
MAKE_MC_REG(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
if (lock)
MAKE_MC_REG(MC_SEC_CARVEOUT_REG_CTRL) = 1;
}
void mc_config_carveout()
{
*(volatile uint32_t *)0x8005FFFC = 0xC0EDBBCC;
MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
MAKE_MC_REG(MC_VIDEO_PROTECT_BOM) = 0;
MAKE_MC_REG(MC_VIDEO_PROTECT_SIZE_MB) = 0;
MAKE_MC_REG(MC_VIDEO_PROTECT_REG_CTRL) = 1;
mc_config_tsec_carveout(0, 0, true);
MAKE_MC_REG(MC_MTS_CARVEOUT_BOM) = 0;
MAKE_MC_REG(MC_MTS_CARVEOUT_SIZE_MB) = 0;
MAKE_MC_REG(MC_MTS_CARVEOUT_ADR_HI) = 0;
MAKE_MC_REG(MC_MTS_CARVEOUT_REG_CTRL) = 1;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_BOM) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_BOM) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_BOM) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_BOM) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
}
void mc_config_carveout_finalize()
{
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
}
void mc_enable_ahb_redirect()
{
volatile tegra_car_t *car = car_get_regs();
car->lvl2_clk_gate_ovrd = ((car->lvl2_clk_gate_ovrd & 0xFFF7FFFF) | 0x80000);
MAKE_MC_REG(MC_IRAM_BOM) = 0x40000000;
MAKE_MC_REG(MC_IRAM_TOM) = 0x4003F000;
}
void mc_disable_ahb_redirect()
{
volatile tegra_car_t *car = car_get_regs();
MAKE_MC_REG(MC_IRAM_BOM) = 0xFFFFF000;
MAKE_MC_REG(MC_IRAM_TOM) = 0;
car->lvl2_clk_gate_ovrd &= 0xFFF7FFFF;
}
void mc_enable()
{
volatile tegra_car_t *car = car_get_regs();
/* Set EMC clock source. */
car->clk_source_emc = ((car->clk_source_emc & 0x1FFFFFFF) | 0x40000000);
/* Enable MIPI CAL clock. */
car->clk_enb_h_set = ((car->clk_enb_h_set & 0xFDFFFFFF) | 0x2000000);
/* Enable MC clock. */
car->clk_enb_h_set = ((car->clk_enb_h_set & 0xFFFFFFFE) | 1);
/* Enable EMC DLL clock. */
car->clk_enb_x_set = ((car->clk_enb_x_set & 0xFFFFBFFF) | 0x4000);
/* Clear EMC and MC reset. */
car->rst_dev_h_set = 0x2000001;
udelay(5);
mc_disable_ahb_redirect();
}

605
fusee/fusee-mtc/src/mc.h Normal file
View File

@@ -0,0 +1,605 @@
/*
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-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/>.
*/
#ifndef FUSEE_MC_H_
#define FUSEE_MC_H_
#include <stdint.h>
#include <stdbool.h>
#define MC_BASE 0x70019000
#define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n)
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4
#define MC_ERR_STATUS 0x8
#define MC_ERR_ADR 0xc
#define MC_SMMU_CONFIG 0x10
#define MC_SMMU_TLB_CONFIG 0x14
#define MC_SMMU_PTC_CONFIG 0x18
#define MC_SMMU_PTB_ASID 0x1c
#define MC_SMMU_PTB_DATA 0x20
#define MC_SMMU_TLB_FLUSH 0x30
#define MC_SMMU_PTC_FLUSH 0x34
#define MC_SMMU_ASID_SECURITY 0x38
#define MC_SMMU_ASID_SECURITY_1 0x3c
#define MC_SMMU_ASID_SECURITY_2 0x9e0
#define MC_SMMU_ASID_SECURITY_3 0x9e4
#define MC_SMMU_ASID_SECURITY_4 0x9e8
#define MC_SMMU_ASID_SECURITY_5 0x9ec
#define MC_SMMU_ASID_SECURITY_6 0x9f0
#define MC_SMMU_ASID_SECURITY_7 0x9f4
#define MC_SMMU_AFI_ASID 0x238
#define MC_SMMU_AVPC_ASID 0x23c
#define MC_SMMU_TSEC_ASID 0x294
#define MC_SMMU_PPCS1_ASID 0x298
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0
#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
#define MC_PCFIFO_CLIENT_CONFIG3 0xddc
#define MC_PCFIFO_CLIENT_CONFIG4 0xde0
#define MC_EMEM_CFG 0x50
#define MC_EMEM_ADR_CFG 0x54
#define MC_EMEM_ADR_CFG_DEV0 0x58
#define MC_EMEM_ADR_CFG_DEV1 0x5c
#define MC_EMEM_ADR_CFG_CHANNEL_MASK 0x60
#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64
#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68
#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c
#define MC_SECURITY_CFG0 0x70
#define MC_SECURITY_CFG1 0x74
#define MC_SECURITY_CFG3 0x9bc
#define MC_SECURITY_RSV 0x7c
#define MC_EMEM_ARB_CFG 0x90
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
#define MC_EMEM_ARB_TIMING_RCD 0x98
#define MC_EMEM_ARB_TIMING_RP 0x9c
#define MC_EMEM_ARB_TIMING_RC 0xa0
#define MC_EMEM_ARB_TIMING_RAS 0xa4
#define MC_EMEM_ARB_TIMING_FAW 0xa8
#define MC_EMEM_ARB_TIMING_RRD 0xac
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
#define MC_EMEM_ARB_TIMING_R2R 0xb8
#define MC_EMEM_ARB_TIMING_W2W 0xbc
#define MC_EMEM_ARB_TIMING_R2W 0xc0
#define MC_EMEM_ARB_TIMING_W2R 0xc4
#define MC_EMEM_ARB_TIMING_RFCPB 0x6c0
#define MC_EMEM_ARB_TIMING_CCDMW 0x6c4
#define MC_EMEM_ARB_REFPB_HP_CTRL 0x6f0
#define MC_EMEM_ARB_REFPB_BANK_CTRL 0x6f4
#define MC_EMEM_ARB_DA_TURNS 0xd0
#define MC_EMEM_ARB_DA_COVERS 0xd4
#define MC_EMEM_ARB_MISC0 0xd8
#define MC_EMEM_ARB_MISC1 0xdc
#define MC_EMEM_ARB_MISC2 0xc8
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
#define MC_EMEM_ARB_NISO_THROTTLE 0x6b0
#define MC_EMEM_ARB_OVERRIDE 0xe8
#define MC_EMEM_ARB_RSV 0xec
#define MC_CLKEN_OVERRIDE 0xf4
#define MC_TIMING_CONTROL_DBG 0xf8
#define MC_TIMING_CONTROL 0xfc
#define MC_STAT_CONTROL 0x100
#define MC_STAT_STATUS 0x104
#define MC_STAT_EMC_CLOCK_LIMIT 0x108
#define MC_STAT_EMC_CLOCK_LIMIT_MSBS 0x10c
#define MC_STAT_EMC_CLOCKS 0x110
#define MC_STAT_EMC_CLOCKS_MSBS 0x114
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 0x118
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 0x158
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 0x11c
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 0x15c
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER 0xa20
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER 0xa24
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 0x198
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 0x1a8
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 0x19c
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 0x1ac
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER 0xa28
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER 0xa2c
#define MC_STAT_EMC_FILTER_SET0_ASID 0x1a0
#define MC_STAT_EMC_FILTER_SET1_ASID 0x1b0
#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 0x120
#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 0x160
#define MC_STAT_EMC_FILTER_SET0_CLIENT_0 0x128
#define MC_STAT_EMC_FILTER_SET1_CLIENT_0 0x168
#define MC_STAT_EMC_FILTER_SET0_CLIENT_1 0x12c
#define MC_STAT_EMC_FILTER_SET1_CLIENT_1 0x16c
#define MC_STAT_EMC_FILTER_SET0_CLIENT_2 0x130
#define MC_STAT_EMC_FILTER_SET1_CLIENT_2 0x170
#define MC_STAT_EMC_FILTER_SET0_CLIENT_3 0x134
#define MC_STAT_EMC_FILTER_SET0_CLIENT_4 0xb88
#define MC_STAT_EMC_FILTER_SET1_CLIENT_3 0x174
#define MC_STAT_EMC_FILTER_SET1_CLIENT_4 0xb8c
#define MC_STAT_EMC_SET0_COUNT 0x138
#define MC_STAT_EMC_SET0_COUNT_MSBS 0x13c
#define MC_STAT_EMC_SET1_COUNT 0x178
#define MC_STAT_EMC_SET1_COUNT_MSBS 0x17c
#define MC_STAT_EMC_SET0_SLACK_ACCUM 0x140
#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 0x144
#define MC_STAT_EMC_SET1_SLACK_ACCUM 0x180
#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 0x184
#define MC_STAT_EMC_SET0_HISTO_COUNT 0x148
#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 0x14c
#define MC_STAT_EMC_SET1_HISTO_COUNT 0x188
#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 0x18c
#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 0x150
#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 0x190
#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 0x1b8
#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 0x1bc
#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 0x1c8
#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 0x1cc
#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 0x1c0
#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 0x1d0
#define MC_CLIENT_HOTRESET_CTRL 0x200
#define MC_CLIENT_HOTRESET_CTRL_1 0x970
#define MC_CLIENT_HOTRESET_STATUS 0x204
#define MC_CLIENT_HOTRESET_STATUS_1 0x974
#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208
#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c
#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210
#define MC_EMEM_ARB_ISOCHRONOUS_3 0x214
#define MC_EMEM_ARB_ISOCHRONOUS_4 0xb94
#define MC_EMEM_ARB_HYSTERESIS_0 0x218
#define MC_EMEM_ARB_HYSTERESIS_1 0x21c
#define MC_EMEM_ARB_HYSTERESIS_2 0x220
#define MC_EMEM_ARB_HYSTERESIS_3 0x224
#define MC_EMEM_ARB_HYSTERESIS_4 0xb84
#define MC_EMEM_ARB_DHYSTERESIS_0 0xbb0
#define MC_EMEM_ARB_DHYSTERESIS_1 0xbb4
#define MC_EMEM_ARB_DHYSTERESIS_2 0xbb8
#define MC_EMEM_ARB_DHYSTERESIS_3 0xbbc
#define MC_EMEM_ARB_DHYSTERESIS_4 0xbc0
#define MC_EMEM_ARB_DHYST_CTRL 0xbcc
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xbd0
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xbd4
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xbd8
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xbdc
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xbe0
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xbe4
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xbe8
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xbec
#define MC_RESERVED_RSV 0x3fc
#define MC_DISB_EXTRA_SNAP_LEVELS 0x408
#define MC_APB_EXTRA_SNAP_LEVELS 0x2a4
#define MC_AHB_EXTRA_SNAP_LEVELS 0x2a0
#define MC_USBD_EXTRA_SNAP_LEVELS 0xa18
#define MC_ISP_EXTRA_SNAP_LEVELS 0xa08
#define MC_AUD_EXTRA_SNAP_LEVELS 0xa10
#define MC_MSE_EXTRA_SNAP_LEVELS 0x40c
#define MC_GK2_EXTRA_SNAP_LEVELS 0xa40
#define MC_A9AVPPC_EXTRA_SNAP_LEVELS 0x414
#define MC_FTOP_EXTRA_SNAP_LEVELS 0x2bc
#define MC_JPG_EXTRA_SNAP_LEVELS 0xa3c
#define MC_HOST_EXTRA_SNAP_LEVELS 0xa14
#define MC_SAX_EXTRA_SNAP_LEVELS 0x2c0
#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac
#define MC_VICPC_EXTRA_SNAP_LEVELS 0xa1c
#define MC_HDAPC_EXTRA_SNAP_LEVELS 0xa48
#define MC_AVP_EXTRA_SNAP_LEVELS 0x2a8
#define MC_USBX_EXTRA_SNAP_LEVELS 0x404
#define MC_PCX_EXTRA_SNAP_LEVELS 0x2b8
#define MC_SD_EXTRA_SNAP_LEVELS 0xa04
#define MC_DFD_EXTRA_SNAP_LEVELS 0xa4c
#define MC_VE_EXTRA_SNAP_LEVELS 0x2d8
#define MC_GK_EXTRA_SNAP_LEVELS 0xa00
#define MC_VE2_EXTRA_SNAP_LEVELS 0x410
#define MC_SDM_EXTRA_SNAP_LEVELS 0xa44
#define MC_VIDEO_PROTECT_BOM 0x648
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
#define MC_VIDEO_PROTECT_BOM_ADR_HI 0x978
#define MC_VIDEO_PROTECT_REG_CTRL 0x650
#define MC_ERR_VPR_STATUS 0x654
#define MC_ERR_VPR_ADR 0x658
#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418
#define MC_VIDEO_PROTECT_VPR_OVERRIDE1 0x590
#define MC_IRAM_BOM 0x65c
#define MC_IRAM_TOM 0x660
#define MC_IRAM_ADR_HI 0x980
#define MC_IRAM_REG_CTRL 0x964
#define MC_EMEM_CFG_ACCESS_CTRL 0x664
#define MC_TZ_SECURITY_CTRL 0x668
#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c
#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO 0x6b4
#define MC_EMEM_ARB_RING0_THROTTLE_MASK 0x6bc
#define MC_EMEM_ARB_NISO_THROTTLE_MASK 0x6b8
#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1 0xb80
#define MC_SEC_CARVEOUT_BOM 0x670
#define MC_SEC_CARVEOUT_SIZE_MB 0x674
#define MC_SEC_CARVEOUT_ADR_HI 0x9d4
#define MC_SEC_CARVEOUT_REG_CTRL 0x678
#define MC_ERR_SEC_STATUS 0x67c
#define MC_ERR_SEC_ADR 0x680
#define MC_PC_IDLE_CLOCK_GATE_CONFIG 0x684
#define MC_STUTTER_CONTROL 0x688
#define MC_RESERVED_RSV_1 0x958
#define MC_DVFS_PIPE_SELECT 0x95c
#define MC_AHB_PTSA_MIN 0x4e0
#define MC_AUD_PTSA_MIN 0x54c
#define MC_MLL_MPCORER_PTSA_RATE 0x44c
#define MC_RING2_PTSA_RATE 0x440
#define MC_USBD_PTSA_RATE 0x530
#define MC_USBX_PTSA_MIN 0x528
#define MC_USBD_PTSA_MIN 0x534
#define MC_APB_PTSA_MAX 0x4f0
#define MC_JPG_PTSA_RATE 0x584
#define MC_DIS_PTSA_MIN 0x420
#define MC_AVP_PTSA_MAX 0x4fc
#define MC_AVP_PTSA_RATE 0x4f4
#define MC_RING1_PTSA_MIN 0x480
#define MC_DIS_PTSA_MAX 0x424
#define MC_SD_PTSA_MAX 0x4d8
#define MC_MSE_PTSA_RATE 0x4c4
#define MC_VICPC_PTSA_MIN 0x558
#define MC_PCX_PTSA_MAX 0x4b4
#define MC_ISP_PTSA_RATE 0x4a0
#define MC_A9AVPPC_PTSA_MIN 0x48c
#define MC_RING2_PTSA_MAX 0x448
#define MC_AUD_PTSA_RATE 0x548
#define MC_HOST_PTSA_MIN 0x51c
#define MC_MLL_MPCORER_PTSA_MAX 0x454
#define MC_SD_PTSA_MIN 0x4d4
#define MC_RING1_PTSA_RATE 0x47c
#define MC_JPG_PTSA_MIN 0x588
#define MC_HDAPC_PTSA_MIN 0x62c
#define MC_AVP_PTSA_MIN 0x4f8
#define MC_JPG_PTSA_MAX 0x58c
#define MC_VE_PTSA_MAX 0x43c
#define MC_DFD_PTSA_MAX 0x63c
#define MC_VICPC_PTSA_RATE 0x554
#define MC_GK_PTSA_MAX 0x544
#define MC_VICPC_PTSA_MAX 0x55c
#define MC_SDM_PTSA_MAX 0x624
#define MC_SAX_PTSA_RATE 0x4b8
#define MC_PCX_PTSA_MIN 0x4b0
#define MC_APB_PTSA_MIN 0x4ec
#define MC_GK2_PTSA_MIN 0x614
#define MC_PCX_PTSA_RATE 0x4ac
#define MC_RING1_PTSA_MAX 0x484
#define MC_HDAPC_PTSA_RATE 0x628
#define MC_MLL_MPCORER_PTSA_MIN 0x450
#define MC_GK2_PTSA_MAX 0x618
#define MC_AUD_PTSA_MAX 0x550
#define MC_GK2_PTSA_RATE 0x610
#define MC_ISP_PTSA_MAX 0x4a8
#define MC_DISB_PTSA_RATE 0x428
#define MC_VE2_PTSA_MAX 0x49c
#define MC_DFD_PTSA_MIN 0x638
#define MC_FTOP_PTSA_RATE 0x50c
#define MC_A9AVPPC_PTSA_RATE 0x488
#define MC_VE2_PTSA_MIN 0x498
#define MC_USBX_PTSA_MAX 0x52c
#define MC_DIS_PTSA_RATE 0x41c
#define MC_USBD_PTSA_MAX 0x538
#define MC_A9AVPPC_PTSA_MAX 0x490
#define MC_USBX_PTSA_RATE 0x524
#define MC_FTOP_PTSA_MAX 0x514
#define MC_HDAPC_PTSA_MAX 0x630
#define MC_SD_PTSA_RATE 0x4d0
#define MC_DFD_PTSA_RATE 0x634
#define MC_FTOP_PTSA_MIN 0x510
#define MC_SDM_PTSA_RATE 0x61c
#define MC_AHB_PTSA_RATE 0x4dc
#define MC_SMMU_SMMU_PTSA_MAX 0x460
#define MC_RING2_PTSA_MIN 0x444
#define MC_SDM_PTSA_MIN 0x620
#define MC_APB_PTSA_RATE 0x4e8
#define MC_MSE_PTSA_MIN 0x4c8
#define MC_HOST_PTSA_RATE 0x518
#define MC_VE_PTSA_RATE 0x434
#define MC_AHB_PTSA_MAX 0x4e4
#define MC_SAX_PTSA_MIN 0x4bc
#define MC_SMMU_SMMU_PTSA_MIN 0x45c
#define MC_ISP_PTSA_MIN 0x4a4
#define MC_HOST_PTSA_MAX 0x520
#define MC_SAX_PTSA_MAX 0x4c0
#define MC_VE_PTSA_MIN 0x438
#define MC_GK_PTSA_MIN 0x540
#define MC_MSE_PTSA_MAX 0x4cc
#define MC_DISB_PTSA_MAX 0x430
#define MC_DISB_PTSA_MIN 0x42c
#define MC_SMMU_SMMU_PTSA_RATE 0x458
#define MC_VE2_PTSA_RATE 0x494
#define MC_GK_PTSA_RATE 0x53c
#define MC_PTSA_GRANT_DECREMENT 0x960
#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
#define MC_LATENCY_ALLOWANCE_AXIAP_0 0x3a0
#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384
#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc
#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8
#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
#define MC_LATENCY_ALLOWANCE_SE_0 0x3e0
#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3d8
#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 0x694
#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
#define MC_LATENCY_ALLOWANCE_TSECB_0 0x3f0
#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 0x698
#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
#define MC_LATENCY_ALLOWANCE_APE_0 0x3dc
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 0x6a0
#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4
#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3e8
#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
#define MC_LATENCY_ALLOWANCE_HC_1 0x314
#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0
#define MC_LATENCY_ALLOWANCE_NVJPG_0 0x3e4
#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
#define MC_LATENCY_ALLOWANCE_ETR_0 0x3ec
#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 0x69c
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 0x6a4
#define MC_LATENCY_ALLOWANCE_SATA_0 0x350
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 0x690
#define MC_LATENCY_ALLOWANCE_HC_0 0x310
#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8
#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac
#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4
#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388
#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328
#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
#define MC_MIN_LENGTH_APE_0 0xb34
#define MC_MIN_LENGTH_DCB_2 0x8a8
#define MC_MIN_LENGTH_A9AVP_0 0x950
#define MC_MIN_LENGTH_TSEC_0 0x93c
#define MC_MIN_LENGTH_DC_1 0x898
#define MC_MIN_LENGTH_AXIAP_0 0x94c
#define MC_MIN_LENGTH_ISP2B_0 0x930
#define MC_MIN_LENGTH_VI2_0 0x944
#define MC_MIN_LENGTH_DCB_0 0x8a0
#define MC_MIN_LENGTH_DCB_1 0x8a4
#define MC_MIN_LENGTH_PPCS_1 0x8f4
#define MC_MIN_LENGTH_NVJPG_0 0xb3c
#define MC_MIN_LENGTH_HDA_0 0x8c4
#define MC_MIN_LENGTH_NVENC_0 0x8d4
#define MC_MIN_LENGTH_SDMMC_0 0xb18
#define MC_MIN_LENGTH_ISP2B_1 0x934
#define MC_MIN_LENGTH_HC_1 0x8c0
#define MC_MIN_LENGTH_DC_3 0xb20
#define MC_MIN_LENGTH_AVPC_0 0x890
#define MC_MIN_LENGTH_VIC_0 0x940
#define MC_MIN_LENGTH_ISP2_0 0x91c
#define MC_MIN_LENGTH_HC_0 0x8bc
#define MC_MIN_LENGTH_SE_0 0xb38
#define MC_MIN_LENGTH_NVDEC_0 0xb30
#define MC_MIN_LENGTH_SATA_0 0x8fc
#define MC_MIN_LENGTH_DC_0 0x894
#define MC_MIN_LENGTH_XUSB_1 0x92c
#define MC_MIN_LENGTH_DC_2 0x89c
#define MC_MIN_LENGTH_SDMMCAA_0 0xb14
#define MC_MIN_LENGTH_GPU_0 0xb04
#define MC_MIN_LENGTH_ETR_0 0xb44
#define MC_MIN_LENGTH_AFI_0 0x88c
#define MC_MIN_LENGTH_PPCS_0 0x8f0
#define MC_MIN_LENGTH_ISP2_1 0x920
#define MC_MIN_LENGTH_XUSB_0 0x928
#define MC_MIN_LENGTH_MPCORE_0 0x8cc
#define MC_MIN_LENGTH_TSECB_0 0xb48
#define MC_MIN_LENGTH_SDMMCA_0 0xb10
#define MC_MIN_LENGTH_GPU2_0 0xb40
#define MC_MIN_LENGTH_SDMMCAB_0 0xb1c
#define MC_MIN_LENGTH_PTC_0 0x8f8
#define MC_EMEM_ARB_OVERRIDE_1 0x968
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0 0x984
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1 0x988
#define MC_EMEM_ARB_STATS_0 0x990
#define MC_EMEM_ARB_STATS_1 0x994
#define MC_MTS_CARVEOUT_BOM 0x9a0
#define MC_MTS_CARVEOUT_SIZE_MB 0x9a4
#define MC_MTS_CARVEOUT_ADR_HI 0x9a8
#define MC_MTS_CARVEOUT_REG_CTRL 0x9ac
#define MC_ERR_MTS_STATUS 0x9b0
#define MC_ERR_MTS_ADR 0x9b4
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 0xd74
#define MC_SECURITY_CARVEOUT4_CFG0 0xcf8
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 0xd10
#define MC_SECURITY_CARVEOUT4_SIZE_128KB 0xd04
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 0xc28
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 0xc30
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 0xc8c
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 0xd1c
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 0xd70
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 0xc2c
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 0xd7c
#define MC_SECURITY_CARVEOUT3_SIZE_128KB 0xcb4
#define MC_SECURITY_CARVEOUT2_CFG0 0xc58
#define MC_SECURITY_CARVEOUT1_CFG0 0xc08
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 0xc84
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 0xc68
#define MC_SECURITY_CARVEOUT3_BOM 0xcac
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 0xc70
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 0xd78
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 0xc7c
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 0xd18
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 0xcbc
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 0xc38
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 0xc34
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 0xcc0
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 0xd60
#define MC_SECURITY_CARVEOUT3_CFG0 0xca8
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 0xcb8
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 0xc88
#define MC_SECURITY_CARVEOUT2_SIZE_128KB 0xc64
#define MC_SECURITY_CARVEOUT5_BOM_HI 0xd50
#define MC_SECURITY_CARVEOUT1_SIZE_128KB 0xc14
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 0xd14
#define MC_SECURITY_CARVEOUT1_BOM 0xc0c
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 0xd2c
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 0xd68
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 0xcc8
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 0xd58
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 0xd24
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 0xcc4
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 0xc78
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 0xc1c
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 0xc18
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 0xd28
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 0xd5c
#define MC_SECURITY_CARVEOUT3_BOM_HI 0xcb0
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 0xcd8
#define MC_SECURITY_CARVEOUT2_BOM_HI 0xc60
#define MC_SECURITY_CARVEOUT4_BOM_HI 0xd00
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 0xd64
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 0xcdc
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 0xc80
#define MC_SECURITY_CARVEOUT5_SIZE_128KB 0xd54
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 0xd20
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 0xcd4
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 0xd0c
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 0xc74
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 0xccc
#define MC_SECURITY_CARVEOUT4_BOM 0xcfc
#define MC_SECURITY_CARVEOUT5_CFG0 0xd48
#define MC_SECURITY_CARVEOUT2_BOM 0xc5c
#define MC_SECURITY_CARVEOUT5_BOM 0xd4c
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 0xc24
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 0xd6c
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 0xcd0
#define MC_SECURITY_CARVEOUT1_BOM_HI 0xc10
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 0xc20
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 0xc3c
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08
#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
#define MC_DA_CONFIG0 0x9dc
/* Memory Controller clients */
#define CLIENT_ACCESS_NUM_CLIENTS 32
typedef enum {
/* _ACCESS0 */
CSR_PTCR = (0 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0A = (1 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0AB = (2 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0B = (3 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0BB = (4 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0C = (5 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAY0CB = (6 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_AFIR = (14 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_AVPCARM7R = (15 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAYHC = (16 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_DISPLAYHCB = (17 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_HDAR = (21 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_HOST1XDMAR = (22 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_HOST1XR = (23 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_NVENCSRD = (28 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_PPCSAHBDMAR = (29 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_PPCSAHBSLVR = (30 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
CSR_SATAR = (31 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
/* _ACCESS1 */
CSR_VDEBSEVR = (34 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSR_VDEMBER = (35 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSR_VDEMCER = (36 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSR_VDETPER = (37 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSR_MPCORELPR = (38 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSR_MPCORER = (39 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_NVENCSWR = (43 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_AFIW = (49 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_AVPCARM7W = (50 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_HDAW = (53 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_HOST1XW = (54 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_MPCORELPW = (56 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_MPCOREW = (57 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_PPCSAHBDMAW = (59 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_PPCSAHBSLVW = (60 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_SATAW = (61 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_VDEBSEVW = (62 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
CSW_VDEDBGW = (63 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
/* _ACCESS2 */
CSW_VDEMBEW = (64 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_VDETPMW = (65 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_ISPRA = (68 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_ISPWA = (70 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_ISPWB = (71 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_XUSB_HOSTR = (74 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_XUSB_HOSTW = (75 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_XUSB_DEVR = (76 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_XUSB_DEVW = (77 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_ISPRAB = (78 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_ISPWAB = (80 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_ISPWBB = (81 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_TSECSRD = (84 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_TSECSWR = (85 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_A9AVPSCR = (86 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_A9AVPSCW = (87 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_GPUSRD = (88 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSW_GPUSWR = (89 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
CSR_DISPLAYT = (90 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
/* _ACCESS3 */
CSR_SDMMCRA = (96 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_SDMMCRAA = (97 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_SDMMCR = (98 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_SDMMCRAB = (99 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_SDMMCWA = (100 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_SDMMCWAA = (101 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_SDMMCW = (102 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_SDMMCWAB = (103 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_VICSRD = (108 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_VICSWR = (109 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_VIW = (114 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_DISPLAYD = (115 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_NVDECSRD = (120 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_NVDECSWR = (121 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_APER = (122 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_APEW = (123 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSR_NVJPGSRD = (126 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
CSW_NVJPGSWR = (127 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
/* _ACCESS4 */
CSR_SESRD = (128 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSW_SESWR = (129 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSR_AXIAPR = (130 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSW_AXIAPW = (131 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSR_ETRR = (132 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSW_ETRW = (133 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSR_TSECSRDB = (134 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSW_TSECSWRB = (135 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSR_GPUSRD2 = (136 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
CSW_GPUSWR2 = (137 - (CLIENT_ACCESS_NUM_CLIENTS * 4))
} McClient;
void mc_config_tsec_carveout(uint32_t bom, uint32_t size1mb, bool lock);
void mc_config_carveout();
void mc_config_carveout_finalize();
void mc_enable_ahb_redirect();
void mc_disable_ahb_redirect();
void mc_enable();
#endif

View File

@@ -3706,7 +3706,7 @@ static int train_one(int z_val, uint32_t next_rate, uint32_t current_rate, tegra
return 0;
}
void train_dram() {
void train_dram(void) {
volatile tegra_car_t *car = car_get_regs();
tegra_emc_timing_t *timing_tables;

View File

@@ -754,6 +754,6 @@ enum {
};
/* Train all possible DRAM sequences. */
void train_dram();
void train_dram(void);
#endif

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2018-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/>.
*/
#ifndef FUSEE_STAGE2_H
#define FUSEE_STAGE2_H
#include "lib/log.h"
#define MTC_ARGV_ARGUMENT_STRUCT 0
#define MTC_ARGC 1
typedef struct {
ScreenLogLevel log_level;
} stage2_mtc_args_t;
#endif

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2018 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/>.
*/
.macro CLEAR_GPR_REG_ITER
mov r\@, #0
.endm
.section .text.start, "ax", %progbits
.arm
.align 5
.global _start
.type _start, %function
_start:
/* Switch to system mode, mask all interrupts, clear all flags */
msr cpsr_cxsf, #0xDF
/* Backup current stack pointer. */
mov r12, sp
/* Set the stack pointer */
ldr sp, =__stack_top__
mov fp, #0
/* Save context */
push {r12, lr}
/* Call init. */
bl __program_init
/* Set r0 to r12 to 0 (for debugging) & call main */
.rept 13
CLEAR_GPR_REG_ITER
.endr
ldr r0, =__program_argc
ldr r1, =__program_argv
ldr r0, [r0]
ldr r1, [r1]
bl main
/* Save result. */
push {r0}
/* Exit manually. */
bl __program_exit
/* Restore result. */
pop {r0}
/* Restore context */
pop {r12}
pop {lr}
/* Restore previous stack pointer. */
mov sp, r12
/* Return */
bx lr

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 2018-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/>.
*/
#ifndef FUSEE_TIMERS_H
#define FUSEE_TIMERS_H
#include "utils.h"
#define TIMERS_BASE 0x60005000
#define MAKE_TIMERS_REG(n) MAKE_REG32(TIMERS_BASE + n)
#define TIMERUS_CNTR_1US_0 MAKE_TIMERS_REG(0x10)
#define TIMERUS_USEC_CFG_0 MAKE_TIMERS_REG(0x14)
#define SHARED_INTR_STATUS_0 MAKE_TIMERS_REG(0x1A0)
#define SHARED_TIMER_SECURE_CFG_0 MAKE_TIMERS_REG(0x1A4)
#define RTC_BASE 0x7000E000
#define MAKE_RTC_REG(n) MAKE_REG32(RTC_BASE + n)
#define RTC_SECONDS MAKE_RTC_REG(0x08)
#define RTC_SHADOW_SECONDS MAKE_RTC_REG(0x0C)
#define RTC_MILLI_SECONDS MAKE_RTC_REG(0x10)
typedef struct {
uint32_t CONFIG;
uint32_t STATUS;
uint32_t COMMAND;
uint32_t PATTERN;
} watchdog_timers_t;
#define GET_WDT(n) ((volatile watchdog_timers_t *)(TIMERS_BASE + 0x100 + 0x20 * n))
#define WDT_REBOOT_PATTERN 0xC45A
#define GET_WDT_REBOOT_CFG_REG(n) MAKE_REG32(TIMERS_BASE + 0x60 + 0x8 * n)
void wait(uint32_t microseconds);
static inline uint32_t get_time_s(void) {
return RTC_SECONDS;
}
static inline uint32_t get_time_ms(void) {
return (RTC_MILLI_SECONDS | (RTC_SHADOW_SECONDS << 10));
}
static inline uint32_t get_time_us(void) {
return TIMERUS_CNTR_1US_0;
}
/**
* Returns the time in microseconds.
*/
static inline uint32_t get_time(void) {
return get_time_us();
}
/**
* Returns the number of microseconds that have passed since a given get_time().
*/
static inline uint32_t get_time_since(uint32_t base) {
return get_time_us() - base;
}
/**
* Delays for a given number of microseconds.
*/
static inline void udelay(uint32_t usecs) {
uint32_t start = get_time_us();
while (get_time_us() - start < usecs);
}
/**
* Delays for a given number of milliseconds.
*/
static inline void mdelay(uint32_t msecs) {
uint32_t start = get_time_ms();
while (get_time_ms() - start < msecs);
}
__attribute__ ((noreturn)) void watchdog_reboot(void);
#endif

View File

@@ -13,18 +13,28 @@
* 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 <stdbool.h>
#include <stdarg.h>
#include "utils.h"
#include "lib/log.h"
#include <switch.h>
#include "pm_registration.hpp"
#include "pm_info.hpp"
Result InformationService::GetTitleId(Out<u64> tid, u64 pid) {
std::scoped_lock<ProcessList &> lk(Registration::GetProcessList());
std::shared_ptr<Registration::Process> proc = Registration::GetProcess(pid);
if (proc != NULL) {
tid.SetValue(proc->tid_sid.title_id);
return ResultSuccess;
__attribute__ ((noreturn)) void generic_panic(void) {
print(SCREEN_LOG_LEVEL_ERROR, "Panic raised!");
while (true) {
/* Lock. */
}
return ResultPmProcessNotFound;
}
__attribute__((noreturn)) void fatal_error(const char *fmt, ...) {
va_list args;
print(SCREEN_LOG_LEVEL_ERROR, "Fatal error: ");
va_start(args, fmt);
vprint(SCREEN_LOG_LEVEL_ERROR, fmt, args);
va_end(args);
while (true) {
/* Lock. */
}
}

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