Compare commits
137 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c62c4846fc | ||
|
|
8db5b01507 | ||
|
|
a6e405c988 | ||
|
|
6613fda4b1 | ||
|
|
a18a6e87df | ||
|
|
93d83c5bb9 | ||
|
|
6ee8720028 | ||
|
|
600d68bd1a | ||
|
|
0c3a294cbe | ||
|
|
25218795b4 | ||
|
|
a65ec67128 | ||
|
|
5d753f2384 | ||
|
|
1f2de35f94 | ||
|
|
5c140b4f35 | ||
|
|
362ee3cdb0 | ||
|
|
215f1bc8ee | ||
|
|
4d72c2b37a | ||
|
|
dc4dbe29ae | ||
|
|
72dd25a99e | ||
|
|
39d041466d | ||
|
|
442ebff829 | ||
|
|
7e169bc7df | ||
|
|
00f4e5158f | ||
|
|
0c688189f6 | ||
|
|
7cee36544c | ||
|
|
f9c1d5fc1b | ||
|
|
d95e20952c | ||
|
|
32a90334bb | ||
|
|
f534d3498e | ||
|
|
3ea9f444db | ||
|
|
5672c935ed | ||
|
|
4cc2b5c38a | ||
|
|
00e3d874e3 | ||
|
|
803e91a8c4 | ||
|
|
227a1d938d | ||
|
|
fc7f06dc78 | ||
|
|
6777dd9b38 | ||
|
|
4db212ea7b | ||
|
|
8177a27db9 | ||
|
|
27ff119ba6 | ||
|
|
c20774ff5d | ||
|
|
a9f5b7728b | ||
|
|
08ad48fbf3 | ||
|
|
2d0c881ffe | ||
|
|
c916a7db88 | ||
|
|
a5da286351 | ||
|
|
20a48c3a26 | ||
|
|
5bba0f47ff | ||
|
|
bfc987abcd | ||
|
|
85bf7c86e0 | ||
|
|
2225b86eea | ||
|
|
d09be18359 | ||
|
|
09ab3efddd | ||
|
|
382a0192f9 | ||
|
|
e3b968fa80 | ||
|
|
6f85b11fcc | ||
|
|
e561919a52 | ||
|
|
b0a66a63ba | ||
|
|
0d840e199d | ||
|
|
3a2bceef8d | ||
|
|
e871a754a8 | ||
|
|
6333327b81 | ||
|
|
18ca8aaf5b | ||
|
|
67c0f4527e | ||
|
|
e5c5101e8a | ||
|
|
934ff7bbde | ||
|
|
014f08f6b4 | ||
|
|
6ba2090c01 | ||
|
|
61fcf5e0f4 | ||
|
|
9217e4c5f9 | ||
|
|
3ccbb34c62 | ||
|
|
9baa4a17ed | ||
|
|
6bbece39bc | ||
|
|
729447eab0 | ||
|
|
1e7f41ea9f | ||
|
|
d0d4888184 | ||
|
|
804e5d49bb | ||
|
|
6d1d226842 | ||
|
|
06416aeded | ||
|
|
4fbae9e5a4 | ||
|
|
c87be7cd69 | ||
|
|
e62754ed56 | ||
|
|
53d7281e66 | ||
|
|
731a2c11a4 | ||
|
|
ec4d078d6d | ||
|
|
f9b48f06a3 | ||
|
|
d986ffa153 | ||
|
|
2357bc70a7 | ||
|
|
e86e1588e3 | ||
|
|
4be88c7180 | ||
|
|
8e8daa64ba | ||
|
|
1671c04e24 | ||
|
|
d3d6c552b7 | ||
|
|
8d9336f561 | ||
|
|
169ec9c12e | ||
|
|
60b831f369 | ||
|
|
4191dcee75 | ||
|
|
44725c8910 | ||
|
|
cead8a36ea | ||
|
|
7b6050a0cb | ||
|
|
491383c637 | ||
|
|
d7a3645f7f | ||
|
|
241b8f4627 | ||
|
|
3f7238cb10 | ||
|
|
1e8a6358ad | ||
|
|
c412d996fd | ||
|
|
f2086fe054 | ||
|
|
3f9d6574fb | ||
|
|
e996acff66 | ||
|
|
e274d3ef37 | ||
|
|
8663eb1a6e | ||
|
|
938da08e14 | ||
|
|
0468bd9483 | ||
|
|
c077c75b8d | ||
|
|
24f7977fa6 | ||
|
|
6699fda8c9 | ||
|
|
06e4158b93 | ||
|
|
b82d8aaba9 | ||
|
|
6829572556 | ||
|
|
11d8021435 | ||
|
|
493b074a9e | ||
|
|
befd912a88 | ||
|
|
c96ae0148e | ||
|
|
63a9c856fc | ||
|
|
31fde233e1 | ||
|
|
f9bf8923b1 | ||
|
|
ee40dcd76f | ||
|
|
c60ee15449 | ||
|
|
876d94c338 | ||
|
|
7c37b7497b | ||
|
|
dfcba5e6d4 | ||
|
|
a0cf3bbed8 | ||
|
|
1c503d59b5 | ||
|
|
0bf7df0426 | ||
|
|
2c46ec9638 | ||
|
|
ef0c8e0aac | ||
|
|
1a5801ee0f |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
common/defaults/hbl_html/accessible-urls/accessible-urls.txt text eol=lf
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -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
|
||||
|
||||
4
Makefile
4
Makefile
@@ -57,11 +57,13 @@ 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
|
||||
cp sept/sept-secondary/sept-secondary.bin atmosphere-$(AMSVER)/sept/sept-secondary.bin
|
||||
cp sept/sept-secondary/sept-secondary.enc atmosphere-$(AMSVER)/sept/sept-secondary.enc
|
||||
cp sept/sept-secondary/sept-secondary_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_00.enc
|
||||
cp sept/sept-secondary/sept-secondary_01.enc atmosphere-$(AMSVER)/sept/sept-secondary_01.enc
|
||||
cp common/defaults/BCT.ini atmosphere-$(AMSVER)/atmosphere/BCT.ini
|
||||
cp common/defaults/loader.ini atmosphere-$(AMSVER)/atmosphere/loader.ini
|
||||
cp common/defaults/system_settings.ini atmosphere-$(AMSVER)/atmosphere/system_settings.ini
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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
|
||||
@@ -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/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ATMOSPHERE_TARGET_FIRMWARE_H
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_H
|
||||
|
||||
@@ -26,11 +26,13 @@
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_620 7
|
||||
#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_800
|
||||
#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_800
|
||||
#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
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ATMOSPHERE_VERSION_H
|
||||
#define ATMOSPHERE_VERSION_H
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 9
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 0
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 4
|
||||
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 8
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 9
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 1
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,73 @@
|
||||
# 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. :)
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.9.0
|
||||
+ Creport output was improved significantly.
|
||||
+ Thread names are now dumped on crash in addition to 0x100 of TLS from each thread.
|
||||
@@ -133,7 +202,7 @@
|
||||
+ This should greatly simplify the update process in the future, for users who do not launch Atmosphère using fusee.
|
||||
+ Support for cheat codes was added.
|
||||
+ These are handled by a new `dmnt` sysmodule, which will also reimplement Nintendo's Debug Monitor in the future.
|
||||
+ Cheat codes can be enabled/disabled at application launch via a per-title key combination.
|
||||
+ Cheat codes can be enabled/disabled at application launch via a per-title key combination.
|
||||
+ For details, please see the [cheat loading documentation](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/cheats.md#cheat-loating-process).
|
||||
+ Cheat codes are fully backwards compatible with the pre-existing format, although a number of bugs have been fixed and some new features have been added.
|
||||
+ For details, please see [the compatibility documentation](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/cheats.md#cheat-code-compatibility).
|
||||
@@ -206,7 +275,7 @@
|
||||
+ This should prevent running FS without `nogc` patches after updating to an unsupported system version.
|
||||
+ An extension was added to `exosphere` allowing userland applications to cause the system to reboot into RCM:
|
||||
+ This is done by calling smcSetConfig(id=65001, value=<nonzero>); user homebrew can use splSetConfig for this.
|
||||
+ On fatal error, the user can now choose to perform a standard reboot via the power button, or a reboot into RCM via either volume button.
|
||||
+ On fatal error, the user can now choose to perform a standard reboot via the power button, or a reboot into RCM via either volume button.
|
||||
+ A custom message was added to `fatal` for when an Atmosphère API version mismatch is detected (2495-1623).
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.8.0
|
||||
@@ -249,7 +318,7 @@
|
||||
+ Instead of only checking one of the crashing thread's PC/LR for code region presence, creport now checks both + every address in the stacktrace. This is also now done for every thread.
|
||||
+ This matches the improvement Nintendo added to official creport in 6.1.0.
|
||||
+ The code region detection heuristic was further improved by checking whether an address points to .rodata or .rwdata, instead of just .text.
|
||||
+ This means that a crash appears in a loaded NRO (or otherwise discontiguous) code region, creport will be able to detect all active code regions, and not just that one.
|
||||
+ This means that a crash appears in a loaded NRO (or otherwise discontiguous) code region, creport will be able to detect all active code regions, and not just that one.
|
||||
## 0.7.4
|
||||
+ [libstratosphere](https://github.com/Atmosphere-NX/libstratosphere) has been completely refactored/rewritten, and split into its own, separate submodule.
|
||||
+ While this is mostly "under the hood" for end-users, the refactor is faster (improving both boot-time and runtime performance), more accurate (many of the internal IPC structures are now bug-for-bug compatible with Nintendo's implementations), and significantly more stable (it fixes a large number of bugs present in the old library).
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/m4xw/emuMMC
|
||||
branch = develop
|
||||
commit = e72e8f1c8fb7ad8fe7cdedc3784729ea8e11f927
|
||||
parent = 87a1aa17a7693ef39ffea91ad0fa1b530f278bb0
|
||||
commit = 5f5817e646d4c800ae4bd6db4a57eee6bde62eed
|
||||
parent = 68091a28a23836032c98396259f7ee4796b312f9
|
||||
method = rebase
|
||||
cmdver = 0.4.0
|
||||
|
||||
@@ -17,7 +17,7 @@ else
|
||||
EMUMMCDIR ?= $(CURDIR)/../
|
||||
endif
|
||||
|
||||
include $(EMUMMCDIR)/nx/switch_rules
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
@@ -31,7 +31,7 @@ CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(EMUMMCDIR)/nx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
"svcReplyAndReceive": "0x43",
|
||||
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
||||
"svcCreateEvent": "0x45",
|
||||
"svcReadWriteRegister": "0x4E",
|
||||
"svcCreateInterruptEvent": "0x53",
|
||||
"svcQueryIoMapping": "0x55",
|
||||
"svcCreateDeviceAddressSpace": "0x56",
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
code PT_LOAD FLAGS(5) /* Read | Execute */;
|
||||
rodata PT_LOAD FLAGS(4) /* Read */;
|
||||
data PT_LOAD FLAGS(6) /* Read | Write */;
|
||||
dyn PT_DYNAMIC;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* =========== CODE section =========== */
|
||||
PROVIDE(__start__ = 0x0);
|
||||
. = __start__;
|
||||
__code_start = . ;
|
||||
|
||||
/*.trampoline :
|
||||
{
|
||||
KEEP (*(.trampoline))
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.emuMMC_ctx :
|
||||
{
|
||||
KEEP (*(.emuMMC_ctx))
|
||||
. = ALIGN(8);
|
||||
} :code */
|
||||
|
||||
.crt0 :
|
||||
{
|
||||
KEEP (*(.crt0))
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.init :
|
||||
{
|
||||
KEEP( *(.init) )
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.plt :
|
||||
{
|
||||
*(.plt)
|
||||
*(.iplt)
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP( *(.fini) )
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
/* =========== RODATA section =========== */
|
||||
. = ALIGN(0x1000);
|
||||
__rodata_start = . ;
|
||||
|
||||
.nx-module-name : { KEEP (*(.nx-module-name)) } :rodata
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
. = ALIGN(8);
|
||||
} :rodata
|
||||
|
||||
.eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } :rodata
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } :rodata
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } :rodata
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } : rodata
|
||||
|
||||
.dynamic : { *(.dynamic) } :rodata :dyn
|
||||
.dynsym : { *(.dynsym) } :rodata
|
||||
.dynstr : { *(.dynstr) } :rodata
|
||||
.rela.dyn : { *(.rela.*) } :rodata
|
||||
.interp : { *(.interp) } :rodata
|
||||
.hash : { *(.hash) } :rodata
|
||||
.gnu.hash : { *(.gnu.hash) } :rodata
|
||||
.gnu.version : { *(.gnu.version) } :rodata
|
||||
.gnu.version_d : { *(.gnu.version_d) } :rodata
|
||||
.gnu.version_r : { *(.gnu.version_r) } :rodata
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) } :rodata
|
||||
|
||||
/* =========== DATA section =========== */
|
||||
. = ALIGN(0x1000);
|
||||
__data_start = . ;
|
||||
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } :data
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } :data
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } : data
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } :data
|
||||
|
||||
.tdata ALIGN(8) :
|
||||
{
|
||||
__tdata_lma = .;
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
. = ALIGN(8);
|
||||
__tdata_lma_end = .;
|
||||
} :data
|
||||
|
||||
.tbss ALIGN(8) :
|
||||
{
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
|
||||
. = ALIGN(8);
|
||||
} :data
|
||||
|
||||
.preinit_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
} :data
|
||||
|
||||
.init_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE (__init_array_end = .);
|
||||
} :data
|
||||
|
||||
.fini_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE (__fini_array_end = .);
|
||||
} :data
|
||||
|
||||
.ctors ALIGN(8) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
} :data
|
||||
|
||||
.dtors ALIGN(8) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
} :data
|
||||
|
||||
__got_start__ = .;
|
||||
|
||||
.got : { *(.got) *(.igot) } :data
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) } :data
|
||||
|
||||
__got_end__ = .;
|
||||
|
||||
.data ALIGN(8) :
|
||||
{
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
} :data
|
||||
|
||||
__bss_start__ = .;
|
||||
.bss ALIGN(8) :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(8);
|
||||
|
||||
/* Reserve space for the TLS segment of the main thread */
|
||||
__tls_start = .;
|
||||
. += + SIZEOF(.tdata) + SIZEOF(.tbss);
|
||||
__tls_end = .;
|
||||
} : data
|
||||
__bss_end__ = .;
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
__end__ = ABSOLUTE(.) ;
|
||||
|
||||
PROVIDE(__injected_size__ = (__end__ - __start__));
|
||||
|
||||
/* ==================
|
||||
==== 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) }
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T %:getenv(PWD /nx/switch.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak --build-id=sha1 --nx-module-name
|
||||
|
||||
*startfile:
|
||||
crti%O%s crtbegin%O%s
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro)
|
||||
endif
|
||||
|
||||
include $(DEVKITPRO)/devkitA64/base_rules
|
||||
|
||||
PORTLIBS := $(PORTLIBS_PATH)/switch
|
||||
PATH := $(PORTLIBS)/bin:$(PATH)
|
||||
|
||||
LIBNX ?= $(DEVKITPRO)/libnx
|
||||
|
||||
ifeq ($(strip $(APP_TITLE)),)
|
||||
APP_TITLE := $(notdir $(OUTPUT))
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(APP_AUTHOR)),)
|
||||
APP_AUTHOR := Unspecified Author
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(APP_VERSION)),)
|
||||
APP_VERSION := 1.0.0
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(APP_ICON)),)
|
||||
APP_ICON := $(LIBNX)/default_icon.jpg
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.nacp: $(MAKEFILE_LIST)
|
||||
@nacptool --create "$(APP_TITLE)" "$(APP_AUTHOR)" "$(APP_VERSION)" $@ $(NACPFLAGS)
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.npdm: $(APP_JSON)
|
||||
@npdmtool $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
define make_pfs0
|
||||
@mkdir -p exefs
|
||||
@[ $(BUILD_EXEFS_SRC) ] && [ -d $(BUILD_EXEFS_SRC) ] && cp -R $(BUILD_EXEFS_SRC)/* exefs || echo > /dev/null
|
||||
@cp $*.nso exefs/main
|
||||
@[ $(APP_JSON) ] && cp $*.npdm exefs/main.npdm || echo > /dev/null
|
||||
@build_pfs0 exefs $@
|
||||
@echo built ... $(notdir $@)
|
||||
endef
|
||||
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
%.pfs0: %.nso
|
||||
else
|
||||
%.pfs0: %.nso %.npdm
|
||||
endif
|
||||
$(make_pfs0)
|
||||
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
%.nsp: %.nso
|
||||
else
|
||||
%.nsp: %.nso %.npdm
|
||||
endif
|
||||
$(make_pfs0)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.nso: %.elf
|
||||
@elf2nso $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.nro: %.elf
|
||||
@elf2nro $< $@ $(NROFLAGS)
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.kip: %.elf
|
||||
@elf2kip $< $(APP_JSON) $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.elf:
|
||||
@echo linking $(notdir $@)
|
||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
@$(NM) -CSn $@ > $(notdir $*.lst)
|
||||
@@ -39,29 +39,33 @@
|
||||
#include "offsets/700_exfat.h"
|
||||
#include "offsets/800.h"
|
||||
#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
|
||||
@@ -88,6 +92,10 @@ DEFINE_OFFSET_STRUCT(_700);
|
||||
DEFINE_OFFSET_STRUCT(_700_EXFAT);
|
||||
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) {
|
||||
@@ -137,6 +145,14 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
return &(GET_OFFSET_STRUCT_NAME(_800));
|
||||
case FS_VER_8_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_800_EXFAT));
|
||||
case FS_VER_8_1_0:
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
typedef struct {
|
||||
int opcode_reg;
|
||||
uint32_t adrp_offset;
|
||||
uint32_t add_rel_offset;
|
||||
} fs_offsets_nintendo_path_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -40,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[];
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
char *device_addr_buffer;
|
||||
uint64_t device_addr_buffer_size;
|
||||
char *device_addr_buffer_masked;
|
||||
@@ -28,25 +29,30 @@ typedef struct {
|
||||
|
||||
_Static_assert(__alignof(sdmmc_dma_buffer_t) == 8, "sdmmc_dma_buffer_t definition");
|
||||
|
||||
typedef struct sdmmc_accessor_vt {
|
||||
typedef struct sdmmc_accessor_vt
|
||||
{
|
||||
void *ctor;
|
||||
void *dtor;
|
||||
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;
|
||||
|
||||
typedef struct {
|
||||
_Static_assert(__alignof(sdmmc_accessor_vt_t) == 8, "sdmmc_accessor_vt_t definition");
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *vtab;
|
||||
t210_sdmmc_t *io_map;
|
||||
sdmmc_dma_buffer_t dmaBuffers[3];
|
||||
// More not included because we don't use it.
|
||||
} mmc_obj_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
sdmmc_accessor_vt_t *vtab;
|
||||
mmc_obj_t *parent;
|
||||
// More not included because we don't use it.
|
||||
|
||||
@@ -56,6 +56,12 @@ enum FS_VER
|
||||
FS_VER_8_0_0,
|
||||
FS_VER_8_0_0_EXFAT,
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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,17 +43,16 @@
|
||||
#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
|
||||
#define FS_OFFSET_100_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 9, .adrp_offset = 0x00032C58}, \
|
||||
{.opcode_reg = 8, .adrp_offset = 0x00032C60}, \
|
||||
{.opcode_reg = 9, .adrp_offset = 0x00032F3C}, \
|
||||
{.opcode_reg = 8, .adrp_offset = 0x00032F44}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 9, .adrp_offset = 0x00032C58, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 8, .adrp_offset = 0x00032C60, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 9, .adrp_offset = 0x00032F3C, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 8, .adrp_offset = 0x00032F44, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_100_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_200_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00033F08}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035084}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003537C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00033F08, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035084, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003537C, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_200_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_200_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00033F08}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035084}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003537C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00033F08, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035084, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003537C, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_200_EXFAT_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_210_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000342E0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003545C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035754}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000342E0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003545C, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035754, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_210_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_210_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000342E0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003545C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035754}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000342E0, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003545C, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035754, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_210_EXFAT_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_300_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000391F4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A480}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A778}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000391F4, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A480, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A778, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_300_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_300_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000391F4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A480}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A778}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000391F4, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A480, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A778, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_300_EXFAT_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_301_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00039260}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A4EC}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A7E4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00039260, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A4EC, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A7E4, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_301_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_301_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00039260}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A4EC}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A7E4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00039260, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A4EC, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A7E4, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_301_EXFAT_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_400_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_400_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_400_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_400_EXFAT_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_410_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4, .add_rel_offset = 0x0000000C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_410_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_410_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8, .add_rel_offset = 12}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4, .add_rel_offset = 12}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_410_EXFAT_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_500_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00028980}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002ACE4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B220}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00028980, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002ACE4, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B220, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_500_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_500_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00028980}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002ACE4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B220}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00028980, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002ACE4, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B220, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_500_EXFAT_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_510_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000289B0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002AD14}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B250}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000289B0, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002AD14, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B250, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_510_H__
|
||||
|
||||
@@ -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,16 +43,15 @@
|
||||
#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
|
||||
#define FS_OFFSET_510_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000289B0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002AD14}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B250}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000289B0, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002AD14, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B250, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_510_EXFAT_H__
|
||||
|
||||
@@ -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,17 +43,16 @@
|
||||
#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
|
||||
#define FS_OFFSET_600_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000790DC}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007A924}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007AB18}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007AEF4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0} \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000790DC, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007A924, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007AB18, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007AEF4, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0} \
|
||||
}
|
||||
|
||||
#endif // __FS_600_H__
|
||||
|
||||
@@ -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,17 +43,16 @@
|
||||
#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
|
||||
#define FS_OFFSET_600_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000847DC}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00086024}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00086218}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000865F4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0} \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000847DC, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00086024, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00086218, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000865F4, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0} \
|
||||
}
|
||||
|
||||
#endif // __FS_600_EXFAT_H__
|
||||
|
||||
@@ -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,18 +43,17 @@
|
||||
#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
|
||||
#define FS_OFFSET_700_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007DA90}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F344}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F538}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F914}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0007FAD8}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007DA90, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F344, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F538, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F914, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0007FAD8, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_700_H__
|
||||
|
||||
@@ -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,18 +43,17 @@
|
||||
#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
|
||||
#define FS_OFFSET_700_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00089040}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008A8F4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008AAE8}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008AEC4}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0008B088}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00089040, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008A8F4, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008AAE8, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008AEC4, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0008B088, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_700_EXFAT_H__
|
||||
|
||||
@@ -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,18 +43,17 @@
|
||||
#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
|
||||
#define FS_OFFSET_800_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F5F0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081084}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081278}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081654}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00081818}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0} \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F5F0, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081084, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081278, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081654, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00081818, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0} \
|
||||
}
|
||||
|
||||
#endif // __FS_800_H__
|
||||
|
||||
@@ -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,18 +43,17 @@
|
||||
#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
|
||||
#define FS_OFFSET_800_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008ABA0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008C634}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008C828}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008CC04}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0008CDC8}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0} \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008ABA0, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008C634, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008C828, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008CC04, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0008CDC8, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0} \
|
||||
}
|
||||
|
||||
#endif // __FS_800_EXFAT_H__
|
||||
|
||||
59
emummc/source/FS/offsets/810.h
Normal file
59
emummc/source/FS/offsets/810.h
Normal 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_810_H__
|
||||
#define __FS_810_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_810_SDMMC_ACCESSOR_GC 0x15EA20
|
||||
#define FS_OFFSET_810_SDMMC_ACCESSOR_SD 0x15E790
|
||||
#define FS_OFFSET_810_SDMMC_ACCESSOR_NAND 0x15AC80
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_810_SDMMC_WRAPPER_READ 0x152A80
|
||||
#define FS_OFFSET_810_SDMMC_WRAPPER_WRITE 0x152B60
|
||||
#define FS_OFFSET_810_RTLD 0x5B4
|
||||
#define FS_OFFSET_810_RTLD_DESTINATION 0x9C
|
||||
|
||||
#define FS_OFFSET_810_CLKRST_SET_MIN_V_CLK_RATE 0x16F370
|
||||
|
||||
// Misc funcs
|
||||
#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
|
||||
#define FS_OFFSET_810_ACTIVE_PARTITION 0xF15C28
|
||||
#define FS_OFFSET_810_SDMMC_DAS_HANDLE 0xE167C0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_810_SD_DAS_INIT 0x87D58
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_810_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F5F0, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081084, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081278, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081654, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00081818, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0} \
|
||||
}
|
||||
|
||||
#endif // __FS_810_H__
|
||||
59
emummc/source/FS/offsets/810_exfat.h
Normal file
59
emummc/source/FS/offsets/810_exfat.h
Normal 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_810_EXFAT_H__
|
||||
#define __FS_810_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_810_EXFAT_SDMMC_ACCESSOR_GC 0x169FD0
|
||||
#define FS_OFFSET_810_EXFAT_SDMMC_ACCESSOR_SD 0x169D40
|
||||
#define FS_OFFSET_810_EXFAT_SDMMC_ACCESSOR_NAND 0x166230
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_810_EXFAT_SDMMC_WRAPPER_READ 0x15E030
|
||||
#define FS_OFFSET_810_EXFAT_SDMMC_WRAPPER_WRITE 0x15E110
|
||||
#define FS_OFFSET_810_EXFAT_RTLD 0x5B4
|
||||
#define FS_OFFSET_810_EXFAT_RTLD_DESTINATION 0x9C
|
||||
|
||||
#define FS_OFFSET_810_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x17A920
|
||||
|
||||
// Misc funcs
|
||||
#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
|
||||
#define FS_OFFSET_810_EXFAT_ACTIVE_PARTITION 0xFF9C28
|
||||
#define FS_OFFSET_810_EXFAT_SDMMC_DAS_HANDLE 0xEFAA20
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_810_EXFAT_SD_DAS_INIT 0x93308
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_810_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008ABA0, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008C634, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008C828, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008CC04, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0008CDC8, .add_rel_offset = 4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0} \
|
||||
}
|
||||
|
||||
#endif // __FS_810_EXFAT_H__
|
||||
59
emummc/source/FS/offsets/900.h
Normal file
59
emummc/source/FS/offsets/900.h
Normal 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__
|
||||
59
emummc/source/FS/offsets/900_exfat.h
Normal file
59
emummc/source/FS/offsets/900_exfat.h
Normal 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__
|
||||
@@ -23,9 +23,15 @@
|
||||
#include "sd.h"
|
||||
#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)
|
||||
{
|
||||
const u32 mask = (size < 32 ? 1 << size : 0) - 1;
|
||||
@@ -41,6 +47,119 @@ static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
|
||||
* Common functions for SD and MMC.
|
||||
*/
|
||||
|
||||
// FS DMA calculations.
|
||||
intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors)
|
||||
{
|
||||
int dma_buf_idx = 0;
|
||||
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 (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[0].device_addr_buffer_size])
|
||||
{
|
||||
dma_buf_idx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
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 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
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 = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If buffer is on a random heap
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sdmmc_memcpy_buf = false;
|
||||
|
||||
intptr_t admaaddr = (intptr_t)&_this->parent->dmaBuffers[dma_buf_idx].device_addr_buffer_masked[actual_buf_start - dma_buffer_start];
|
||||
return admaaddr;
|
||||
}
|
||||
|
||||
int sdmmc_calculate_dma_index(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors)
|
||||
{
|
||||
int dma_buf_idx = 0;
|
||||
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 (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[0].device_addr_buffer_size])
|
||||
{
|
||||
dma_buf_idx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
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 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
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 = 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sdmmc_memcpy_buf = true;
|
||||
return dma_buf_idx;
|
||||
}
|
||||
|
||||
static int _sdmmc_storage_check_result(u32 res)
|
||||
{
|
||||
//Error mask:
|
||||
@@ -129,9 +248,11 @@ static int _sdmmc_storage_check_status(sdmmc_storage_t *storage)
|
||||
static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out, u32 sector, u32 num_sectors, void *buf, u32 is_write)
|
||||
{
|
||||
sdmmc_cmd_t cmdbuf;
|
||||
sdmmc_req_t reqbuf;
|
||||
u32 tmp = 0;
|
||||
|
||||
sdmmc_init_cmd(&cmdbuf, is_write ? MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK, sector, SDMMC_RSP_TYPE_1, 0);
|
||||
|
||||
sdmmc_req_t reqbuf;
|
||||
reqbuf.buf = buf;
|
||||
reqbuf.num_sectors = num_sectors;
|
||||
reqbuf.blksize = 512;
|
||||
@@ -140,12 +261,12 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out
|
||||
reqbuf.is_auto_cmd12 = 1;
|
||||
|
||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, blkcnt_out))
|
||||
{
|
||||
u32 tmp = 0;
|
||||
{
|
||||
sdmmc_stop_transmission(storage->sdmmc, &tmp);
|
||||
_sdmmc_storage_get_status(storage, &tmp, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -186,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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -623,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 &&
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define _SDMMC_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "../FS/FS.h"
|
||||
#include "sdmmc_driver.h"
|
||||
|
||||
typedef struct _mmc_cid
|
||||
@@ -102,6 +103,9 @@ typedef struct _sdmmc_storage_t
|
||||
sd_ssr_t ssr;
|
||||
} sdmmc_storage_t;
|
||||
|
||||
extern sdmmc_accessor_t *_current_accessor;
|
||||
extern bool sdmmc_memcpy_buf;
|
||||
|
||||
int sdmmc_storage_end(sdmmc_storage_t *storage);
|
||||
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
|
||||
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
|
||||
@@ -109,5 +113,8 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32
|
||||
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_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
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "../soc/pmc.h"
|
||||
#include "../soc/pinmux.h"
|
||||
#include "../soc/gpio.h"
|
||||
#include "../utils/fatal.h"
|
||||
|
||||
#define DPRINTF(...)
|
||||
|
||||
@@ -788,7 +789,15 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
|
||||
u32 blkcnt = req->num_sectors;
|
||||
if (blkcnt >= 0xFFFF)
|
||||
blkcnt = 0xFFFF;
|
||||
u64 admaaddr = sdmmc->dma_addr_fs;
|
||||
|
||||
u64 admaaddr = (u64)sdmmc_calculate_dma_addr(_current_accessor, req->buf, blkcnt);
|
||||
if (!admaaddr)
|
||||
{
|
||||
// buf is on a heap
|
||||
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;
|
||||
}
|
||||
|
||||
//Check alignment.
|
||||
if (admaaddr & 7)
|
||||
@@ -870,7 +879,22 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
if (req)
|
||||
{
|
||||
_sdmmc_config_dma(sdmmc, &blkcnt, req);
|
||||
armDCacheFlush(req->buf, req->blksize * blkcnt);
|
||||
if(!sdmmc_memcpy_buf)
|
||||
{
|
||||
// Flush from/to phys
|
||||
armDCacheFlush(req->buf, req->blksize * blkcnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(req->is_write)
|
||||
{
|
||||
void* dma_addr = &_current_accessor->parent->dmaBuffers[sdmmc->last_dma_idx].device_addr_buffer[0];
|
||||
memcpy(dma_addr, req->buf, req->blksize * blkcnt);
|
||||
|
||||
// Flush to phys
|
||||
armDCacheFlush(dma_addr, req->blksize * blkcnt);
|
||||
}
|
||||
}
|
||||
|
||||
_sdmmc_enable_interrupts(sdmmc);
|
||||
is_data_present = true;
|
||||
@@ -892,8 +916,15 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
{
|
||||
sdmmc->expected_rsp_type = cmd->rsp_type;
|
||||
_sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type);
|
||||
|
||||
/*if(sdmmc->rsp[0] & 0xFDF9A080)
|
||||
{
|
||||
res = 0;
|
||||
sdmmc->rsp[0] = 0; // Reset error
|
||||
}*/
|
||||
}
|
||||
if (req)
|
||||
|
||||
if (res && req)
|
||||
_sdmmc_update_dma(sdmmc);
|
||||
}
|
||||
|
||||
@@ -903,7 +934,22 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
||||
{
|
||||
if (req)
|
||||
{
|
||||
armDCacheFlush(req->buf, req->blksize * blkcnt);
|
||||
if(!req->is_write)
|
||||
{
|
||||
if(!sdmmc_memcpy_buf)
|
||||
{
|
||||
// Flush from phys
|
||||
armDCacheFlush(req->buf, req->blksize * blkcnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
void* dma_addr = &_current_accessor->parent->dmaBuffers[sdmmc->last_dma_idx].device_addr_buffer[0];
|
||||
// Flush from phys
|
||||
armDCacheFlush(dma_addr, req->blksize * blkcnt);
|
||||
// Copy to buffer
|
||||
memcpy(req->buf, dma_addr, req->blksize * blkcnt);
|
||||
}
|
||||
}
|
||||
|
||||
if (blkcnt_out)
|
||||
*blkcnt_out = blkcnt;
|
||||
@@ -948,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.
|
||||
@@ -962,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;
|
||||
@@ -1008,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);
|
||||
@@ -1040,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);
|
||||
@@ -1095,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);
|
||||
|
||||
@@ -83,7 +83,7 @@ typedef struct _sdmmc_t
|
||||
int venclkctl_set;
|
||||
u32 venclkctl_tap;
|
||||
u32 expected_rsp_type;
|
||||
u64 dma_addr_fs;
|
||||
u64 last_dma_idx;
|
||||
u64 dma_addr_next;
|
||||
u32 rsp[4];
|
||||
u32 rsp3;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "emummc.h"
|
||||
#include "emummc_ctx.h"
|
||||
|
||||
static bool sdmmc_first_init = false;
|
||||
static bool storageMMCinitialized = false;
|
||||
static bool storageSDinitialized = false;
|
||||
|
||||
@@ -68,39 +69,32 @@ static void _sdmmc_ensure_device_attached(void)
|
||||
|
||||
static void _sdmmc_ensure_initialized(void)
|
||||
{
|
||||
// The boot sysmodule will eventually kill power to SD. Detect this, and reinitialize when it happens.
|
||||
static bool init_done = false;
|
||||
if (!init_done)
|
||||
|
||||
// First Initial init
|
||||
if (!sdmmc_first_init)
|
||||
{
|
||||
if (gpio_read(GPIO_PORT_E, GPIO_PIN_4) == 0)
|
||||
sdmmc_initialize();
|
||||
sdmmc_first_init = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The boot sysmodule will eventually kill power to SD. Detect this, and reinitialize when it happens.
|
||||
if (!init_done)
|
||||
{
|
||||
sdmmc_finalize();
|
||||
sdmmc_initialize();
|
||||
init_done = true;
|
||||
if (gpio_read(GPIO_PORT_E, GPIO_PIN_4) == 0)
|
||||
{
|
||||
sdmmc_finalize();
|
||||
sdmmc_initialize();
|
||||
init_done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -108,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);
|
||||
@@ -121,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];
|
||||
@@ -128,40 +136,36 @@ static void _file_based_emmc_initialize(void)
|
||||
memset(&f_emu, 0, sizeof(file_based_ctxt));
|
||||
|
||||
memcpy(path, (void *)emuMMC_ctx.storagePath, sizeof(emuMMC_ctx.storagePath));
|
||||
strcat(path, "/eMMC");
|
||||
strcat(path, "/eMMC/");
|
||||
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;
|
||||
@@ -188,23 +192,33 @@ bool sdmmc_initialize(void)
|
||||
|
||||
if (!storageSDinitialized)
|
||||
{
|
||||
if (sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, SDMMC_1, SDMMC_BUS_WIDTH_4, 11))
|
||||
int retries = 5;
|
||||
while (retries)
|
||||
{
|
||||
storageSDinitialized = true;
|
||||
|
||||
// File based emummc.
|
||||
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_File) && !fat_mounted)
|
||||
if (sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, SDMMC_1, SDMMC_BUS_WIDTH_4, 11))
|
||||
{
|
||||
f_emu.sd_fs = (FATFS *)malloc(sizeof(FATFS));
|
||||
if (f_mount(f_emu.sd_fs, "", 1) != FR_OK)
|
||||
fatal_abort(Fatal_InitSD);
|
||||
else
|
||||
fat_mounted = true;
|
||||
storageSDinitialized = true;
|
||||
|
||||
_file_based_emmc_initialize();
|
||||
// File based emummc.
|
||||
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_File) && !fat_mounted)
|
||||
{
|
||||
f_emu.sd_fs = (FATFS *)malloc(sizeof(FATFS));
|
||||
if (f_mount(f_emu.sd_fs, "", 1) != FR_OK)
|
||||
fatal_abort(Fatal_InitSD);
|
||||
else
|
||||
fat_mounted = true;
|
||||
|
||||
_file_based_emmc_initialize();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
retries--;
|
||||
msleep(100);
|
||||
}
|
||||
else
|
||||
|
||||
if (!storageSDinitialized)
|
||||
{
|
||||
fatal_abort(Fatal_InitSD);
|
||||
}
|
||||
@@ -213,38 +227,6 @@ bool sdmmc_initialize(void)
|
||||
return storageMMCinitialized && storageSDinitialized;
|
||||
}
|
||||
|
||||
// FS DMA calculations.
|
||||
intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors)
|
||||
{
|
||||
int dma_buf_idx = 0;
|
||||
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;
|
||||
|
||||
if (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer_size])
|
||||
{
|
||||
dma_buf_idx = FS_SDMMC_EMMC;
|
||||
}
|
||||
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_buf_idx = FS_SDMMC_SD;
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer;
|
||||
dma_buf_idx = FS_SDMMC_GC;
|
||||
}
|
||||
}
|
||||
|
||||
intptr_t admaaddr = (intptr_t)&_this->parent->dmaBuffers[dma_buf_idx].device_addr_buffer_masked[actual_buf_start - dma_buffer_start];
|
||||
|
||||
return admaaddr;
|
||||
}
|
||||
|
||||
sdmmc_accessor_t *sdmmc_accessor_get(int mmc_id)
|
||||
{
|
||||
sdmmc_accessor_t *_this;
|
||||
@@ -268,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()
|
||||
@@ -314,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;
|
||||
}
|
||||
|
||||
@@ -335,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.
|
||||
@@ -354,6 +376,8 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
|
||||
if (mmc_id == FS_SDMMC_EMMC || mmc_id == FS_SDMMC_SD)
|
||||
{
|
||||
mutex_lock_handler(mmc_id);
|
||||
// Assign FS accessor to the SDMMC driver
|
||||
_current_accessor = _this;
|
||||
// Make sure we're attached to the device address space.
|
||||
_sdmmc_ensure_device_attached();
|
||||
// Make sure we're still initialized if boot killed sd card power.
|
||||
@@ -362,8 +386,6 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
|
||||
|
||||
if (mmc_id == FS_SDMMC_EMMC)
|
||||
{
|
||||
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
|
||||
|
||||
// Call hekates driver.
|
||||
if (emummc_read_write_inner(buf, sector, num_sectors, false))
|
||||
{
|
||||
@@ -377,7 +399,17 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
|
||||
|
||||
if (mmc_id == FS_SDMMC_SD)
|
||||
{
|
||||
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
|
||||
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))
|
||||
@@ -410,8 +442,7 @@ uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_s
|
||||
if (mmc_id == FS_SDMMC_EMMC)
|
||||
{
|
||||
mutex_lock_handler(mmc_id);
|
||||
|
||||
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
|
||||
_current_accessor = _this;
|
||||
|
||||
// Call hekates driver.
|
||||
if (emummc_read_write_inner(buf, sector, num_sectors, true))
|
||||
@@ -427,9 +458,9 @@ uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_s
|
||||
if (mmc_id == FS_SDMMC_SD)
|
||||
{
|
||||
mutex_lock_handler(mmc_id);
|
||||
_current_accessor = _this;
|
||||
|
||||
sector += 0;
|
||||
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
|
||||
|
||||
// Call hekates driver.
|
||||
if (sdmmc_storage_write(&sd_storage, sector, num_sectors, buf))
|
||||
|
||||
@@ -50,8 +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);
|
||||
|
||||
intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors);
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -61,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
|
||||
|
||||
@@ -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"
|
||||
@@ -40,7 +42,7 @@ uintptr_t text_base;
|
||||
char inner_heap[INNER_HEAP_SIZE];
|
||||
size_t inner_heap_size = INNER_HEAP_SIZE;
|
||||
extern char _start;
|
||||
extern char __injected_size__;
|
||||
extern char __argdata__;
|
||||
|
||||
// Nintendo Path
|
||||
// TODO
|
||||
@@ -53,7 +55,7 @@ static char nintendo_path_contents_100[0x100] = "/Nintendo/Contents";
|
||||
static const fs_offsets_t *fs_offsets;
|
||||
|
||||
// Defined by linkerscript
|
||||
#define INJECTED_SIZE ((uintptr_t)&__injected_size__ - (uintptr_t)&_start)
|
||||
#define INJECTED_SIZE ((uintptr_t)&__argdata__ - (uintptr_t)&_start)
|
||||
#define INJECT_OFFSET(type, offset) (type)(text_base + INJECTED_SIZE + offset)
|
||||
|
||||
#define GENERATE_ADD(register, register_target, value) (0x91000000 | value << 10 | register << 5 | register_target)
|
||||
@@ -154,15 +156,14 @@ void write_nop(uintptr_t source)
|
||||
smcWriteAddress32((void *)source, GENERATE_NOP());
|
||||
}
|
||||
|
||||
void write_adrp_add(int reg, uintptr_t pc, intptr_t destination)
|
||||
void write_adrp_add(int reg, uintptr_t pc, uintptr_t add_rel_offset, intptr_t destination)
|
||||
{
|
||||
uintptr_t add_opcode_location = pc + sizeof(uint32_t);
|
||||
uintptr_t add_opcode_location = pc + add_rel_offset;
|
||||
|
||||
intptr_t offset = (destination & 0xFFFFF000) - (pc & 0xFFFFF000);
|
||||
uint32_t opcode_adrp = GENERATE_ADRP(reg, offset);
|
||||
uint32_t opcode_add = GENERATE_ADD(reg, reg, (destination & 0x00000FFF));
|
||||
|
||||
// TODO: use 64 write?
|
||||
smcWriteAddress32((void *)pc, opcode_adrp);
|
||||
smcWriteAddress32((void *)add_opcode_location, opcode_add);
|
||||
}
|
||||
@@ -175,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.
|
||||
@@ -204,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
|
||||
@@ -268,7 +267,7 @@ void setup_nintendo_paths(void)
|
||||
{
|
||||
intptr_t nintendo_path_location = (intptr_t)&nintendo_path;
|
||||
uintptr_t fs_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[i].adrp_offset);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[i].opcode_reg, fs_adrp_opcode_location, nintendo_path_location);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[i].opcode_reg, fs_adrp_opcode_location, fs_offsets->nintendo_paths[i].add_rel_offset, nintendo_path_location);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -281,8 +280,8 @@ void setup_nintendo_paths(void)
|
||||
intptr_t album_path_location = nintendo_album_path_location + path_len - 6; // "/Album"
|
||||
uintptr_t fs_n_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[0].adrp_offset);
|
||||
uintptr_t fs_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[1].adrp_offset);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[0].opcode_reg, fs_n_adrp_opcode_location, nintendo_album_path_location);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[1].opcode_reg, fs_adrp_opcode_location, album_path_location);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[0].opcode_reg, fs_n_adrp_opcode_location, fs_offsets->nintendo_paths[0].add_rel_offset, nintendo_album_path_location);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[1].opcode_reg, fs_adrp_opcode_location, fs_offsets->nintendo_paths[1].add_rel_offset, album_path_location);
|
||||
}
|
||||
// Do contents path
|
||||
{
|
||||
@@ -291,8 +290,8 @@ void setup_nintendo_paths(void)
|
||||
intptr_t contents_path_location = nintendo_contents_path_location + path_len - 9; // "/Contents"
|
||||
uintptr_t fs_n_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[2].adrp_offset);
|
||||
uintptr_t fs_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[3].adrp_offset);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[2].opcode_reg, fs_n_adrp_opcode_location, nintendo_contents_path_location);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[3].opcode_reg, fs_adrp_opcode_location, contents_path_location);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[2].opcode_reg, fs_n_adrp_opcode_location, fs_offsets->nintendo_paths[2].add_rel_offset, nintendo_contents_path_location);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[3].opcode_reg, fs_adrp_opcode_location, fs_offsets->nintendo_paths[3].add_rel_offset, contents_path_location);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -318,5 +317,6 @@ void __init()
|
||||
write_nops();
|
||||
setup_nintendo_paths();
|
||||
|
||||
sdmmc_initialize();
|
||||
clock_enable_i2c5();
|
||||
i2c_init();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -78,7 +78,7 @@ startup:
|
||||
|
||||
MOV W0, #0xFFFF8001
|
||||
ADR X1, __data_start
|
||||
ADR X2, __end__
|
||||
ADR X2, __argdata__
|
||||
SUB X2, X2, X1
|
||||
MOV X3, #3
|
||||
SVC 0x73
|
||||
@@ -127,5 +127,5 @@ bss_loop:
|
||||
MOV X30, X27
|
||||
|
||||
# FS main
|
||||
ADR X16, __injected_size__
|
||||
ADRP X16, __argdata__
|
||||
BR X16
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
ParseClipboard()
|
||||
|
||||
Func FormatLineData($sLineData)
|
||||
Func FormatLineData($sLineData, $sLineDataAdd)
|
||||
Local $lineData = StringReplace($sLineData, @TAB, " ")
|
||||
Local $lineDataADRP, $lineDataADD
|
||||
Local $isADRP = false
|
||||
$lineData = StringReplace($lineData, "Up o sub_71000" , "0x")
|
||||
$isADRP = StringInStr($lineData, "ADRP")
|
||||
@@ -13,24 +14,39 @@ Func FormatLineData($sLineData)
|
||||
|
||||
$lineDataAddr = StringReplace($lineDataAddr, "0x" , "")
|
||||
$lineDataAddition = StringReplace($lineDataAddition, "0x" , "")
|
||||
$addrADRP = Dec($lineDataAddr) + Dec($lineDataAddition)
|
||||
|
||||
If $isADRP Then
|
||||
$lineData = "0x" & Hex(Dec($lineDataAddr) + Dec($lineDataAddition))
|
||||
Else
|
||||
Return ""
|
||||
EndIf
|
||||
$lineDataADRP = "0x" & Hex($addrADRP)
|
||||
|
||||
Return "{.opcode_reg = " & $targetRegister & ", .adrp_offset = " & $lineData & "}, \" & @LF
|
||||
Local $lineDataADD = StringReplace($sLineDataAdd, @TAB, " ")
|
||||
Local $isADD = false
|
||||
$lineDataADD = StringReplace($lineDataADD, "Up o sub_71000" , "0x")
|
||||
$isADD = StringInStr($lineData, "ADD")
|
||||
|
||||
$lineDataADD = StringSplit($lineDataADD, " ")[1]
|
||||
$lineDataAddAddr = StringSplit($lineDataADD, "+")[1]
|
||||
$lineDataAddAddition = StringSplit($lineDataADD, "+")[2]
|
||||
|
||||
$lineDataAddAddr = StringReplace($lineDataAddAddr, "0x" , "")
|
||||
$lineDataAddAddition = StringReplace($lineDataAddAddition, "0x" , "")
|
||||
$addrADD = Dec($lineDataAddAddr) + Dec($lineDataAddAddition)
|
||||
$addrADD = $addrADD - $addrADRP
|
||||
$lineDataADD = "0x" & Hex($addrADD)
|
||||
|
||||
Return @TAB & "{.opcode_reg = " & $targetRegister & ", .adrp_offset = " & $lineDataADRP & ", .add_rel_offset = " & $lineDataADD & "}, \" & @LF
|
||||
EndFunc
|
||||
|
||||
Func ParseClipboard()
|
||||
Local $sData = ClipGet()
|
||||
Local $oData = ""
|
||||
Local $sLineData = StringSplit(StringReplace($sData, @CRLF, @LF), @LF)
|
||||
For $i = 2 to UBound($sLineData) - 2
|
||||
Local $lineData = FormatLineData($sLineData[$i])
|
||||
For $i = 2 to UBound($sLineData) - 2 Step 2
|
||||
Local $lineData = FormatLineData($sLineData[$i], $sLineData[$i+1])
|
||||
;ConsoleWrite($lineData)
|
||||
$oData = $oData & $lineData
|
||||
Next
|
||||
|
||||
$oData = "{ \" & @LF & $oData & @TAB & "{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \" & @LF & "}" & @LF
|
||||
;ConsoleWrite($oData)
|
||||
ClipPut($oData)
|
||||
EndFunc
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -34,13 +34,13 @@ unsigned int exosphere_load_config(void) {
|
||||
generic_panic();
|
||||
}
|
||||
g_has_loaded_config = true;
|
||||
|
||||
|
||||
const unsigned int magic = MAILBOX_EXOSPHERE_CONFIG.magic;
|
||||
|
||||
|
||||
if (magic == MAGIC_EXOSPHERE_CONFIG) {
|
||||
g_exosphere_cfg = MAILBOX_EXOSPHERE_CONFIG;
|
||||
}
|
||||
|
||||
|
||||
return g_exosphere_cfg.target_firmware;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ unsigned int exosphere_get_target_firmware(void) {
|
||||
if (!g_has_loaded_config) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
|
||||
return g_exosphere_cfg.target_firmware;
|
||||
}
|
||||
|
||||
@@ -56,15 +56,15 @@ unsigned int exosphere_should_perform_620_keygen(void) {
|
||||
if (!g_has_loaded_config) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
return g_exosphere_cfg.target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_620 && EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_PERFORM_620_KEYGEN);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int exosphere_should_override_debugmode_priv(void) {
|
||||
if (!g_has_loaded_config) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
|
||||
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ unsigned int exosphere_should_override_debugmode_user(void) {
|
||||
if (!g_has_loaded_config) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
|
||||
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_IS_DEBUGMODE_USER);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ unsigned int exosphere_should_disable_usermode_exception_handlers(void) {
|
||||
if (!g_has_loaded_config) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
|
||||
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS);
|
||||
}
|
||||
|
||||
|
||||
@@ -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/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef EXOSPHERE_EXOSPHERE_CONFIG_H
|
||||
#define EXOSPHERE_EXOSPHERE_CONFIG_H
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
/* Exosphere config in DRAM shares physical/virtual mapping. */
|
||||
#define MAILBOX_EXOSPHERE_CONFIG_PHYS MAILBOX_EXOSPHERE_CONFIG
|
||||
|
||||
#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u)
|
||||
#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN_DEPRECATED (1 << 0u)
|
||||
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
|
||||
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
|
||||
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -42,6 +42,8 @@ static const uint8_t mkey_vectors_dev[MASTERKEY_REVISION_MAX][0x10] =
|
||||
{0x78, 0xD5, 0xF1, 0x20, 0x3D, 0x16, 0xE9, 0x30, 0x32, 0x27, 0x34, 0x6F, 0xCF, 0xE0, 0x27, 0xDC}, /* Master key 04 encrypted with Master key 05. */
|
||||
{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. */
|
||||
@@ -55,6 +57,8 @@ static const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] =
|
||||
{0xEB, 0xF5, 0x6F, 0x83, 0x61, 0x9E, 0xF8, 0xFA, 0xE0, 0x87, 0xD7, 0xA1, 0x4E, 0x25, 0x36, 0xEE}, /* Master key 04 encrypted with Master key 05. */
|
||||
{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) {
|
||||
@@ -83,7 +87,7 @@ void mkey_detect_revision(void) {
|
||||
if (g_determined_mkey_revision) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
|
||||
for (unsigned int rev = 0; rev < MASTERKEY_REVISION_MAX; rev++) {
|
||||
if (check_mkey_revision(rev, configitem_is_retail())) {
|
||||
g_determined_mkey_revision = true;
|
||||
@@ -91,7 +95,7 @@ void mkey_detect_revision(void) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* We must have determined the master key, or we're not running on a Switch. */
|
||||
if (!g_determined_mkey_revision) {
|
||||
/* Panic in bright red. */
|
||||
@@ -125,7 +129,6 @@ unsigned int mkey_get_keyslot(unsigned int revision) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void set_old_devkey(unsigned int revision, const uint8_t *key) {
|
||||
if (revision < MASTERKEY_REVISION_400_410 || MASTERKEY_REVISION_MAX <= revision) {
|
||||
generic_panic();
|
||||
@@ -135,23 +138,17 @@ void set_old_devkey(unsigned int revision, const uint8_t *key) {
|
||||
}
|
||||
|
||||
unsigned int devkey_get_keyslot(unsigned int revision) {
|
||||
if (!g_determined_mkey_revision || revision >= MASTERKEY_REVISION_MAX) {
|
||||
if (!g_determined_mkey_revision || revision > g_mkey_revision) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
if (revision > g_mkey_revision) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
if (revision >= 1) {
|
||||
if (revision == MASTERKEY_REVISION_MAX) {
|
||||
return KEYSLOT_SWITCH_DEVICEKEY;
|
||||
} else {
|
||||
/* Load into a temp keyslot. */
|
||||
set_aes_keyslot(KEYSLOT_SWITCH_TEMPKEY, g_old_devicekeys[revision - MASTERKEY_REVISION_400_410], 0x10);
|
||||
return KEYSLOT_SWITCH_TEMPKEY;
|
||||
}
|
||||
} else {
|
||||
if (revision < MASTERKEY_REVISION_400_410) {
|
||||
return KEYSLOT_SWITCH_4XOLDDEVICEKEY;
|
||||
} else if (revision < g_mkey_revision) {
|
||||
/* Load into a temp keyslot. */
|
||||
set_aes_keyslot(KEYSLOT_SWITCH_TEMPKEY, g_old_devicekeys[revision - MASTERKEY_REVISION_400_410], 0x10);
|
||||
return KEYSLOT_SWITCH_TEMPKEY;
|
||||
} else {
|
||||
return KEYSLOT_SWITCH_DEVICEKEY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
* 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_MASTERKEY_H
|
||||
#define EXOSPHERE_MASTERKEY_H
|
||||
|
||||
/* This is glue code to enable master key support across versions. */
|
||||
|
||||
/* TODO: Update to 0x9 on release of new master key. */
|
||||
#define MASTERKEY_REVISION_MAX 0x8
|
||||
/* 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,7 +29,9 @@
|
||||
#define MASTERKEY_REVISION_500_510 0x04
|
||||
#define MASTERKEY_REVISION_600_610 0x05
|
||||
#define MASTERKEY_REVISION_620 0x06
|
||||
#define MASTERKEY_REVISION_700_CURRENT 0x07
|
||||
#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)
|
||||
|
||||
|
||||
@@ -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 "memory_map.h"
|
||||
@@ -28,7 +28,7 @@ typedef struct {
|
||||
static saved_carveout_info_t g_saved_carveouts[2] = {
|
||||
{0x80060000ull, KERNEL_CARVEOUT_SIZE_MAX},
|
||||
{0x00000000ull, 0x00000000ull}
|
||||
};
|
||||
};
|
||||
|
||||
volatile security_carveout_t *get_carveout_by_id(unsigned int carveout) {
|
||||
if (CARVEOUT_ID_MIN <= carveout && carveout <= CARVEOUT_ID_MAX) {
|
||||
@@ -130,7 +130,7 @@ void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint6
|
||||
if (carveout_id != 4 && carveout_id != 5) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
|
||||
g_saved_carveouts[carveout_id-4].address = address;
|
||||
g_saved_carveouts[carveout_id-4].size = size;
|
||||
|
||||
@@ -140,8 +140,12 @@ void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint6
|
||||
carveout->size_big_pages = (uint32_t)(size >> 17);
|
||||
carveout->client_access_0 = (BIT(CSR_PTCR) | BIT(CSR_DISPLAY0A) | BIT(CSR_DISPLAY0AB) | BIT(CSR_DISPLAY0B) | BIT(CSR_DISPLAY0BB) | BIT(CSR_DISPLAY0C) | BIT(CSR_DISPLAY0CB) | BIT(CSR_AFIR) | BIT(CSR_DISPLAYHC) | BIT(CSR_DISPLAYHCB) | BIT(CSR_HDAR) | BIT(CSR_HOST1XDMAR) | BIT(CSR_HOST1XR) | BIT(CSR_NVENCSRD) | BIT(CSR_PPCSAHBDMAR) | BIT(CSR_PPCSAHBSLVR));
|
||||
carveout->client_access_1 = (BIT(CSR_MPCORER) | BIT(CSW_NVENCSWR) | BIT(CSW_AFIW) | BIT(CSW_HDAW) | BIT(CSW_HOST1XW) | BIT(CSW_MPCOREW) | BIT(CSW_PPCSAHBDMAW) | BIT(CSW_PPCSAHBSLVW));
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_800) {
|
||||
carveout->client_access_2 = (BIT(CSR_XUSB_HOSTR) | BIT(CSW_XUSB_HOSTW) | BIT(CSR_XUSB_DEVR) | BIT(CSW_XUSB_DEVW));
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_810) {
|
||||
carveout->client_access_2 = (BIT(CSR_XUSB_HOSTR) | BIT(CSW_XUSB_HOSTW) | BIT(CSR_XUSB_DEVR) | BIT(CSW_XUSB_DEVW));
|
||||
carveout->client_access_3 = (BIT(CSR_SDMMCRA) | BIT(CSR_SDMMCRAA) | BIT(CSR_SDMMCRAB) | BIT(CSW_SDMMCWA) | BIT(CSW_SDMMCWAA) | BIT(CSW_SDMMCWAB) | BIT(CSR_VICSRD) | BIT(CSW_VICSWR) | BIT(CSR_DISPLAYD) | BIT(CSR_APER) | BIT(CSW_APEW) | BIT(CSR_NVJPGSRD) | BIT(CSW_NVJPGSWR));
|
||||
carveout->client_access_4 = (BIT(CSR_SESRD) | BIT(CSW_SESWR));
|
||||
} else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_800) {
|
||||
carveout->client_access_2 = (BIT(CSR_XUSB_HOSTR) | BIT(CSW_XUSB_HOSTW) | BIT(CSR_XUSB_DEVR) | BIT(CSW_XUSB_DEVW));
|
||||
carveout->client_access_3 = (BIT(CSR_SDMMCRA) | BIT(CSR_SDMMCRAA) | BIT(CSR_SDMMCRAB) | BIT(CSW_SDMMCWA) | BIT(CSW_SDMMCWAA) | BIT(CSW_SDMMCWAB) | BIT(CSR_VICSRD) | BIT(CSW_VICSWR) | BIT(CSR_DISPLAYD) | BIT(CSR_NVDECSRD) | BIT(CSW_NVDECSWR) | BIT(CSR_APER) | BIT(CSW_APEW) | BIT(CSR_NVJPGSRD) | BIT(CSW_NVJPGSWR));
|
||||
carveout->client_access_4 = (BIT(CSR_SESRD) | BIT(CSW_SESWR) | BIT(CSR_TSECSRDB) | BIT(CSW_TSECSWRB));
|
||||
} else {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
@@ -43,6 +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. */
|
||||
{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] = {
|
||||
@@ -51,6 +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. */
|
||||
{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] = {
|
||||
@@ -58,45 +62,29 @@ static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS
|
||||
{0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8}, /* 5.x New Device Keygen Source. */
|
||||
{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}, /* 6.2.0 New Device Keygen Source. */
|
||||
};
|
||||
|
||||
static const uint8_t new_master_kek_sources[MASTERKEY_REVISION_700_CURRENT - MASTERKEY_REVISION_600_610][0x10] = {
|
||||
{0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, /* 6.2.0 Master Kek Source. */
|
||||
{0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, /* 7.0.0 Master Kek Source. */
|
||||
};
|
||||
|
||||
static const uint8_t keyblob_key_seed_00[0x10] = {
|
||||
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3
|
||||
};
|
||||
|
||||
static const uint8_t devicekey_seed[0x10] = {
|
||||
0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78
|
||||
};
|
||||
|
||||
static const uint8_t devicekey_4x_seed[0x10] = {
|
||||
0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28
|
||||
};
|
||||
|
||||
static const uint8_t masterkey_seed[0x10] = {
|
||||
0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C
|
||||
};
|
||||
|
||||
static const uint8_t devicekek_4x_seed[0x10] = {
|
||||
0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66
|
||||
{0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE}, /* 7.0.0 New Device Keygen Source. */
|
||||
{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) {
|
||||
uint8_t work_buffer[0x10];
|
||||
bool is_retail = configitem_is_retail();
|
||||
for (unsigned int revision = 0; revision < MASTERKEY_NUM_NEW_DEVICE_KEYS; revision++) {
|
||||
const unsigned int relative_revision = revision + MASTERKEY_REVISION_400_410;
|
||||
|
||||
se_aes_ecb_decrypt_block(keygen_keyslot, work_buffer, 0x10, new_device_key_sources[revision], 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, mkey_get_keyslot(0), is_retail ? new_device_keygen_sources[revision] : new_device_keygen_sources_dev[revision], 0x10);
|
||||
if (revision < MASTERKEY_NUM_NEW_DEVICE_KEYS - 1) {
|
||||
se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10, work_buffer, 0x10);
|
||||
set_old_devkey(revision + MASTERKEY_REVISION_400_410, work_buffer);
|
||||
if (relative_revision > mkey_get_revision()) {
|
||||
break;
|
||||
} else if (relative_revision == mkey_get_revision()) {
|
||||
/* On 7.0.0, sept will have derived this key for us already. */
|
||||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_700) {
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_DEVICEKEY, KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10);
|
||||
}
|
||||
} else {
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_DEVICEKEY, KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10);
|
||||
se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10, work_buffer, 0x10);
|
||||
set_old_devkey(relative_revision, work_buffer);
|
||||
}
|
||||
}
|
||||
set_aes_keyslot_flags(KEYSLOT_SWITCH_DEVICEKEY, 0xFF);
|
||||
@@ -118,7 +106,8 @@ static void setup_se(void) {
|
||||
se->_0x0 &= 0xFFFEFFFF; /* Clear bit 16. */
|
||||
(void)(se->FLAGS_REG);
|
||||
__dsb_sy();
|
||||
|
||||
|
||||
/* NOTE: On 8.1.0+, Nintendo does not make keyslots 0-5 unreadable. */
|
||||
se->_0x4 = 0;
|
||||
se->AES_KEY_READ_DISABLE_REG = 0;
|
||||
se->RSA_KEY_READ_DISABLE_REG = 0;
|
||||
@@ -136,33 +125,6 @@ static void setup_se(void) {
|
||||
for (unsigned int i = 0; i < KEYSLOT_RSA_MAX; i++) {
|
||||
set_rsa_keyslot_flags(i, 0x41);
|
||||
}
|
||||
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_620 && exosphere_should_perform_620_keygen()) {
|
||||
unsigned int master_kek_source_ind;
|
||||
switch (exosphere_get_target_firmware()) {
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_620:
|
||||
master_kek_source_ind = MASTERKEY_REVISION_620 - MASTERKEY_REVISION_620;
|
||||
break;
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
||||
master_kek_source_ind = MASTERKEY_REVISION_700_CURRENT - MASTERKEY_REVISION_620;
|
||||
break;
|
||||
default:
|
||||
generic_panic();
|
||||
break;
|
||||
}
|
||||
/* Start by generating device keys. */
|
||||
se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_6XTSECKEY, work_buffer, 0x10, keyblob_key_seed_00, 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XOLDDEVICEKEY, KEYSLOT_SWITCH_6XSBK, work_buffer, 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XNEWCONSOLEKEYGENKEY, KEYSLOT_SWITCH_4XOLDDEVICEKEY, devicekey_4x_seed, 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XOLDDEVICEKEY, KEYSLOT_SWITCH_4XOLDDEVICEKEY, devicekey_seed, 0x10);
|
||||
|
||||
/* Next, generate the master kek, and from there master key/device kek. We use different keyslots than Nintendo, here. */
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_6XTSECROOTKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, new_master_kek_sources[master_kek_source_ind], 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_MASTERKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, masterkey_seed, 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, devicekek_4x_seed, 0x10);
|
||||
clear_aes_keyslot(KEYSLOT_SWITCH_6XTSECROOTKEY);
|
||||
}
|
||||
|
||||
/* Detect Master Key revision. */
|
||||
mkey_detect_revision();
|
||||
@@ -181,6 +143,8 @@ static void setup_se(void) {
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_620:
|
||||
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;
|
||||
}
|
||||
@@ -198,7 +162,7 @@ static void setup_se(void) {
|
||||
set_aes_keyslot_flags(KEYSLOT_SWITCH_SESSIONKEY, 0xFF);
|
||||
|
||||
/* Generate test vector for our keys. */
|
||||
se_generate_stored_vector();
|
||||
se_generate_stored_vector();
|
||||
}
|
||||
|
||||
static void setup_boot_config(void) {
|
||||
@@ -287,7 +251,7 @@ static bool validate_package2_metadata(package2_meta_t *metadata) {
|
||||
if (metadata->magic != MAGIC_PK21) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Package2 size, version number is stored XORed in header CTR. */
|
||||
/* Nintendo, what the fuck? */
|
||||
@@ -370,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_700_CURRENT) {
|
||||
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_900_CURRENT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -495,21 +459,23 @@ static void copy_warmboot_bin_to_dram() {
|
||||
break;
|
||||
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;
|
||||
}
|
||||
uint8_t *warmboot_dst = (uint8_t *)0x8000D000;
|
||||
const size_t warmboot_size = 0x2000;
|
||||
|
||||
|
||||
/* Flush cache, to ensure warmboot is where we need it to be. */
|
||||
flush_dcache_range(warmboot_src, warmboot_src + warmboot_size);
|
||||
__dsb_sy();
|
||||
|
||||
|
||||
/* Copy warmboot. */
|
||||
for (size_t i = 0; i < warmboot_size; i += sizeof(uint32_t)) {
|
||||
write32le(warmboot_dst, i, read32le(warmboot_src, i));
|
||||
}
|
||||
|
||||
|
||||
/* Flush cache, to ensure warmboot is where we need it to be. */
|
||||
flush_dcache_range(warmboot_dst, warmboot_dst + warmboot_size);
|
||||
__dsb_sy();
|
||||
@@ -544,12 +510,12 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
|
||||
/* Setup the Security Engine. */
|
||||
setup_se();
|
||||
|
||||
|
||||
/* Perform initial PMC register writes, if relevant. */
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
MAKE_REG32(PMC_BASE + 0x054) = 0x8000D000;
|
||||
MAKE_REG32(PMC_BASE + 0x0A0) &= 0xFFF3FFFF;
|
||||
MAKE_REG32(PMC_BASE + 0x818) &= 0xFFFFFFFE;
|
||||
MAKE_REG32(PMC_BASE + 0x054) = 0x8000D000;
|
||||
MAKE_REG32(PMC_BASE + 0x0A0) &= 0xFFF3FFFF;
|
||||
MAKE_REG32(PMC_BASE + 0x818) &= 0xFFFFFFFE;
|
||||
MAKE_REG32(PMC_BASE + 0x334) |= 0x10;
|
||||
switch (exosphere_get_target_firmware()) {
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_400:
|
||||
@@ -568,6 +534,12 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
||||
MAKE_REG32(PMC_BASE + 0x360) = 0x129;
|
||||
break;
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||
MAKE_REG32(PMC_BASE + 0x360) = 0x14A;
|
||||
break;
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_900:
|
||||
MAKE_REG32(PMC_BASE + 0x360) = 0x16B;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,7 +557,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
|
||||
/* memclear the initial copy of Exosphere running in IRAM (relocated to TZRAM by earlier code). */
|
||||
/* memset((void *)reloc_list->reloc_base, 0, reloc_list->loaded_bin_size); */
|
||||
|
||||
|
||||
/* Let NX Bootloader know that we're running. */
|
||||
MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE(exosphere_get_target_firmware()) = 1;
|
||||
|
||||
@@ -597,7 +569,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
|
||||
/* Load Boot Config into global. */
|
||||
setup_boot_config();
|
||||
|
||||
|
||||
/* Set sysctr0 registers based on bootconfig. */
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
uint64_t sysctr0_val = bootconfig_get_value_for_sysctr0();
|
||||
@@ -620,7 +592,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
|
||||
/* Make PMC (2.x+), MC (4.x+) registers secure-only */
|
||||
secure_additional_devices();
|
||||
|
||||
|
||||
/* Remove the identity mapping for iRAM-C+D & TZRAM */
|
||||
/* For our crt0 to work, this doesn't actually unmap TZRAM */
|
||||
identity_unmap_iram_cd_tzram();
|
||||
@@ -630,7 +602,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
flush_dcache_range((uint8_t *)NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS, (uint8_t *)NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS + sizeof(header));
|
||||
memcpy(&header, NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS, sizeof(header));
|
||||
flush_dcache_range((uint8_t *)&header, (uint8_t *)&header + sizeof(header));
|
||||
|
||||
|
||||
/* Perform signature checks. */
|
||||
/* Special exosphere patching enable: All-zeroes signature + decrypted header implies unsigned and decrypted package2. */
|
||||
if (header.signature[0] == 0 && memcmp(header.signature, header.signature + 1, sizeof(header.signature) - 1) == 0 && header.metadata.magic == MAGIC_PK21) {
|
||||
@@ -641,7 +613,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
|
||||
/* Decrypt header, get key revision required. */
|
||||
uint32_t package2_mkey_rev = decrypt_and_validate_header(&header);
|
||||
|
||||
|
||||
/* Copy hash, if necessary. */
|
||||
if (bootconfig_is_recovery_boot()) {
|
||||
bootconfig_set_package2_hash_for_recovery(NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS, get_package2_size(&header.metadata));
|
||||
@@ -649,7 +621,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
|
||||
/* Load Package2 Sections. */
|
||||
load_package2_sections(&header.metadata, package2_mkey_rev);
|
||||
|
||||
|
||||
/* Clean up cache. */
|
||||
flush_dcache_all();
|
||||
invalidate_icache_all(); /* non-broadcasting */
|
||||
@@ -660,7 +632,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
/* Remove the DRAM identity mapping. */
|
||||
if (0) {
|
||||
identity_unmap_dram();
|
||||
}
|
||||
}
|
||||
|
||||
/* Synchronize with NX BOOTLOADER. */
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
|
||||
@@ -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/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef EXOSPHERE_PACKAGE2_H
|
||||
#define EXOSPHERE_PACKAGE2_H
|
||||
|
||||
@@ -70,7 +70,9 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(unsigned int targetfw) {
|
||||
#define PACKAGE2_MAXVER_500_510 0x7
|
||||
#define PACKAGE2_MAXVER_600_610 0x8
|
||||
#define PACKAGE2_MAXVER_620 0x9
|
||||
#define PACKAGE2_MAXVER_700_CURRENT 0xA
|
||||
#define PACKAGE2_MAXVER_700_800 0xA
|
||||
#define PACKAGE2_MAXVER_810 0xB
|
||||
#define PACKAGE2_MAXVER_900_CURRENT 0xC
|
||||
|
||||
#define PACKAGE2_MINVER_100 0x3
|
||||
#define PACKAGE2_MINVER_200 0x4
|
||||
@@ -80,7 +82,9 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(unsigned int targetfw) {
|
||||
#define PACKAGE2_MINVER_500_510 0x8
|
||||
#define PACKAGE2_MINVER_600_610 0x9
|
||||
#define PACKAGE2_MINVER_620 0xA
|
||||
#define PACKAGE2_MINVER_700_CURRENT 0xB
|
||||
#define PACKAGE2_MINVER_700_800 0xB
|
||||
#define PACKAGE2_MINVER_810 0xC
|
||||
#define PACKAGE2_MINVER_900_CURRENT 0xD
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
|
||||
214
exosphere/src/pinmux.h
Normal file
214
exosphere/src/pinmux.h
Normal 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
|
||||
@@ -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();
|
||||
|
||||
@@ -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 <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -185,6 +185,8 @@ void set_version_specific_smcs(void) {
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_620:
|
||||
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;
|
||||
@@ -256,7 +258,7 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
||||
unsigned char smc_id, call_range;
|
||||
unsigned int result;
|
||||
unsigned int (*smc_handler)(smc_args_t *args);
|
||||
|
||||
|
||||
/* Validate top-level handler. */
|
||||
if (handler_id >= SMC_HANDLER_COUNT) {
|
||||
generic_panic();
|
||||
@@ -288,17 +290,17 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
||||
if ((smc_handler = g_smc_tables[handler_id].handlers[smc_id].handler) == NULL) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
|
||||
bool is_aes_kek = handler_id == SMC_HANDLER_USER && args->X[0] == 0xC3000007;
|
||||
|
||||
#if DEBUG_LOG_SMCS
|
||||
uint64_t num;
|
||||
#if DEBUG_LOG_SMCS
|
||||
uint64_t num;
|
||||
if (handler_id == SMC_HANDLER_USER) {
|
||||
num = atomic_fetch_add(&num_smcs_called, 1);
|
||||
*(volatile smc_args_t *)(get_iram_address_for_debug() + 0x100 + ((0x80 * num) & 0x3FFF)) = *args;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Call function. */
|
||||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_800 ||
|
||||
(g_smc_tables[handler_id].handlers[smc_id].blacklist_mask & g_smc_blacklist_mask) == 0) {
|
||||
@@ -307,15 +309,15 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
||||
/* Call not allowed due to current boot conditions. */
|
||||
args->X[0] = 6;
|
||||
}
|
||||
|
||||
#if DEBUG_LOG_SMCS
|
||||
|
||||
#if DEBUG_LOG_SMCS
|
||||
if (handler_id == SMC_HANDLER_USER) {
|
||||
*(volatile smc_args_t *)(get_iram_address_for_debug() + 0x100 + ((0x80 * num + 0x40) & 0x3FFF)) = *args;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if DEBUG_PANIC_ON_FAILURE
|
||||
if (args->X[0] && (!is_aes_kek || args->X[3] <= ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG))
|
||||
if (args->X[0] && (!is_aes_kek || args->X[3] <= ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG))
|
||||
{
|
||||
MAKE_REG32(get_iram_address_for_debug() + 0x4FF0) = handler_id;
|
||||
MAKE_REG32(get_iram_address_for_debug() + 0x4FF4) = smc_id;
|
||||
@@ -695,14 +697,14 @@ uint32_t smc_configure_carveout(smc_args_t *args) {
|
||||
if (size > KERNEL_CARVEOUT_SIZE_MAX) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
/* Ensure validity of carveout index. */
|
||||
if (carveout_id > 1) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Configuration is one-shot, and cannot be done multiple times. */
|
||||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_300) {
|
||||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_300) {
|
||||
if (g_configured_carveouts[carveout_id]) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -52,6 +52,8 @@ static bool is_user_keyslot_valid(unsigned int keyslot) {
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_620:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_900:
|
||||
default:
|
||||
return keyslot <= 5;
|
||||
}
|
||||
@@ -165,7 +167,7 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
|
||||
bool is_personalized = (int)(packed_options & 1);
|
||||
|
||||
bool is_recovery_boot = configitem_is_recovery_boot();
|
||||
|
||||
|
||||
/* 5.0.0+ Bounds checking. */
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (is_personalized) {
|
||||
@@ -295,7 +297,7 @@ uint32_t crypt_aes_done_handler(void) {
|
||||
uint32_t user_crypt_aes(smc_args_t *args) {
|
||||
uint32_t keyslot = args->X[1] & 3;
|
||||
uint32_t mode = (args->X[1] >> 4) & 3;
|
||||
|
||||
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
|
||||
keyslot = args->X[1] & 7;
|
||||
}
|
||||
@@ -791,7 +793,7 @@ uint32_t user_encrypt_rsa_key_for_import(smc_args_t *args) {
|
||||
|
||||
if (usecase > CRYPTOUSECASE_RSAIMPORT) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
if (usecase == 0) {
|
||||
if (size < 0x31 || size > 0x240) {
|
||||
return 2;
|
||||
@@ -823,7 +825,7 @@ uint32_t user_encrypt_rsa_key_for_import(smc_args_t *args) {
|
||||
|
||||
if (secure_copy_to_user(&page_ref, user_address, user_data, size) == 0) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -854,7 +856,7 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
|
||||
|
||||
if (usecase > CRYPTOUSECASE_RSAIMPORT) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
if (usecase == 0) {
|
||||
if (size < 0x31 || size > 0x240) {
|
||||
return 2;
|
||||
@@ -881,7 +883,7 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
|
||||
case 0:
|
||||
if (secure_copy_to_user(&page_ref, user_address, user_data, size) == 0) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
case 1:
|
||||
exponent_id = 1;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
163
fusee/fusee-mtc/Makefile
Normal 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
170
fusee/fusee-mtc/linker.ld
Normal 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) }
|
||||
}
|
||||
7
fusee/fusee-mtc/linker.specs
Normal file
7
fusee/fusee-mtc/linker.specs
Normal 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
139
fusee/fusee-mtc/src/car.c
Normal 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
505
fusee/fusee-mtc/src/car.h
Normal 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
|
||||
1619
fusee/fusee-mtc/src/display/cfb_console.c
Normal file
1619
fusee/fusee-mtc/src/display/cfb_console.c
Normal file
File diff suppressed because it is too large
Load Diff
57
fusee/fusee-mtc/src/display/video_fb.h
Normal file
57
fusee/fusee-mtc/src/display/video_fb.h
Normal 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_ */
|
||||
6181
fusee/fusee-mtc/src/display/video_font_large.h
Normal file
6181
fusee/fusee-mtc/src/display/video_font_large.h
Normal file
File diff suppressed because it is too large
Load Diff
4630
fusee/fusee-mtc/src/display/video_font_small.h
Normal file
4630
fusee/fusee-mtc/src/display/video_font_small.h
Normal file
File diff suppressed because it is too large
Load Diff
1089
fusee/fusee-mtc/src/emc.h
Normal file
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
260
fusee/fusee-mtc/src/fuse.c
Normal 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
213
fusee/fusee-mtc/src/fuse.h
Normal 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
|
||||
86
fusee/fusee-mtc/src/init.c
Normal file
86
fusee/fusee-mtc/src/init.c
Normal 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);
|
||||
}
|
||||
127
fusee/fusee-mtc/src/lib/log.c
Normal file
127
fusee/fusee-mtc/src/lib/log.c
Normal 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);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user