Compare commits

..

2 Commits

Author SHA1 Message Date
Michael Scire
c7fb3f7203 lmem: Implement Slab^H^H^H^HUnitHeap 2019-12-11 04:04:27 -08:00
Michael Scire
04beea44b0 lmem: implement ExpHeap 2019-12-11 01:24:45 -08:00
1854 changed files with 11494 additions and 116485 deletions

View File

@@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: ReSwitched Discord
url: https://discordapp.com/invite/DThbZ7z
about: Please ask questions here, instead of making GitHub issues.

7
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@@ -0,0 +1,7 @@
---
name: Question
about: Please ask questions in the ReSwitched discord, instead of making issues.
---
We would like to use GitHub to keep track of problems/feature requests.
If you have a question, please join the ReSwitched discord for help.
- Discord link: https://discordapp.com/invite/DThbZ7z

1
.gitignore vendored
View File

@@ -64,7 +64,6 @@ dkms.conf
# Distribution files
*.tgz
*.zip
*.bz2
# IDA binaries
*.id0

View File

@@ -1,4 +1,4 @@
TOPTARGETS := all clean dist-no-debug dist
TOPTARGETS := all clean dist
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
AMSHASH := $(shell git rev-parse --short HEAD)
AMSREV := $(AMSBRANCH)-$(AMSHASH)
@@ -7,7 +7,7 @@ ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
AMSREV := $(AMSREV)-dirty
endif
COMPONENTS := fusee stratosphere mesosphere exosphere thermosphere troposphere libraries
COMPONENTS := fusee stratosphere exosphere thermosphere troposphere libraries
all: $(COMPONENTS)
@@ -20,16 +20,13 @@ exosphere: thermosphere
stratosphere: exosphere libraries
$(MAKE) -C stratosphere all
mesosphere: exosphere libraries
$(MAKE) -C mesosphere all
troposphere: stratosphere
$(MAKE) -C troposphere all
sept: exosphere
$(MAKE) -C sept all
fusee: exosphere mesosphere stratosphere sept
fusee: exosphere stratosphere sept
$(MAKE) -C $@ all
libraries:
@@ -39,7 +36,7 @@ clean:
$(MAKE) -C fusee clean
rm -rf out
dist-no-debug: all
dist: all
$(eval MAJORVER = $(shell grep 'define ATMOSPHERE_RELEASE_VERSION_MAJOR\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
| tr -s [:blank:] \
| cut -d' ' -f3))
@@ -58,12 +55,10 @@ dist-no-debug: all
mkdir atmosphere-$(AMSVER)/switch
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000002B
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000003C
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
mkdir -p atmosphere-$(AMSVER)/atmosphere/config_templates
mkdir -p atmosphere-$(AMSVER)/atmosphere/config
@@ -75,8 +70,6 @@ dist-no-debug: all
cp sept/sept-secondary/sept-secondary.bin atmosphere-$(AMSVER)/sept/sept-secondary.bin
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 sept/sept-secondary/sept-secondary_dev_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_dev_00.enc
cp sept/sept-secondary/sept-secondary_dev_01.enc atmosphere-$(AMSVER)/sept/sept-secondary_dev_01.enc
cp config_templates/BCT.ini atmosphere-$(AMSVER)/atmosphere/config/BCT.ini
cp config_templates/override_config.ini atmosphere-$(AMSVER)/atmosphere/config_templates/override_config.ini
cp config_templates/system_settings.ini atmosphere-$(AMSVER)/atmosphere/config_templates/system_settings.ini
@@ -84,12 +77,10 @@ dist-no-debug: all
cp -r config_templates/hbl_html atmosphere-$(AMSVER)/atmosphere/hbl_html
cp stratosphere/boot2/boot2.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008/exefs.nsp
cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D/exefs.nsp
cp stratosphere/erpt/erpt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000002B/exefs.nsp
cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/exefs.nsp
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034/exefs.nsp
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036/exefs.nsp
cp stratosphere/ro/ro.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/exefs.nsp
cp stratosphere/jpegdec/jpegdec.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000003C/exefs.nsp
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/flags
touch atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/flags/boot2.flag
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/flags
@@ -101,47 +92,5 @@ dist-no-debug: all
mv atmosphere-$(AMSVER).zip out/atmosphere-$(AMSVER).zip
cp fusee/fusee-primary/fusee-primary.bin out/fusee-primary.bin
dist: dist-no-debug
$(eval MAJORVER = $(shell grep 'define ATMOSPHERE_RELEASE_VERSION_MAJOR\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
| tr -s [:blank:] \
| cut -d' ' -f3))
$(eval MINORVER = $(shell grep 'define ATMOSPHERE_RELEASE_VERSION_MINOR\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
| tr -s [:blank:] \
| cut -d' ' -f3))
$(eval MICROVER = $(shell grep 'define ATMOSPHERE_RELEASE_VERSION_MICRO\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
| tr -s [:blank:] \
| cut -d' ' -f3))
$(eval AMSVER = $(MAJORVER).$(MINORVER).$(MICROVER)-$(AMSREV))
rm -rf atmosphere-$(AMSVER)-debug
mkdir atmosphere-$(AMSVER)-debug
cp fusee/fusee-primary/fusee-primary.elf atmosphere-$(AMSVER)-debug/fusee-primary.elf
cp fusee/fusee-mtc/fusee-mtc.elf atmosphere-$(AMSVER)-debug/fusee-mtc.elf
cp fusee/fusee-secondary/fusee-secondary.elf atmosphere-$(AMSVER)-debug/fusee-secondary.elf
cp sept/sept-primary/sept-primary.elf atmosphere-$(AMSVER)-debug/sept-primary.elf
cp sept/sept-secondary/sept-secondary.elf atmosphere-$(AMSVER)-debug/sept-secondary.elf
cp sept/sept-secondary/key_derivation/key_derivation.elf atmosphere-$(AMSVER)-debug/sept-secondary-key-derivation.elf
cp exosphere/exosphere.elf atmosphere-$(AMSVER)-debug/exosphere.elf
cp exosphere/lp0fw/lp0fw.elf atmosphere-$(AMSVER)-debug/lp0fw.elf
cp exosphere/sc7fw/sc7fw.elf atmosphere-$(AMSVER)-debug/sc7fw.elf
cp exosphere/rebootstub/rebootstub.elf atmosphere-$(AMSVER)-debug/rebootstub.elf
cp mesosphere/kernel_ldr/kernel_ldr.elf atmosphere-$(AMSVER)-debug/kernel_ldr.elf
cp stratosphere/ams_mitm/ams_mitm.elf atmosphere-$(AMSVER)-debug/ams_mitm.elf
cp stratosphere/boot/boot.elf atmosphere-$(AMSVER)-debug/boot.elf
cp stratosphere/boot2/boot2.elf atmosphere-$(AMSVER)-debug/boot2.elf
cp stratosphere/creport/creport.elf atmosphere-$(AMSVER)-debug/creport.elf
cp stratosphere/dmnt/dmnt.elf atmosphere-$(AMSVER)-debug/dmnt.elf
cp stratosphere/eclct.stub/eclct.stub.elf atmosphere-$(AMSVER)-debug/eclct.stub.elf
cp stratosphere/fatal/fatal.elf atmosphere-$(AMSVER)-debug/fatal.elf
cp stratosphere/loader/loader.elf atmosphere-$(AMSVER)-debug/loader.elf
cp stratosphere/pm/pm.elf atmosphere-$(AMSVER)-debug/pm.elf
cp stratosphere/ro/ro.elf atmosphere-$(AMSVER)-debug/ro.elf
cp stratosphere/sm/sm.elf atmosphere-$(AMSVER)-debug/sm.elf
cp stratosphere/spl/spl.elf atmosphere-$(AMSVER)-debug/spl.elf
cp stratosphere/erpt/erpt.elf atmosphere-$(AMSVER)-debug/erpt.elf
cp stratosphere/jpegdec/jpegdec.elf atmosphere-$(AMSVER)-debug/jpegdec.elf
cd atmosphere-$(AMSVER)-debug; zip -r ../atmosphere-$(AMSVER)-debug.zip ./*; cd ../;
rm -r atmosphere-$(AMSVER)-debug
mv atmosphere-$(AMSVER)-debug.zip out/atmosphere-$(AMSVER)-debug.zip
.PHONY: $(TOPTARGETS) $(COMPONENTS)

View File

@@ -27,8 +27,7 @@ This software is licensed under the terms of the GPLv2, with exemptions for spec
You can find a copy of the license in the [LICENSE file](LICENSE).
Exemptions:
* The [yuzu Nintendo Switch emulator](https://github.com/yuzu-emu/yuzu) and the [Ryujinx Team and Contributors](https://github.com/orgs/Ryujinx) are exempt from GPLv2 licensing. They are permitted, each at their individual discretion, to instead license any source code authored for the Atmosphère project as either GPLv2 or later or the [MIT license](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/licensing_exemptions/MIT_LICENSE). In doing so, they may alter, supplement, or entirely remove the copyright notice for each file they choose to relicense. Neither the Atmosphère project nor its individual contributors shall assert their moral rights against any of the aforementioned projects.
* [Nintendo](https://github.com/Nintendo) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the Atmosphère project under the Zero-Clause BSD license.
* The [yuzu emulator project](https://github.com/yuzu-emu/yuzu) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the Atmosphère project as GPLv2 or later.
Credits
=====

View File

@@ -5,8 +5,16 @@ stage2_mtc_path = atmosphere/fusee-mtc.bin
stage2_addr = 0xF0000000
stage2_entrypoint = 0xF0000000
[exosphere]
; Note: Disabling debugmode will cause parts of ams.tma to not work, in the future.
debugmode = 1
debugmode_user = 0
; Note: Disabling usermode exception handlers will cause atmosphere to not fail gracefully under error conditions.
; Support will not be provided to users who disable these. If you do not know what you are doing, leave them on.
disable_user_exception_handlers = 0
; Note: It's currently unknown what effects enabling the usermode PMU register access may have on official code.
enable_user_pmu_access = 0
[stratosphere]
; To force-enable nogc, add nogc = 1
; To force-disable nogc, add nogc = 0
; To opt in to using Atmosphere's NCM reimplementation, add enable_ncm = 1

View File

@@ -1,45 +0,0 @@
# Key: debugmode, default: 1.
# Desc: Controls whether kernel is debug mode.
# Disabling this may break Atmosphere's debugger in a future release.
# Key: debugmode_user, default: 0.
# Desc: Controls whether userland is debug mode.
# Key: disable_user_exception_handlers, default: 0.
# Desc: Controls whether user exception handlers are executed on error.
# NOTE: This will cause atmosphere to not fail gracefully.
# Support may not be provided to users tho disable these.
# If you do not know what you are doing, leave them on.
# Key: enable_user_pmu_access, default: 0.
# Desc: Controls whether userland has access to the PMU registers.
# NOTE: It is unknown what effects this has on official code.
# Key: blank_prodinfo_sysmmc, default: 0.
# Desc: Controls whether PRODINFO should be blanked in sysmmc.
# This will cause the system to see dummied out keys and
# serial number information.
# NOTE: This is not known to be safe, as data may be
# cached elsewhere in the system. Usage is not encouraged.
# Key: blank_prodinfo_emummc, default: 0.
# Desc: Controls whether PRODINFO should be blanked in emummc.
# NOTE: This is not known to be safe, as data may be
# cached elsewhere in the system. Usage is not encouraged.
# Key: allow_writing_to_cal_sysmmc, default: 0.
# Desc: Controls whether PRODINFO can be written by homebrew in sysmmc.
# NOTE: Usage of this setting is strongly discouraged without
# a safe backup elsewhere. Turning this on will also cause Atmosphere
# to ensure a safe backup of calibration data is stored in unused
# mmc space, encrypted to prevent detection. This backup can be used
# to prevent unrecoverable edits in emergencies.
[exosphere]
debugmode=1
debugmode_user=0
disable_user_exception_handlers=0
enable_user_pmu_access=0
blank_prodinfo_sysmmc=0
blank_prodinfo_emummc=0
allow_writing_to_cal_sysmmc=0

View File

@@ -1,18 +1,9 @@
[hbl_config]
; Program Specific Config
; Up to 8 program-specific configurations can be set.
; These use `program_id_#` and `override_key_#`
; where # is in range [0,7].
; program_id_0=010000000000100D
; override_key_0=!R
; Any Application Config
; Note that this will only apply to program IDs that
; are both applications and not specified above
; by a program specific config.
; program_id=010000000000100D
; override_any_app=true
; override_any_app_key=R
; path=atmosphere/hbl.nsp
; override_key=!R
; override_any_app_key=R
[default_config]
; override_key=!L

View File

@@ -32,12 +32,6 @@
; NOTE: EXPERIMENTAL
; If you do not know what you are doing, do not touch this yet.
; fsmitm_redirect_saves_to_sd = u8!0x0
; Controls whether to enable the deprecated hid mitm
; to fix compatibility with old homebrew.
; 0 = Do not enable, 1 = Enable.
; Please note this setting may be removed in a
; future release of Atmosphere.
; enable_deprecated_hid_mitm = 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.

View File

@@ -1,7 +1,7 @@
# Building Atmosphère
The process for building Atmosphère is similar to building Fusée Gelée payloads and other Switch apps.
In order to build Atmosphère you must have devkitARM and devkitA64 installed on your computer. You can find instructions on how to install and setup devkitARM and devkitA64 on various OSes [here](https://devkitpro.org/wiki/Getting_Started). You'll need to install the following packages via (dkp-)pacman: switch-dev switch-freetype switch-libjpeg-turbo devkitARM devkitarm-rules
In order to build Atmosphère you must have devkitARM and devkitA64 installed on your computer. You can find instructions on how to install and setup devkitARM and devkitA64 on various OSes [here](https://devkitpro.org/wiki/Getting_Started). You'll need to install the following packages via (dkp-)pacman: switch-dev switch-freetype devkitARM devkitarm-rules
sept requires you have python installed with the pycryptodome PyPi packages (`pip install pycryptodome`). You may also want to install the zip package from your package manager of choice to support the `make dist` recipe.

View File

@@ -1,164 +1,4 @@
# Changelog
## 0.12.0
+ Configuration for exosphere was moved to sd:/exosphere.ini.
+ This is to facilitate BIS protection changes described below.
+ Hopefully having this outside of the Atmosphere folder will prevent accidental deletion, since this now contains important settings.
+ Atmosphere's bis protection policy for the PRODINFO partition was substantially reworked.
+ Support was added for "automatically" performing a "blanking" operation to PRODINFO without actually modifying NAND.
+ This is equivalent to using the "incognito" homebrew tool, but NAND is never actually modified.
+ This can be turned on in sysmmc by setting `blank_prodinfo_sysmmc=1` in exosphere.ini, and in emummc by setting `blank_prodinfo_emummc=1` in exosphere.ini.
+ **Please note**: This is not known to be safe. There is a lack of research on whether the information blanked out is cached elsewhere in the system.
+ Usage of this option is not encouraged for this reason.
+ Support was added for writing to the PRODINFO partition, if a verified encrypted backup has been made.
+ PRODINFO is the only system data that cannot be recovered if not backed up, and thus Atmosphere has backed it up to the SD card on boot for some time now.
+ Users who wish to modify their calibration data may now do so unconditionally in emummc, and in sysmmc if `allow_writing_to_cal_sysmmc=1` is set in exosphere.ini.
+ **Please note**: This is heavily discouraged, and the typical user will almost never want to do this.
+ Setting this option will cause Atmosphere to attempt to verify (or create) an encrypted backup of the PRODINFO data to an unused region in the partition.
+ The backup is encrypted with per-console keys that Atmosphere's developers do not know.
+ If the backup is not verified or created, writes will not work. Users who have corrupted their PRODINFO in the past are encouraged to flash a good backup to allow use of this setting.
+ Reads and writes to the region used for the securely encrypted backup will appear to succeed, but will actually read/write from a buffer filled with garbage in memory.
+ Support will be investigated in the future for supporting booting with fully blanked calibration.
+ This is desirable to allow boot to succeed for users who lost their calibration data due to bricking homebrew before bis protection was implemented.
+ `creport` has been updated to use the new screenshot APIs added in 9.0.0+.
+ On 10.0.0+, if a crash occurs in an application (not applet or sysmodule) a screenshot will now be automatically saved to the SD card.
+ If the user applies a patch to vi on 9.0.0 (as the command this uses was previously for dev-units only), this can also work on 9.0.0.
+ The new sysmodule `pgl` added in 10.0.0 was reimplemented.
+ `pgl` ("Program Launcher", probably) is responsible for managing launched user-processes, previously this was handled by NS.
+ The most exciting thing about pgl is that it finally provides an API for multiple clients to subscribe to process events.
+ Using these new APIs, system modules / other homebrew can subscribe to be notified whenever a process event occurs.
+ This means action can be taken on process launch, process exit, process crash, etc.
+ A slight concern with Nintendo's implementation is that each subscriber object uses 0x448 bytes of memory, and N only reserves 8KB for all allocations in pgl.
+ Atmosphere's implementation uses a 32KB heap, which should not be exhaustible.
+ Atmosphere's implementation has a total memory footprint roughly 0x28000 bytes smaller than Nintendo's.
+ A reimplementation was added for the `jpegdec` system module (thanks @HookedBehemoth)!
+ This allows two sessions instead of 1, so homebrew can now use it for software jpeg decoding in addition to the OS itself.
+ As usual the implementation has a very slightly smaller memory footprint than Nintendo's.
+ `dmnt`'s Cheat VM was extended to add three new opcodes.
+ The first new opcode, "ReadWriteStaticRegister", allows for cheats to read from a bank of 128 read-only static registers, and write to a bank of 128 write-only static registers.
+ This can be used in concert with new IPC commands that allow a cheat manager to read or write the value of these static registers to have "dynamic" cheats.
+ As an example, a cheat manager could write a value to a static register that a cheat to control how many of an item to give in a game.
+ As another example, a cheat manager could read a static register that a cheat writes to to learn how many items a player has.
+ The second and third opcodes are a pair, "PauseProcess" and "ResumeProcess".
+ Executing pause process in a cheat will pause the game (it will be frozen) until a resume process opcode is used.
+ These are also available over IPC, for cheat managers or system modules that want to pause or resume the attached cheat process.
+ This allows a cheat to know that the game won't modify or access data the cheat is accessing.
+ For example, this can be used to prevent Pokemon from seeing a pokemon a cheat is in the middle of injecting and turning it into a bad egg.
+ A bug was fixed that would cause the console to crash when connected to Wi-Fi on versions between 3.0.0 and 4.1.0 inclusive.
+ A bug was fixed that could cause boot to fail sporadically due to cache/tlb mismanagement when doing physical ASLR of the kernel.
+ A number of other minor issues were addressed (and more of Atmosphere was updated to reflect other changes in 10.0.x).
+ General system stability improvements to enhance the user's experience.
## 0.11.1
+ A bug was fixed that could cause owls to flicker under certain circumstances.
+ For those interested in technical details, in 10.0.0 kernelldr/kernel no longer set cpuactlr_el1, assuming that it was set correctly by the secure monitor.
+ However, exosphere did not set cpuactlr_el1. This meant that the register held the reset value going into boot.
+ This caused a variety of highly erratic symptoms, including causing basically any game to crash seemingly randomly.
+ A number of other major inaccuracies in exosphere were corrected.
+ General system stability improvements to enhance the user's experience.
## 0.11.0
+ Support was added for 10.0.0.
+ Exosphere has been updated to reflect the new key import semantics in 10.0.0.
+ kernel_ldr now implements physical ASLR for the kernel's backing pages.
+ Loader, NCM, and PM have been updated to reflect the changes Nintendo made in 10.0.0.
+ Creport was updated to use the new `pgl` service to terminate processes instead of `ns:dev`.
+ A reimplementation of the `erpt` (error reports) system module was added.
+ In previous versions of Atmosphere, a majority of error reports were prevented via a combination of custom creport, fatal, and stubbed eclct.
+ However, error reports were still generated via some system actions.
+ Most notably, any time the error applet appeared, an error report was generated.
+ By default, atmosphere disabled the *uploading* of error reports, but going online in OFW after an error report occurred in Atmosphere could lead to undesirable telemetry.
+ Atmosphere's `erpt` reimplementation allows the system to interact with existing error reports as expected.
+ However, all new error reports are instead saved to the sd card (`/atmosphere/erpt_reports`), and are not committed to the system savegame.
+ Users curious about what kind of telemetry is being prevented can view the reports as they're generated in there.
+ Reports are saved as msgpack (as this is what Nintendo uses).
+ Please note, not all telemetry is disabled. Play reports and System reports will continue to function unmodified.
+ With atmosphere's `erpt` implementation, homebrew can now use the native error applet to display errors without worrying about generating undesirable telemetry.
+ libstratosphere and libvapours received a number of improvements.
+ With thanks to @Adubbz for his work, the NCM namespace now has client code.
+ This lays the groundwork for first-class system update/downgrade homebrew support in the near future.
+ In particular, code implementing the os namespace is significantly more accurate.
+ In addition, Nintendo's allocators were implemented, allowing for identical memory efficiency versus Nintendo's implementations.
+ General system stability improvements to enhance the user's experience.
## 0.10.5
+ Changes were made to the way fs.mitm builds images when providing a layeredfs romfs.
+ Building romfs metadata previously had a memory cost of about ~4-5x the file table size.
+ This caused games that have particularly enormous file metadata tables (> 4 MB) to exhaust fs.mitm's 16 MB memory pool.
+ The code that creates romfs images was thus changed to be significantly more memory efficient, again.
+ Memory requirements have been lowered from ~4x file table size to ~2x file table size + 0.5 MB.
+ There is a slight speed penalty to this, but testing on Football Manager 2020 only took an extra ~1.5 seconds for the game to boot with many modded files.
+ This shouldn't be noticeable thanks to the async changes made in 0.10.2.
+ If you encounter a game that exhausts ams.mitm's memory (crashing it) when loading layeredfs mods, please contact SciresM.
+ Romfs building can be made even more memory efficient, but unless games show up with even more absurdly huge file tables it seems not worth the speed trade-off.
+ A bug was fixed that caused Atmosphere's fatal error context to not dump TLS for certain processes.
+ General system stability improvements to enhance the user's experience.
## 0.10.4
+ With major thanks to @Adubbz for his work, the NCM system module has now been re-implemented.
+ This was a major stepping stone towards the goal of having implementations everything in the Switch's package1/package2 firmware.
+ This also lays the groundwork for libstratosphere providing bindings for changing the installed version of the Switch's OS.
+ **Please Note**: The NCM implementation will initially be opt-in.
+ The Atmosphere team is confident in our NCM implementation (and we have tested it on every firmware version).
+ That said, this is our first system module that manages NAND savegames -- and caution is a habit.
+ We do not anticipate any issues that didn't come up in testing, so this is just our being particularly careful.
+ Users interested in opting in to using our implementation should set `stratosphere!ncm_enabled = 1` in BCT.ini.
+ In the unlikely event that any issues are encountered, please report them to @SciresM.
+ The NCM implementation will stop being opt-in in a future update, after thorough testing has been done in practice.
+ A bug was fixed in emummc that caused Nintendo path to be corrupted on 1.0.0.
+ This manifested as the emummc folder being created inside the virtual NAND instead of the SD card.
+ It's unlikely there are any negative consequences to this in practice.
+ If you want to be truly sure, you can re-clone sysmmc before updating a 1.0.0 emummc to latest firmware.
+ Stratosphere system modules now use new Nintendo-style FS bindings instead of stdio.
+ This saves a modest amount of memory due to leaner code, and greatly increases the accuracy of several components.
+ These bindings will make it easier for other system modules using libstratosphere to interact with the filesystem.
+ This also lays the groundwork for changes necessary to support per-emummc Atmosphere folders in a future update.
+ Atmosphere's fatal error context now dumps 0x100 of TLS.
+ This will make it much easier to fix bugs when an error report is dumped for whatever caused the crash.
+ General system stability improvements to enhance the user's experience.
## 0.10.3
+ Support was added for 9.2.0.
+ Support was added for redirecting manual html content for games.
+ This works like normal layeredfs, replacing content placed in `/atmosphere/contents/<program id>/manual_html/`.
+ This allows for game mods/translations to provide custom manual content, if they so choose.
+ A number of improvements were made to Atmosphere's memory usage, including:
+ `fatal` now uses STB instead of freetype for rendering.
+ This saves around 1 MB of memory, and makes our fatal substantially leaner than Nintendo's.
+ `sm` no longer wastes 2 MiB unnecessarily.
+ fusee/sept's sdmmc access now better matches official behavior.
+ This improves compatibility with some SD cards.
+ `ro` has been updated to reflect changes made in 9.1.0.
+ The temporary auto-migration added in 0.10.0 has been removed, since the transitionary period is well over.
+ General system stability improvements to enhance the user's experience.
## 0.10.2
+ hbl configuration was made more flexible.
+ Up to eight specific program ids can now be specified to have their own override keys.
+ This allows designating both the album applet and a specific game as hbl by default as desired.
+ Configuration targeting a specific program is now mutually exclusive with override-any-app for that program.
+ This fixes unintuitive behavior when override key differed for an application specific program.
+ Loader's external content fileystem support was fixed (thanks @misson20000!).
+ KernelLdr was reimplemented.
+ This is the first step towards developing mesosphere, Atmosphere's planned reimplementation of the Switch's Kernel.
+ The typical user won't notice anything different, as there are no extensions, but a lot of groundwork was laid for future development.
+ Improvements were made to the way Atmosphere's buildsystem detects source code files.
+ This significantly reduces compilation time (saving >30 seconds) on the machine that builds official releases.
+ Certain device code was cleaned up and made more correct in fusee/sept/exosphere (thanks @hexkyz!).
+ A number of changes were made to the way fs.mitm builds images when providing a layeredfs romfs.
+ Some games (Resident Evil 6, Football Manager 2020 Touch, possibly others) have enormous numbers of files.
+ Attempting to create a layeredfs mod for these games actually caused fs.mitm to run out of memory, causing a fatal error.
+ The code that creates these images was changed to be significantly more memory efficient.
+ However, these changes also cause a significant slowdown in the romfs building code (~2-5x).
+ This introduced a noticeable stutter when launching a game, because the UI thread would block on the romfs creation.
+ To solve this, fs.mitm now lazily initializes the image in a background thread.
+ This fixes stutter issues, however some games may be slightly slower (~1-2s in the worst cases) to transition from the "loading" GIF to gameplay now.
+ Please note: the slowdown is not noticeable in the common case where games don't have tons of files (typical is ~0.1-0.2 seconds).
+ Once the image has been built, there is no further speed penalty at runtime -- only when the game is launched.
+ A number of other bugs were fixed, including:
+ Several minor logic inversions that could have caused fatal errors when modding games.
+ Atmosphere's new-ipc code did not handle "automatic" recvlist buffers correctly, so some non-libnx homebrew could crash.
+ fs.mitm now correctly mitms sdb, which makes redirection of certain system data archives work again.
+ In 0.10.0/0.10.1, changing the system font/language did not work correctly due to this.
+ A bug was fixed in process cleanup that caused the system to hang on < 5.0.0.
+ The temporary hid-mitm added in Atmosphere 0.9.0 was disabled by default.
+ Please ensure your homebrew is updated.
+ For now, users may re-enable this mitm by use of a custom setting (`atmosphere!enable_deprecated_hid_mitm`) to ease the transition process some.
+ Please note: support for this setting may be removed to save memory in a future atmosphere release.
+ General system stability improvements to enhance the user's experience.
## 0.10.1
+ A bug was fixed that caused memory reallocation to the system pool to work improperly on firmware 5.0.0 and above.
+ Atmosphere was always trying to deallocate memory away from the applet pool and towards the system pool.

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018-2020 Atmosphère-NX
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/m4xw/emuMMC
branch = develop
commit = b168ddf5fbb31013ff529a4859110c82b11eb361
parent = c07f54f3709a4710e0aead6c91139fa0893b5e5c
commit = bd81a674a946c30b566e1732a95c18f19b701558
parent = 6ee525201ccef107c61d81ba73c891e3eb5f0215
method = rebase
cmdver = 0.4.1
cmdver = 0.4.0

View File

@@ -1,21 +1,21 @@
# emuMMC
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
### Supported Horizon Versions
**1.0.0 - 10.0.0**
**1.0.0 - 9.1.0**
## Features
* Arbitrary SDMMC backend selection
* Arbitrary SDMMC backend selection
**This allows loading eMMC from SD or even SD from eMMC**
* On the fly hooking / patching, fully self-infesting
* On the fly hooking / patching, fully self-infesting
**Only one payload required for all versions!**
* File-based SDMMC backend support (from SD)
* File-based SDMMC backend support (from SD)
**This allows loading eMMC images from hekate-backups (split or not)**
* SDMMC device based sector offset (*currently eMMC only*)
* SDMMC device based sector offset (*currently eMMC only*)
**Raw partition support for eMMC from SD with less performance overhead**
* Full support for `/Nintendo` folder redirection to a arbitrary path
* Full support for `/Nintendo` folder redirection to a arbitrary path
**No 8 char length restriction!**
* exosphere based context configuration
* exosphere based context configuration
**This includes full support for multiple emuMMC images**
## Compiling

View File

@@ -45,8 +45,6 @@
#include "offsets/900_exfat.h"
#include "offsets/910.h"
#include "offsets/910_exfat.h"
#include "offsets/1000.h"
#include "offsets/1000_exfat.h"
#include "../utils/fatal.h"
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
@@ -102,8 +100,6 @@ DEFINE_OFFSET_STRUCT(_900);
DEFINE_OFFSET_STRUCT(_900_EXFAT);
DEFINE_OFFSET_STRUCT(_910);
DEFINE_OFFSET_STRUCT(_910_EXFAT);
DEFINE_OFFSET_STRUCT(_1000);
DEFINE_OFFSET_STRUCT(_1000_EXFAT);
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
switch (version) {
@@ -165,10 +161,6 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
return &(GET_OFFSET_STRUCT_NAME(_910));
case FS_VER_9_1_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_910_EXFAT));
case FS_VER_10_0_0:
return &(GET_OFFSET_STRUCT_NAME(_1000));
case FS_VER_10_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1000_EXFAT));
default:
fatal_abort(Fatal_UnknownVersion);
}

View File

@@ -65,9 +65,6 @@ enum FS_VER
FS_VER_9_1_0,
FS_VER_9_1_0_EXFAT,
FS_VER_10_0_0,
FS_VER_10_0_0_EXFAT,
FS_VER_MAX,
};

View File

@@ -48,8 +48,10 @@
// Nintendo Paths
#define FS_OFFSET_100_NINTENDO_PATHS \
{ \
{.opcode_reg = 8, .adrp_offset = 0x00032C58, .add_rel_offset = 8}, \
{.opcode_reg = 9, .adrp_offset = 0x00032F40, .add_rel_offset = 8}, \
{.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}, \
}

View File

@@ -1,58 +0,0 @@
/*
* 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_1000_H__
#define __FS_1000_H__
// Accessor vtable getters
#define FS_OFFSET_1000_SDMMC_ACCESSOR_GC 0x14DC90
#define FS_OFFSET_1000_SDMMC_ACCESSOR_SD 0x14BDA0
#define FS_OFFSET_1000_SDMMC_ACCESSOR_NAND 0x146C20
// Hooks
#define FS_OFFSET_1000_SDMMC_WRAPPER_READ 0x142380
#define FS_OFFSET_1000_SDMMC_WRAPPER_WRITE 0x142460
#define FS_OFFSET_1000_RTLD 0x634
#define FS_OFFSET_1000_RTLD_DESTINATION 0x9C
#define FS_OFFSET_1000_CLKRST_SET_MIN_V_CLK_RATE 0x1415A0
// Misc funcs
#define FS_OFFSET_1000_LOCK_MUTEX 0x28910
#define FS_OFFSET_1000_UNLOCK_MUTEX 0x28960
#define FS_OFFSET_1000_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
// Misc Data
#define FS_OFFSET_1000_SD_MUTEX 0xE273E8
#define FS_OFFSET_1000_NAND_MUTEX 0xE22DA0
#define FS_OFFSET_1000_ACTIVE_PARTITION 0xE22DE0
#define FS_OFFSET_1000_SDMMC_DAS_HANDLE 0xE0AB90
// NOPs
#define FS_OFFSET_1000_SD_DAS_INIT 0x151CEC
// Nintendo Paths
#define FS_OFFSET_1000_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006BBA4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00078520, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007ED0C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0009115C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1000_H__

View File

@@ -1,58 +0,0 @@
/*
* 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_1000_EXFAT_H__
#define __FS_1000_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_1000_EXFAT_SDMMC_ACCESSOR_GC 0x14DC90
#define FS_OFFSET_1000_EXFAT_SDMMC_ACCESSOR_SD 0x14BDA0
#define FS_OFFSET_1000_EXFAT_SDMMC_ACCESSOR_NAND 0x146C20
// Hooks
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_READ 0x142380
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_WRITE 0x142460
#define FS_OFFSET_1000_EXFAT_RTLD 0x634
#define FS_OFFSET_1000_EXFAT_RTLD_DESTINATION 0x9C
#define FS_OFFSET_1000_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1415A0
// Misc funcs
#define FS_OFFSET_1000_EXFAT_LOCK_MUTEX 0x28910
#define FS_OFFSET_1000_EXFAT_UNLOCK_MUTEX 0x28960
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
// Misc Data
#define FS_OFFSET_1000_EXFAT_SD_MUTEX 0xE353E8
#define FS_OFFSET_1000_EXFAT_NAND_MUTEX 0xE30DA0
#define FS_OFFSET_1000_EXFAT_ACTIVE_PARTITION 0xE30DE0
#define FS_OFFSET_1000_EXFAT_SDMMC_DAS_HANDLE 0xE18B90
// NOPs
#define FS_OFFSET_1000_EXFAT_SD_DAS_INIT 0x151CEC
// Nintendo Paths
#define FS_OFFSET_1000_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006BBA4, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00078520, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007ED0C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x0009115C, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1000_EXFAT_H__

View File

@@ -36,6 +36,7 @@ sdmmc_storage_t sd_storage;
// init vars
bool custom_driver = true;
extern const volatile emuMMC_ctx_t emuMMC_ctx;
// FS funcs
_sdmmc_accessor_gc sdmmc_accessor_gc;
@@ -343,7 +344,7 @@ uint64_t sdmmc_wrapper_controller_close(int mmc_id)
{
return 0;
}
if (mmc_id == FS_SDMMC_EMMC)
{
// Close file handles and unmount

View File

@@ -48,9 +48,6 @@ extern char __argdata__;
// TODO
static char nintendo_path[0x80] = "Nintendo";
// 1.0.0 requires special path handling because it has separate album and contents paths.
#define FS_100_ALBUM_PATH 0
#define FS_100_CONTENTS_PATH 1
static char nintendo_path_album_100[0x100] = "/Nintendo/Album";
static char nintendo_path_contents_100[0x100] = "/Nintendo/Contents";
@@ -278,18 +275,23 @@ void setup_nintendo_paths(void)
// 1.0.0 needs special handling because it uses two paths.
// Do album path
{
snprintf(nintendo_path_album_100, sizeof(nintendo_path_album_100), "/%s/Album", nintendo_path);
int path_len = snprintf(nintendo_path_album_100, sizeof(nintendo_path_album_100), "/%s/Album", nintendo_path);
intptr_t nintendo_album_path_location = (intptr_t)&nintendo_path_album_100;
uintptr_t fs_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[FS_100_ALBUM_PATH].adrp_offset);
write_adrp_add(fs_offsets->nintendo_paths[FS_100_ALBUM_PATH].opcode_reg, fs_adrp_opcode_location, fs_offsets->nintendo_paths[FS_100_ALBUM_PATH].add_rel_offset, nintendo_album_path_location);
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, 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
{
snprintf(nintendo_path_contents_100, sizeof(nintendo_path_contents_100), "/%s/Contents", nintendo_path);
int path_len = snprintf(nintendo_path_contents_100, sizeof(nintendo_path_contents_100), "/%s/Contents", nintendo_path);
intptr_t nintendo_contents_path_location = (intptr_t)&nintendo_path_contents_100;
uintptr_t fs_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[FS_100_CONTENTS_PATH].adrp_offset);
write_adrp_add(fs_offsets->nintendo_paths[FS_100_CONTENTS_PATH].opcode_reg, fs_adrp_opcode_location, fs_offsets->nintendo_paths[FS_100_CONTENTS_PATH].add_rel_offset, nintendo_contents_path_location);
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, 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);
}
}
}

View File

@@ -50,18 +50,8 @@ extern "C" {
* @return Result code.
* @note Syscall number 0x55.
* @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available.
* @warning Only exists on [10.0.0+]. For older versions use \ref svcLegacyQueryIoMapping.
*/
Result svcQueryIoMapping(u64* virtaddr, u64* out_size, u64 physaddr, u64 size);
/**
* @brief Returns a virtual address mapped to a given IO range.
* @return Result code.
* @note Syscall number 0x55.
* @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available.
* @warning Only exists on [1.0.0-9.2.0]. For newer versions use \ref svcQueryIoMapping.
*/
Result svcLegacyQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size);
Result svcQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size);
/**
* @brief Attaches a device address space to a device.

View File

@@ -17,15 +17,6 @@
.endm
SVC_BEGIN svcQueryIoMapping
STP X0, X1, [SP, #-16]!
SVC 0x55
LDP X3, X4, [SP], #16
STR X1, [X3]
STR X2, [X4]
RET
SVC_END
SVC_BEGIN svcLegacyQueryIoMapping
STR X0, [SP, #-16]!
SVC 0x55
LDR X2, [SP], #16

View File

@@ -25,12 +25,11 @@ enum FatalReason
Fatal_InvalidAccessor,
Fatal_ReadNoAccessor,
Fatal_WriteNoAccessor,
Fatal_IoMappingLegacy,
Fatal_IoMapping,
Fatal_UnknownVersion,
Fatal_BadResult,
Fatal_GetConfig,
Fatal_CloseAccessor,
Fatal_IoMapping,
Fatal_Max
};

View File

@@ -38,15 +38,8 @@ static inline uintptr_t _GetIoMapping(u64 io_addr, u64 io_size)
u64 vaddr;
u64 aligned_addr = (io_addr & ~0xFFFul);
u64 aligned_size = io_size + (io_addr - aligned_addr);
if (emuMMC_ctx.fs_ver >= FS_VER_10_0_0) {
u64 out_size;
if (svcQueryIoMapping(&vaddr, &out_size, aligned_addr, aligned_size) != 0) {
fatal_abort(Fatal_IoMapping);
}
} else {
if (svcLegacyQueryIoMapping(&vaddr, aligned_addr, aligned_size) != 0) {
fatal_abort(Fatal_IoMappingLegacy);
}
if (svcQueryIoMapping(&vaddr, aligned_addr, aligned_size) != 0) {
fatal_abort(Fatal_IoMapping);
}
return (uintptr_t)(vaddr + (io_addr - aligned_addr));
}

View File

@@ -19,7 +19,6 @@
#define _UTIL_H_
#include "types.h"
#include "../emuMMC/emummc_ctx.h"
intptr_t QueryIoMapping(u64 addr, u64 size);
#define byte_swap_32(num) ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
@@ -38,6 +37,4 @@ void usleep(u64 ticks);
void msleep(u64 milliseconds);
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
extern volatile emuMMC_ctx_t emuMMC_ctx;
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -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 "utils.h"
@@ -33,7 +33,7 @@ static inline uint32_t get_special_clk_reg(CarDevice dev) {
case CARDEVICE_BPMP: return 0;
default: reboot();
}
}
}
static inline uint32_t get_special_clk_val(CarDevice dev) {
switch (dev) {
@@ -48,19 +48,19 @@ static inline uint32_t get_special_clk_val(CarDevice dev) {
}
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};
static uint32_t g_rst_reg_offsets[NUM_CAR_BANKS] = {0x004, 0x008, 0x00C, 0x358, 0x35C, 0x28C, 0x2A4};
static uint32_t g_clk_clr_reg_offsets[NUM_CAR_BANKS] = {0x324, 0x32C, 0x334, 0x444, 0x44C, 0x228, 0x2A0};
void car_configure_oscillators(void) {
/* Enable the crystal oscillator, setting drive strength to the saved value in PMC. */
CLK_RST_CONTROLLER_OSC_CTRL_0 = (CLK_RST_CONTROLLER_OSC_CTRL_0 & 0xFFFFFC0E) | 1 | (((APBDEV_PMC_OSC_EDPD_OVER_0 >> 1) & 0x3F) << 4);
/* Set CLK_M_DIVISOR to 1 (causes actual division by 2.) */
CLK_RST_CONTROLLER_SPARE_REG0_0 = (1 << 2);
/* Reading the register after writing it is required to ensure value takes. */
(void)(CLK_RST_CONTROLLER_SPARE_REG0_0);
/* Set TIMERUS_USEC_CFG to cycle at 0x60 / 0x5 = 19.2 MHz. */
/* Value is (dividend << 8) | (divisor). */
TIMERUS_USEC_CFG_0 = 0x45F;
@@ -68,30 +68,30 @@ void car_configure_oscillators(void) {
void car_mbist_workaround(void) {
/* This code works around MBIST bug. */
/* Clear LVL2_CLK_GATE_OVR* registers. */
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA_0 = 0;
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_0 = 0;
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC_0 = 0;
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 = 0;
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE_0 = 0;
/* Clear bit patterns in CAR. */
/* L: Reset all but RTC, TMR, GPIO, BPMP Cache (CACHE2). */
/* L: Reset all but RTC, TMR, GPIO, BPMP Cache (CACHE2). */
MAKE_CAR_REG(g_clk_clr_reg_offsets[0]) = MAKE_CAR_REG(g_clk_reg_offsets[0]) & 0x7FFFFECF;
/* H: Reset all but MC, PMC, FUSE, EMC. */
/* H: Reset all but MC, PMC, FUSE, EMC. */
MAKE_CAR_REG(g_clk_clr_reg_offsets[1]) = MAKE_CAR_REG(g_clk_reg_offsets[1]) & 0xFDFFFF3E;
/* U: Reset all but CSITE, IRAM[A-D], BPMP Cache RAM (CRAM2). */
/* U: Reset all but CSITE, IRAM[A-D], BPMP Cache RAM (CRAM2). */
MAKE_CAR_REG(g_clk_clr_reg_offsets[2]) = MAKE_CAR_REG(g_clk_reg_offsets[2]) & 0xFE0FFDFF;
/* V: Reset all but MSELECT, S/PDIF audio doubler, TZRAM, SE. */
/* V: Reset all but MSELECT, S/PDIF audio doubler, TZRAM, SE. */
MAKE_CAR_REG(g_clk_clr_reg_offsets[3]) = MAKE_CAR_REG(g_clk_reg_offsets[3]) & 0x3FBFFFF7;
/* W: Reset all but PCIERX[0-5], ENTROPY. */
/* W: Reset all but PCIERX[0-5], ENTROPY. */
MAKE_CAR_REG(g_clk_clr_reg_offsets[4]) = MAKE_CAR_REG(g_clk_reg_offsets[4]) & 0xFFDFFF03;
/* X: Reset all but ETC, MCLK, MCLK2, I2C6, EMC_DLL, GPU, DBGAPB, PLLG_REF, . */
/* X: Reset all but ETC, MCLK, MCLK2, I2C6, EMC_DLL, GPU, DBGAPB, PLLG_REF, . */
MAKE_CAR_REG(g_clk_clr_reg_offsets[5]) = MAKE_CAR_REG(g_clk_reg_offsets[5]) & 0xDCFFB87F;
/* Y: Reset all but MC_CDPA, MC_CCPA. */
/* Y: Reset all but MC_CDPA, MC_CCPA. */
MAKE_CAR_REG(g_clk_clr_reg_offsets[6]) = MAKE_CAR_REG(g_clk_reg_offsets[6]) & 0xFFFFFCFF;
/* Enable clock to MC1, if CH1 is enabled in EMC. */
if (EMC_FBIO_CFG7_0 & 4) { /* CH1_ENABLE */
CLK_RST_CONTROLLER_CLK_ENB_W_SET_0 |= 0x40000000; /* SET_CLK_ENB_MC1 */
@@ -132,7 +132,3 @@ void clkrst_reboot(CarDevice dev) {
clkrst_disable(dev);
clkrst_enable(dev);
}
void clkrst_enable_fuse_regs(bool enable) {
CLK_RST_CONTROLLER_MISC_CLK_ENB_0 = ((CLK_RST_CONTROLLER_MISC_CLK_ENB_0 & 0xEFFFFFFF) | ((enable & 1) << 28));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -103,8 +103,7 @@ 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -29,7 +29,7 @@ bool fuse_check_downgrade_status(void) {
}
void fuse_disable_programming(void) {
FUSE_REGS->FUSE_DISABLEREGPROGRAM = 1;
FUSE_REGS->FUSE_DIS_PGM = 1;
}
static fuse_bypass_data_t g_fuse_bypass_entries[NUM_FUSE_BYPASS_ENTRIES] = {
@@ -37,14 +37,13 @@ static fuse_bypass_data_t g_fuse_bypass_entries[NUM_FUSE_BYPASS_ENTRIES] = {
};
void fuse_configure_fuse_bypass(void) {
/* Make all fuse registers visible. */
clkrst_enable_fuse_regs(true);
/* Enable fuses in CAR? This seems to affect fuse data visibility. */
CLK_RST_CONTROLLER_MISC_CLK_ENB_0 |= 0x10000000;
/* Configure bypass/override, only if programming is allowed. */
if (!(FUSE_REGS->FUSE_DISABLEREGPROGRAM & 1)) {
/* Enable write access and flush status. */
FUSE_REGS->FUSE_WRITE_ACCESS_SW = (FUSE_REGS->FUSE_WRITE_ACCESS_SW & ~0x1) | 0x10000;
/* Configure bypass/override, only if programming is allowed. */
if (!(FUSE_REGS->FUSE_DIS_PGM & 1)) {
/* Enable write access. */
FUSE_REGS->FUSE_WRITE_ACCESS = (FUSE_REGS->FUSE_WRITE_ACCESS & ~0x1) | 0x10000;
/* Enable fuse bypass config. */
FUSE_REGS->FUSE_FUSEBYPASS = 1;
@@ -54,7 +53,7 @@ void fuse_configure_fuse_bypass(void) {
}
/* Disable fuse write access. */
FUSE_REGS->FUSE_WRITE_ACCESS_SW |= 1;
FUSE_REGS->FUSE_WRITE_ACCESS |= 1;
/* Enable fuse bypass config. */
/* I think this is a bug, and Nintendo meant to write 0 here? */
@@ -64,7 +63,7 @@ void fuse_configure_fuse_bypass(void) {
/* I have no idea why this happens. What? */
/* This is probably also either a bug or does nothing. */
/* Is this bit even clearable? */
FUSE_REGS->FUSE_DISABLEREGPROGRAM &= 0xFFFFFFFE;
FUSE_REGS->FUSE_DIS_PGM &= 0xFFFFFFFE;
/* Restore saved private key disable bit. */
FUSE_REGS->FUSE_PRIVATEKEYDISABLE |= (APBDEV_PMC_SECURE_SCRATCH21_0 & 0x10);
@@ -72,4 +71,5 @@ void fuse_configure_fuse_bypass(void) {
/* Lock private key disable secure scratch. */
APBDEV_PMC_SEC_DISABLE2_0 |= 0x4000000;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -23,167 +23,154 @@
#include "utils.h"
typedef struct {
uint32_t FUSE_FUSECTRL;
uint32_t FUSE_FUSEADDR;
uint32_t FUSE_FUSERDATA;
uint32_t FUSE_FUSEWDATA;
uint32_t FUSE_FUSETIME_RD1;
uint32_t FUSE_FUSETIME_RD2;
uint32_t FUSE_FUSETIME_PGM1;
uint32_t FUSE_FUSETIME_PGM2;
uint32_t FUSE_PRIV2INTFC_START;
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_DISABLEREGPROGRAM;
uint32_t FUSE_WRITE_ACCESS_SW;
uint32_t FUSE_DIS_PGM;
uint32_t FUSE_WRITE_ACCESS;
uint32_t FUSE_PWR_GOOD_SW;
uint32_t _0x38;
uint32_t FUSE_PRIV2RESHIFT;
uint32_t _0x40[0x3];
uint32_t FUSE_FUSETIME_RD3;
uint32_t _0x50[0xC];
uint32_t FUSE_PRIVATE_KEY0_NONZERO;
uint32_t FUSE_PRIVATE_KEY1_NONZERO;
uint32_t FUSE_PRIVATE_KEY2_NONZERO;
uint32_t FUSE_PRIVATE_KEY3_NONZERO;
uint32_t FUSE_PRIVATE_KEY4_NONZERO;
uint32_t _0x90[0x1C];
} tegra_fuse_t;
uint32_t _0x38[0x32];
} fuse_registers_t;
typedef struct {
uint32_t FUSE_PRODUCTION_MODE;
uint32_t FUSE_JTAG_SECUREID_VALID;
uint32_t FUSE_ODM_LOCK;
uint32_t FUSE_OPT_OPENGL_EN;
uint32_t _0x4;
uint32_t _0x8;
uint32_t _0xC;
uint32_t FUSE_SKU_INFO;
uint32_t FUSE_CPU_SPEEDO_0_CALIB;
uint32_t FUSE_CPU_IDDQ_CALIB;
uint32_t FUSE_DAC_CRT_CALIB;
uint32_t FUSE_DAC_HDTV_CALIB;
uint32_t FUSE_DAC_SDTV_CALIB;
uint32_t FUSE_OPT_FT_REV;
uint32_t FUSE_CPU_SPEEDO_1_CALIB;
uint32_t FUSE_CPU_SPEEDO_2_CALIB;
uint32_t FUSE_SOC_SPEEDO_0_CALIB;
uint32_t FUSE_SOC_SPEEDO_1_CALIB;
uint32_t FUSE_SOC_SPEEDO_2_CALIB;
uint32_t FUSE_SOC_IDDQ_CALIB;
uint32_t FUSE_RESERVED_PRODUCTION_WP;
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 FUSE_RESERVED_PRODUCTION;
uint32_t FUSE_HDMI_LANE0_CALIB;
uint32_t FUSE_HDMI_LANE1_CALIB;
uint32_t FUSE_HDMI_LANE2_CALIB;
uint32_t FUSE_HDMI_LANE3_CALIB;
uint32_t FUSE_ENCRYPTION_RATE;
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_TSENSOR1_CALIB;
uint32_t FUSE_TSENSOR2_CALIB;
uint32_t FUSE_VSENSOR_CALIB;
uint32_t FUSE_OPT_CP_REV;
uint32_t FUSE_OPT_PFG;
uint32_t FUSE_TSENSOR0_CALIB;
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE;
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[0x5];
uint32_t FUSE_ARM_JTAG_DIS;
uint32_t FUSE_BOOT_DEVICE_INFO;
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_OPT_VP9_DISABLE;
uint32_t FUSE_VP8_ENABLE;
uint32_t FUSE_RESERVED_ODM[0x8];
uint32_t FUSE_OBS_DIS;
uint32_t FUSE_NOR_INFO;
uint32_t FUSE_USB_CALIB;
uint32_t _0xE8;
uint32_t _0xEC;
uint32_t FUSE_SKU_USB_CALIB;
uint32_t FUSE_SKU_DIRECT_CONFIG;
uint32_t FUSE_KFUSE_PRIVKEY_CTRL;
uint32_t FUSE_PACKAGE_INFO;
uint32_t FUSE_OPT_VENDOR_CODE;
uint32_t FUSE_OPT_FAB_CODE;
uint32_t FUSE_OPT_LOT_CODE_0;
uint32_t FUSE_OPT_LOT_CODE_1;
uint32_t FUSE_OPT_WAFER_ID;
uint32_t FUSE_OPT_X_COORDINATE;
uint32_t FUSE_OPT_Y_COORDINATE;
uint32_t FUSE_OPT_SEC_DEBUG_EN;
uint32_t FUSE_OPT_OPS_RESERVED;
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_CALIB;
uint32_t FUSE_TSENSOR3_CALIB;
uint32_t FUSE_SKU_BOND_OUT_L;
uint32_t FUSE_SKU_BOND_OUT_H;
uint32_t FUSE_SKU_BOND_OUT_U;
uint32_t FUSE_SKU_BOND_OUT_V;
uint32_t FUSE_SKU_BOND_OUT_W;
uint32_t FUSE_OPT_SAMPLE_TYPE;
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 FUSE_OPT_SW_RESERVED_0;
uint32_t FUSE_OPT_SW_RESERVED_1;
uint32_t FUSE_TSENSOR4_CALIB;
uint32_t FUSE_TSENSOR5_CALIB;
uint32_t FUSE_TSENSOR6_CALIB;
uint32_t FUSE_TSENSOR7_CALIB;
uint32_t FUSE_OPT_PRIV_SEC_EN;
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 FUSE_FUSE2TSEC_DEBUG_DISABLE;
uint32_t _0x17C;
uint32_t FUSE_TSENSOR_COMMON;
uint32_t FUSE_OPT_CP_BIN;
uint32_t FUSE_OPT_GPU_DISABLE;
uint32_t FUSE_OPT_FT_BIN;
uint32_t FUSE_OPT_DONE_MAP;
uint32_t _0x184;
uint32_t _0x188;
uint32_t _0x18C;
uint32_t _0x190;
uint32_t _0x194;
uint32_t FUSE_APB2JTAG_DISABLE;
uint32_t FUSE_ODM_INFO;
uint32_t _0x198;
uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
uint32_t _0x1A0;
uint32_t _0x1A4;
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
uint32_t _0x1A8;
uint32_t _0x1AC;
uint32_t _0x1B0;
uint32_t _0x1B4;
uint32_t _0x1B8;
uint32_t _0x1BC;
uint32_t FUSE_WOA_SKU_FLAG;
uint32_t FUSE_ECO_RESERVE_1;
uint32_t FUSE_GCPLEX_CONFIG_FUSE;
uint32_t FUSE_PRODUCTION_MONTH;
uint32_t FUSE_RAM_REPAIR_INDICATOR;
uint32_t FUSE_TSENSOR9_CALIB;
uint32_t _0x1D0;
uint32_t FUSE_TSENSOR_8;
uint32_t _0x1D8;
uint32_t FUSE_VMIN_CALIBRATION;
uint32_t FUSE_AGING_SENSOR_CALIBRATION;
uint32_t FUSE_DEBUG_AUTHENTICATION;
uint32_t FUSE_SECURE_PROVISION_INDEX;
uint32_t FUSE_SECURE_PROVISION_INFO;
uint32_t FUSE_OPT_GPU_DISABLE_CP1;
uint32_t FUSE_SPARE_ENDIS;
uint32_t FUSE_ECO_RESERVE_0;
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_CALIB0;
uint32_t FUSE_RESERVED_CALIB1;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1;
uint32_t FUSE_OPT_CPU_DISABLE;
uint32_t FUSE_OPT_CPU_DISABLE_CP1;
uint32_t FUSE_TSENSOR10_CALIB;
uint32_t FUSE_TSENSOR10_CALIB_AUX;
uint32_t FUSE_OPT_RAM_SVOP_DP;
uint32_t FUSE_OPT_RAM_SVOP_PDP;
uint32_t FUSE_OPT_RAM_SVOP_REG;
uint32_t FUSE_OPT_RAM_SVOP_SP;
uint32_t FUSE_OPT_RAM_SVOP_SMPDP;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2;
uint32_t FUSE_OPT_CPU_DISABLE_CP2;
uint32_t FUSE_OPT_GPU_DISABLE_CP2;
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 FUSE_RESERVED_FIELD;
uint32_t FUSE_OPT_ECC_EN;
uint32_t _0x254;
uint32_t _0x258;
uint32_t _0x25C;
uint32_t _0x260;
uint32_t _0x264;
@@ -192,12 +179,12 @@ typedef struct {
uint32_t _0x270;
uint32_t _0x274;
uint32_t _0x278;
uint32_t FUSE_SPARE_REALIGNMENT_REG;
uint32_t _0x27C;
uint32_t FUSE_SPARE_BIT[0x20];
} tegra_fuse_chip_t;
} fuse_chip_registers_t;
#define FUSE_REGS ((volatile tegra_fuse_t *)(0x7000F800))
#define FUSE_CHIP_REGS ((volatile tegra_fuse_chip_t *)(0x7000F900))
#define FUSE_REGS ((volatile fuse_registers_t *)(0x7000F800))
#define FUSE_CHIP_REGS ((volatile fuse_chip_registers_t *)(0x7000F900))
#define MAKE_FUSE_REG(n) MAKE_REG32(0x7000F800 + n)
@@ -207,7 +194,9 @@ typedef struct {
} fuse_bypass_data_t;
bool fuse_check_downgrade_status(void);
void fuse_configure_fuse_bypass(void);
void fuse_disable_programming(void);
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -23,26 +23,26 @@
#include "pmc.h"
void misc_configure_device_dbg_settings(void) {
/* Set APB_MISC_PP_CONFIG_CTL_TBE (enables RTCK daisy-chaining). */
/* Enable RTCK daisychaining by setting TBE bit. */
APB_MISC_PP_CONFIG_CTL_0 = 0x80;
/* Configure JTAG and debug bits. */
/* Literally none of this is documented in the TRM, lol. */
if (FUSE_CHIP_REGS->FUSE_SECURITY_MODE == 1) {
uint32_t secure_boot_val = 0b0100; /* Set NIDEN for aarch64. */
uint32_t pp_config_ctl_val = 0x40; /* Set APB_MISC_PP_CONFIG_CTL_JTAG. */
uint32_t secure_boot_val = 0b0100; /* Sets NIDEN for aarch64. */
uint32_t misc_val = 0x40;
if (APBDEV_PMC_STICKY_BITS_0 & 0x40) {
pp_config_ctl_val = 0x0;
misc_val = 0x0;
} else {
secure_boot_val = 0b1101; /* Set SPNIDEN, NIDEN, DBGEN for aarch64. */
secure_boot_val = 0b1101; /* Sets SPNIDEN, NIDEN, DBGEN for aarch64. */
}
SB_PFCFG_0 = (SB_PFCFG_0 & ~0b1111) | secure_boot_val; /* Configure debug bits. */
APB_MISC_PP_CONFIG_CTL_0 |= pp_config_ctl_val; /* Configure JTAG. */
SB_PFCFG_0 = (SB_PFCFG_0 & ~0b1111) | secure_boot_val; /* Configures debug bits. */
APB_MISC_PP_CONFIG_CTL_0 |= misc_val; /* Undocumented, seems to control invasive debugging/JTAG. */
}
/* Set HDA_LPBK_DIS if FUSE_SECURITY_MODE is set (disables HDA codec loopback). */
/* Set sticky bits based SECURITY_MODE. */
APBDEV_PMC_STICKY_BITS_0 |= FUSE_CHIP_REGS->FUSE_SECURITY_MODE;
/* Set E_INPUT in PINMUX_AUX_GPIO_PA6_0 (needed by the XUSB and SATA controllers). */
/* Set E_INPUT in PINMUX_AUX_GPIO_PA6_0 */
PINMUX_AUX_GPIO_PA6_0 |= 0x40;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -26,14 +26,17 @@
#define MAKE_MISC_REG(n) MAKE_REG32(MISC_BASE + n)
#define APB_MISC_PP_CONFIG_CTL_0 MAKE_MISC_REG(0x024)
#define APB_MISC_GP_ASDBGREG_0 MAKE_MISC_REG(0x810)
#define PINMUX_AUX_PWR_I2C_SCL_0 MAKE_MISC_REG(0x30DC)
#define PINMUX_AUX_PWR_I2C_SDA_0 MAKE_MISC_REG(0x30E0)
#define PINMUX_AUX_DVFS_PWM_0 MAKE_MISC_REG(0x3184)
#define PINMUX_AUX_GPIO_PA6_0 MAKE_MISC_REG(0x3244)
void misc_configure_device_dbg_settings(void);
void misc_restore_ram_svop(void);
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -23,35 +23,47 @@
#define MAKE_PMC_REG(ofs) (MAKE_REG32(PMC_BASE + ofs))
#define APBDEV_PMC_CNTRL_0 MAKE_PMC_REG(0x000)
#define APBDEV_PMC_DPD_SAMPLE_0 MAKE_PMC_REG(0x020)
#define APBDEV_PMC_DPD_ENABLE_0 MAKE_PMC_REG(0x024)
#define APBDEV_PMC_CLAMP_STATUS_0 MAKE_PMC_REG(0x02C)
#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x030)
#define APBDEV_PMC_REMOVE_CLAMPING_CMD_0 MAKE_PMC_REG(0x034)
#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x038)
#define APBDEV_PMC_SCRATCH12_0 MAKE_PMC_REG(0x080)
#define APBDEV_PMC_SCRATCH13_0 MAKE_PMC_REG(0x084)
#define APBDEV_PMC_SCRATCH18_0 MAKE_PMC_REG(0x098)
#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818)
#define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4)
#define APBDEV_PMC_STICKY_BITS_0 MAKE_PMC_REG(0x2C0)
#define APBDEV_PMC_SEC_DISABLE2_0 MAKE_PMC_REG(0x2C4)
#define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8)
#define APBDEV_PMC_SECURE_SCRATCH21_0 MAKE_PMC_REG(0x334)
#define APBDEV_PMC_SECURE_SCRATCH32_0 MAKE_PMC_REG(0x360)
#define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_PMC_REG(0x368)
#define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_PMC_REG(0x36C)
#define APBDEV_PMC_SECURE_SCRATCH112_0 MAKE_PMC_REG(0xB18)
#define APBDEV_PMC_SECURE_SCRATCH113_0 MAKE_PMC_REG(0xB1C)
#define APBDEV_PMC_SECURE_SCRATCH114_0 MAKE_PMC_REG(0xB20)
#define APBDEV_PMC_SECURE_SCRATCH115_0 MAKE_PMC_REG(0xB24)
#define APBDEV_PMC_FUSE_CTRL MAKE_PMC_REG(0x450)
#define APBDEV_PMC_IO_DPD3_REQ_0 MAKE_PMC_REG(0x45C)
#define APBDEV_PMC_IO_DPD3_STATUS_0 MAKE_PMC_REG(0x460)
#define APBDEV_PMC_IO_DPD4_REQ_0 MAKE_PMC_REG(0x464)
#define APBDEV_PMC_IO_DPD4_STATUS_0 MAKE_PMC_REG(0x468)
#define APBDEV_PMC_SET_SW_CLAMP_0 MAKE_PMC_REG(0x47C)
#define APBDEV_PMC_DDR_CNTRL_0 MAKE_PMC_REG(0x4E4)
#define APBDEV_PMC_CNTRL_0 MAKE_PMC_REG(0x000)
#define APBDEV_PMC_DPD_SAMPLE_0 MAKE_PMC_REG(0x020)
#define APBDEV_PMC_DPD_ENABLE_0 MAKE_PMC_REG(0x024)
#define APBDEV_PMC_CLAMP_STATUS_0 MAKE_PMC_REG(0x02C)
#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x030)
#define APBDEV_PMC_REMOVE_CLAMPING_CMD_0 MAKE_PMC_REG(0x034)
#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x038)
#define APBDEV_PMC_SCRATCH12_0 MAKE_PMC_REG(0x080)
#define APBDEV_PMC_SCRATCH13_0 MAKE_PMC_REG(0x084)
#define APBDEV_PMC_SCRATCH18_0 MAKE_PMC_REG(0x098)
#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818)
#define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4)
#define APBDEV_PMC_STICKY_BITS_0 MAKE_PMC_REG(0x2C0)
#define APBDEV_PMC_SEC_DISABLE2_0 MAKE_PMC_REG(0x2C4)
#define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8)
#define APBDEV_PMC_SECURE_SCRATCH21_0 MAKE_PMC_REG(0x334)
#define APBDEV_PMC_SECURE_SCRATCH32_0 MAKE_PMC_REG(0x360)
#define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_PMC_REG(0x368)
#define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_PMC_REG(0x36C)
#define APBDEV_PMC_SECURE_SCRATCH112_0 MAKE_PMC_REG(0xB18)
#define APBDEV_PMC_SECURE_SCRATCH113_0 MAKE_PMC_REG(0xB1C)
#define APBDEV_PMC_SECURE_SCRATCH114_0 MAKE_PMC_REG(0xB20)
#define APBDEV_PMC_SECURE_SCRATCH115_0 MAKE_PMC_REG(0xB24)
#define APBDEV_PMC_IO_DPD3_REQ_0 MAKE_PMC_REG(0x45C)
#define APBDEV_PMC_IO_DPD3_STATUS_0 MAKE_PMC_REG(0x460)
#define APBDEV_PMC_IO_DPD4_REQ_0 MAKE_PMC_REG(0x464)
#define APBDEV_PMC_IO_DPD4_STATUS_0 MAKE_PMC_REG(0x468)
#define APBDEV_PMC_SET_SW_CLAMP_0 MAKE_PMC_REG(0x47C)
#define APBDEV_PMC_DDR_CNTRL_0 MAKE_PMC_REG(0x4E4)
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -36,20 +36,20 @@ static void __attribute__((__noinline__)) ll_init(volatile se_ll_t *ll, void *bu
}
void se_check_error_status_reg(void) {
if (se_get_regs()->SE_ERR_STATUS) {
if (se_get_regs()->ERR_STATUS_REG) {
reboot();
}
}
void se_check_for_error(void) {
volatile tegra_se_t *se = se_get_regs();
if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) {
if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) {
reboot();
}
}
void se_verify_flags_cleared(void) {
if (se_get_regs()->SE_STATUS & 3) {
if (se_get_regs()->FLAGS_REG & 3) {
reboot();
}
}
@@ -63,8 +63,8 @@ void clear_aes_keyslot(unsigned int keyslot) {
/* Zero out the whole keyslot and IV. */
for (unsigned int i = 0; i < 0x10; i++) {
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
se->SE_CRYPTO_KEYTABLE_DATA = 0;
se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
se->AES_KEYTABLE_DATA = 0;
}
}
@@ -78,13 +78,13 @@ void clear_rsa_keyslot(unsigned int keyslot) {
/* Zero out the whole keyslot. */
for (unsigned int i = 0; i < 0x40; i++) {
/* Select Keyslot Modulus[i] */
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
se->SE_RSA_KEYTABLE_DATA = 0;
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
se->RSA_KEYTABLE_DATA = 0;
}
for (unsigned int i = 0; i < 0x40; i++) {
/* Select Keyslot Expontent[i] */
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
se->SE_RSA_KEYTABLE_DATA = 0;
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
se->RSA_KEYTABLE_DATA = 0;
}
}
@@ -96,8 +96,8 @@ void clear_aes_keyslot_iv(unsigned int keyslot) {
}
for (size_t i = 0; i < (0x10 >> 2); i++) {
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
se->SE_CRYPTO_KEYTABLE_DATA = 0;
se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
se->AES_KEYTABLE_DATA = 0;
}
}
@@ -111,15 +111,15 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v
ll_init(&out_ll, dst, dst_size);
/* Set the LLs. */
se->SE_IN_LL_ADDR = (uint32_t)(&in_ll);
se->SE_OUT_LL_ADDR = (uint32_t) (&out_ll);
se->IN_LL_ADDR_REG = (uint32_t)(&in_ll);
se->OUT_LL_ADDR_REG = (uint32_t) (&out_ll);
/* Set registers for operation. */
se->SE_ERR_STATUS = se->SE_ERR_STATUS;
se->SE_INT_STATUS = se->SE_INT_STATUS;
se->SE_OPERATION = op;
se->ERR_STATUS_REG = se->ERR_STATUS_REG;
se->INT_STATUS_REG = se->INT_STATUS_REG;
se->OPERATION_REG = op;
while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ }
while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
se_check_for_error();
}
@@ -137,7 +137,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src,
}
/* Trigger AES operation. */
se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0;
se_get_regs()->BLOCK_COUNT_REG = 0;
trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
/* Copy output data into dst. */
@@ -154,8 +154,8 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size,
}
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100;
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
se->CRYPTO_REG = keyslot << 24 | 0x100;
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
}
@@ -166,8 +166,8 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size,
reboot();
}
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY);
se->SE_CRYPTO_CONFIG = keyslot << 24;
se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
se->CRYPTO_REG = keyslot << 24;
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
}
@@ -198,16 +198,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
shift_left_xor_rb(derived_key);
}
se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145);
se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
se->CRYPTO_REG = (keyslot << 24) | (0x145);
clear_aes_keyslot_iv(keyslot);
unsigned int num_blocks = (data_size + 0xF) >> 4;
/* Handle aligned blocks. */
if (num_blocks > 1) {
se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2;
se->BLOCK_COUNT_REG = num_blocks - 2;
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
se->SE_CRYPTO_CONFIG |= 0x80;
se->CRYPTO_REG |= 0x80;
}
/* Create final block. */
@@ -224,12 +224,12 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
}
/* Perform last operation. */
se->SE_CRYPTO_LAST_BLOCK = 0;
se->BLOCK_COUNT_REG = 0;
trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
/* Copy output CMAC. */
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
((uint32_t *)cmac)[i] = ((volatile uint32_t *)se->SE_HASH_RESULT)[i];
((uint32_t *)cmac)[i] = ((volatile uint32_t *)se->HASH_RESULT_REG)[i];
}
}
@@ -244,9 +244,9 @@ void se_aes_256_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, co
reboot();
}
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY) | (0x202 << 16);
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x66;
se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY) | (0x202 << 16);
se->CRYPTO_REG = (keyslot << 24) | 0x66;
clear_aes_keyslot_iv(keyslot);
se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1;
se->BLOCK_COUNT_REG = (src_size >> 4) - 1;
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -92,59 +92,71 @@
#define RSA_2048_BYTES 0x100
typedef struct {
uint32_t SE_SE_SECURITY;
uint32_t SE_TZRAM_SECURITY;
uint32_t SE_OPERATION;
uint32_t SE_INT_ENABLE;
uint32_t SE_INT_STATUS;
uint32_t SE_CONFIG;
uint32_t SE_IN_LL_ADDR;
uint32_t SE_IN_CUR_BYTE_ADDR;
uint32_t SE_IN_CUR_LL_ID;
uint32_t SE_OUT_LL_ADDR;
uint32_t SE_OUT_CUR_BYTE_ADDR;
uint32_t SE_OUT_CUR_LL_ID;
uint32_t SE_HASH_RESULT[0x10];
uint32_t SE_CTX_SAVE_CONFIG;
uint32_t _0x74[0x63];
uint32_t SE_SHA_CONFIG;
uint32_t SE_SHA_MSG_LENGTH[0x4];
uint32_t SE_SHA_MSG_LEFT[0x4];
uint32_t _0x224[0x17];
uint32_t SE_CRYPTO_SECURITY_PERKEY;
uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10];
uint32_t _0x2C4[0x10];
uint32_t SE_CRYPTO_CONFIG;
uint32_t SE_CRYPTO_LINEAR_CTR[0x4];
uint32_t SE_CRYPTO_LAST_BLOCK;
uint32_t SE_CRYPTO_KEYTABLE_ADDR;
uint32_t SE_CRYPTO_KEYTABLE_DATA;
uint32_t _0x324[0x3];
uint32_t SE_CRYPTO_KEYTABLE_DST;
uint32_t _0x334[0x3];
uint32_t SE_RNG_CONFIG;
uint32_t SE_RNG_SRC_CONFIG;
uint32_t SE_RNG_RESEED_INTERVAL;
uint32_t _0x34C[0x2D];
uint32_t SE_RSA_CONFIG;
uint32_t SE_RSA_KEY_SIZE;
uint32_t SE_RSA_EXP_SIZE;
uint32_t SE_RSA_SECURITY_PERKEY;
uint32_t SE_RSA_KEYTABLE_ACCESS[0x2];
uint32_t _0x418[0x2];
uint32_t SE_RSA_KEYTABLE_ADDR;
uint32_t SE_RSA_KEYTABLE_DATA;
uint32_t SE_RSA_OUTPUT[0x40];
uint32_t _0x528[0xB6];
uint32_t SE_STATUS;
uint32_t SE_ERR_STATUS;
uint32_t SE_MISC;
uint32_t SE_SPARE;
uint32_t SE_ENTROPY_DEBUG_COUNTER;
uint32_t _0x0;
uint32_t _0x4;
uint32_t OPERATION_REG;
uint32_t INT_ENABLE_REG;
uint32_t INT_STATUS_REG;
uint32_t CONFIG_REG;
uint32_t IN_LL_ADDR_REG;
uint32_t _0x1C;
uint32_t _0x20;
uint32_t OUT_LL_ADDR_REG;
uint32_t _0x28;
uint32_t _0x2C;
uint8_t HASH_RESULT_REG[0x20];
uint8_t _0x50[0x20];
uint32_t CONTEXT_SAVE_CONFIG_REG;
uint8_t _0x74[0x18C];
uint32_t SHA_CONFIG_REG;
uint32_t SHA_MSG_LENGTH_REG;
uint32_t _0x208;
uint32_t _0x20C;
uint32_t _0x210;
uint32_t SHA_MSG_LEFT_REG;
uint32_t _0x218;
uint32_t _0x21C;
uint32_t _0x220;
uint32_t _0x224;
uint8_t _0x228[0x58];
uint32_t AES_KEY_READ_DISABLE_REG;
uint32_t AES_KEYSLOT_FLAGS[0x10];
uint8_t _0x2C4[0x3C];
uint32_t _0x300;
uint32_t CRYPTO_REG;
uint32_t CRYPTO_CTR_REG[4];
uint32_t BLOCK_COUNT_REG;
uint32_t AES_KEYTABLE_ADDR;
uint32_t AES_KEYTABLE_DATA;
uint32_t _0x324;
uint32_t _0x328;
uint32_t _0x32C;
uint32_t CRYPTO_KEYTABLE_DST_REG;
uint8_t _0x334[0xC];
uint32_t RNG_CONFIG_REG;
uint32_t RNG_SRC_CONFIG_REG;
uint32_t RNG_RESEED_INTERVAL_REG;
uint8_t _0x34C[0xB4];
uint32_t RSA_CONFIG;
uint32_t RSA_KEY_SIZE_REG;
uint32_t RSA_EXP_SIZE_REG;
uint32_t RSA_KEY_READ_DISABLE_REG;
uint32_t RSA_KEYSLOT_FLAGS[2];
uint32_t _0x418;
uint32_t _0x41C;
uint32_t RSA_KEYTABLE_ADDR;
uint32_t RSA_KEYTABLE_DATA;
uint8_t RSA_OUTPUT[0x100];
uint8_t _0x528[0x2D8];
uint32_t FLAGS_REG;
uint32_t ERR_STATUS_REG;
uint32_t _0x808;
uint32_t SPARE_0;
uint32_t _0x810;
uint32_t _0x814;
uint32_t _0x818;
uint32_t _0x81C;
uint32_t _0x820[0x5F8];
uint8_t _0x820[0x17E0];
} tegra_se_t;
typedef struct {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -46,7 +46,7 @@ void secmon_restore_to_tzram(const uint32_t target_firmware) {
}
/* Make security engine require secure busmaster. */
se_get_regs()->SE_TZRAM_SECURITY = 0;
se_get_regs()->_0x4 = 0;
/* TODO: se_verify_keys_unreadable(); */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -2,7 +2,7 @@
* Defining registers address and its bit definitions of MAX77620 and MAX20024
*
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -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 "utils.h"
@@ -30,7 +30,7 @@ static inline uint32_t get_special_clk_reg(CarDevice dev) {
case CARDEVICE_BPMP: return 0;
default: generic_panic();
}
}
}
static inline uint32_t get_special_clk_val(CarDevice dev) {
switch (dev) {
@@ -45,7 +45,7 @@ static inline uint32_t get_special_clk_val(CarDevice dev) {
}
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};
static uint32_t g_rst_reg_offsets[NUM_CAR_BANKS] = {0x004, 0x008, 0x00C, 0x358, 0x35C, 0x28C, 0x2A4};
void clk_enable(CarDevice dev) {
uint32_t special_reg;
@@ -67,6 +67,7 @@ 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);
@@ -81,7 +82,3 @@ void clkrst_reboot(CarDevice dev) {
clkrst_disable(dev);
clkrst_enable(dev);
}
void clkrst_enable_fuse_regs(bool enable) {
CLK_RST_CONTROLLER_MISC_CLK_ENB_0 = ((CLK_RST_CONTROLLER_MISC_CLK_ENB_0 & 0xEFFFFFFF) | ((enable & 1) << 28));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -51,8 +51,7 @@ 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -187,10 +187,11 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
*p_outvalue = INTERRUPT_ID_USER_SECURITY_ENGINE;
break;
case CONFIGITEM_VERSION:
*p_outvalue = fuse_get_expected_fuse_version(exosphere_get_target_firmware());
/* Always returns maxver - 1 on hardware. */
*p_outvalue = PACKAGE2_MAXVER_400_410 - 1;
break;
case CONFIGITEM_HARDWARETYPE:
*p_outvalue = fuse_get_hardware_type(exosphere_get_target_firmware());
*p_outvalue = fuse_get_hardware_type();
break;
case CONFIGITEM_ISRETAIL:
*p_outvalue = fuse_get_retail_type();
@@ -290,15 +291,7 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
break;
case CONFIGITEM_HAS_RCM_BUG_PATCH:
/* UNOFFICIAL: Gets whether this unit has the RCM bug patched. */
*p_outvalue = (int)(fuse_has_rcm_bug_patch());
break;
case CONFIGITEM_SHOULD_BLANK_PRODINFO:
/* UNOFFICIAL: Gets whether this unit should simulate a "blanked" PRODINFO. */
*p_outvalue = exosphere_should_blank_prodinfo();
break;
case CONFIGITEM_ALLOW_CAL_WRITES:
/* UNOFFICIAL: Gets whether this unit should allow writing to the calibration partition. */
*p_outvalue = exosphere_should_allow_writing_to_cal();
*p_outvalue = (int)(fuse_has_rcm_bug_patch());;
break;
default:
result = 2;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -45,8 +45,6 @@ typedef enum {
CONFIGITEM_NEEDS_SHUTDOWN = 65002,
CONFIGITEM_EXOSPHERE_VERHASH = 65003,
CONFIGITEM_HAS_RCM_BUG_PATCH = 65004,
CONFIGITEM_SHOULD_BLANK_PRODINFO = 65005,
CONFIGITEM_ALLOW_CAL_WRITES = 65006,
} ConfigItem;
#define REBOOT_KIND_NO_REBOOT 0

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -4,7 +4,7 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Declare the exception vector table, enforcing it is aligned on a
@@ -92,7 +92,7 @@ vector_entry fiq_spx
vector_entry serror_spx
b unknown_exception
check_vector_size serror_spx
/* Lower EL, A64 */
vector_entry synch_a64
stp x29, x30, [sp, #-0x10]!

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -27,9 +27,6 @@ static bool g_has_loaded_config = false;
#define EXOSPHERE_CHECK_FLAG(flag) ((g_exosphere_cfg.flags & flag) != 0)
static unsigned int exosphere_is_emummc() {
return g_exosphere_cfg.emummc_cfg.base_cfg.magic == MAGIC_EMUMMC_CONFIG && g_exosphere_cfg.emummc_cfg.base_cfg.type != EMUMMC_TYPE_NONE;
}
/* Read config out of IRAM, return target firmware version. */
unsigned int exosphere_load_config(void) {
@@ -95,26 +92,6 @@ unsigned int exosphere_should_enable_usermode_pmu_access(void) {
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS);
}
unsigned int exosphere_should_blank_prodinfo(void) {
if (!g_has_loaded_config) {
generic_panic();
}
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_BLANK_PRODINFO);
}
unsigned int exosphere_should_allow_writing_to_cal(void) {
if (!g_has_loaded_config) {
generic_panic();
}
if (exosphere_is_emummc()) {
return 1;
} else {
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC);
}
}
const exo_emummc_config_t *exosphere_get_emummc_config(void) {
if (!g_has_loaded_config) {
generic_panic();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -41,8 +41,6 @@
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
#define EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS (1 << 4u)
#define EXOSPHERE_FLAG_BLANK_PRODINFO (1 << 5u)
#define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 6u)
#define EXOSPHERE_FLAGS_DEFAULT (EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV)
typedef struct {
@@ -62,8 +60,6 @@ unsigned int exosphere_should_override_debugmode_priv(void);
unsigned int exosphere_should_override_debugmode_user(void);
unsigned int exosphere_should_disable_usermode_exception_handlers(void);
unsigned int exosphere_should_enable_usermode_pmu_access(void);
unsigned int exosphere_should_blank_prodinfo(void);
unsigned int exosphere_should_allow_writing_to_cal(void);
const exo_emummc_config_t *exosphere_get_emummc_config(void);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -13,168 +13,185 @@
* 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 <vapours/ams_version.h>
#include "car.h"
#include "fuse.h"
#include "masterkey.h"
#include "pmc.h"
#include "utils.h"
#include "timers.h"
#include "exocfg.h"
#include "masterkey.h"
static bool g_has_checked_for_rcm_bug_patch = false;
static bool g_has_rcm_bug_patch = false;
/* 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) {
/* Make all fuse registers visible, disable the private key and disable programming. */
clkrst_enable_fuse_regs(true);
fuse_disable_private_key();
/* Initialize the FUSE driver */
void fuse_init(void)
{
fuse_make_regs_visible();
fuse_secondary_private_key_disable();
fuse_disable_programming();
/* TODO: Should we allow this to be done later? */
if (!g_has_checked_for_rcm_bug_patch) {
(void)(fuse_has_rcm_bug_patch());
}
/* TODO: Overrides (iROM patches) and various reads happen here */
}
/* Disable access to the private key and set the TZ sticky bit. */
void fuse_disable_private_key(void) {
FUSE_REGS->FUSE_PRIVATEKEYDISABLE = 0x10;
/* Make all fuse registers visible */
void fuse_make_regs_visible(void)
{
CLK_RST_CONTROLLER_MISC_CLK_ENB_0 |= BIT(28);
}
/* Disables all fuse programming. */
void fuse_disable_programming(void) {
FUSE_REGS->FUSE_DISABLEREGPROGRAM = 1;
/* Enable power to the fuse hardware array */
void fuse_enable_power(void)
{
FUSE_REGS->FUSE_PWR_GOOD_SW = 1;
wait(1);
}
/* Enable power to the fuse hardware array. */
void fuse_enable_power(void) {
APBDEV_PMC_FUSE_CTRL &= ~(0x200); /* Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
mdelay(1);
APBDEV_PMC_FUSE_CTRL |= 0x100; /* Set PMC_FUSE_CTRL_PS18_LATCH_SET. */
mdelay(1);
/* Disable power to the fuse hardware array */
void fuse_disable_power(void)
{
FUSE_REGS->FUSE_PWR_GOOD_SW = 0;
wait(1);
}
/* Disable power to the fuse hardware array. */
void fuse_disable_power(void) {
APBDEV_PMC_FUSE_CTRL &= ~(0x100); /* Clear PMC_FUSE_CTRL_PS18_LATCH_SET. */
mdelay(1);
APBDEV_PMC_FUSE_CTRL |= 0x200; /* Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
mdelay(1);
}
/* Wait for the fuse driver to go idle. */
void fuse_wait_idle(void) {
/* Wait for the fuse driver to go idle */
void fuse_wait_idle(void)
{
uint32_t ctrl_val = 0;
/* Wait for STATE_IDLE */
while ((ctrl_val & (0xF0000)) != 0x40000)
ctrl_val = FUSE_REGS->FUSE_FUSECTRL;
{
wait(1);
ctrl_val = FUSE_REGS->FUSE_CTRL;
}
}
/* Read a fuse from the hardware array. */
uint32_t fuse_hw_read(uint32_t addr) {
/* Wait for idle state. */
/* Read a fuse from the hardware array */
uint32_t fuse_hw_read(uint32_t addr)
{
fuse_wait_idle();
/* Program the target address. */
FUSE_REGS->FUSE_FUSEADDR = addr;
/* Program the target address */
FUSE_REGS->FUSE_REG_ADDR = addr;
/* Enable read operation in control register. */
uint32_t ctrl_val = FUSE_REGS->FUSE_FUSECTRL;
/* Enable read operation in control register */
uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x1; /* Set READ command. */
FUSE_REGS->FUSE_FUSECTRL = ctrl_val;
ctrl_val |= 0x1; /* Set FUSE_READ command */
FUSE_REGS->FUSE_CTRL = ctrl_val;
/* Wait for idle state. */
fuse_wait_idle();
return FUSE_REGS->FUSE_FUSERDATA;
return FUSE_REGS->FUSE_REG_READ;
}
/* Write a fuse in the hardware array. */
void fuse_hw_write(uint32_t value, uint32_t addr) {
/* Wait for idle state. */
/* Write a fuse in the hardware array */
void fuse_hw_write(uint32_t value, uint32_t addr)
{
fuse_wait_idle();
/* Program the target address and value. */
FUSE_REGS->FUSE_FUSEADDR = addr;
FUSE_REGS->FUSE_FUSEWDATA = value;
/* Program the target address and value */
FUSE_REGS->FUSE_REG_ADDR = addr;
FUSE_REGS->FUSE_REG_WRITE = value;
/* Enable write operation in control register. */
uint32_t ctrl_val = FUSE_REGS->FUSE_FUSECTRL;
/* Enable write operation in control register */
uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x2; /* Set WRITE command. */
FUSE_REGS->FUSE_FUSECTRL = ctrl_val;
ctrl_val |= 0x2; /* Set FUSE_WRITE command */
FUSE_REGS->FUSE_CTRL = ctrl_val;
/* Wait for idle state. */
fuse_wait_idle();
}
/* Sense the fuse hardware array into the shadow cache. */
void fuse_hw_sense(void) {
/* Wait for idle state. */
/* Sense the fuse hardware array into the shadow cache */
void fuse_hw_sense(void)
{
fuse_wait_idle();
/* Enable sense operation in control register */
uint32_t ctrl_val = FUSE_REGS->FUSE_FUSECTRL;
uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
FUSE_REGS->FUSE_FUSECTRL = ctrl_val;
ctrl_val |= 0x3; /* Set FUSE_SENSE command */
FUSE_REGS->FUSE_CTRL = ctrl_val;
/* Wait for idle state. */
fuse_wait_idle();
}
/* Read the SKU info register from the shadow cache. */
uint32_t fuse_get_sku_info(void) {
/* Disables all fuse programming. */
void fuse_disable_programming(void) {
FUSE_REGS->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) {
FUSE_REGS->FUSE_PRIVATEKEYDISABLE = 0x10;
}
/* Read the SKU info register from the shadow cache */
uint32_t fuse_get_sku_info(void)
{
return FUSE_CHIP_REGS->FUSE_SKU_INFO;
}
/* Read the bootrom patch version from a register in the shadow cache. */
uint32_t fuse_get_bootrom_patch_version(void) {
return FUSE_CHIP_REGS->FUSE_SOC_SPEEDO_1_CALIB;
/* Read the bootrom patch version from a register in the shadow cache */
uint32_t fuse_get_bootrom_patch_version(void)
{
return FUSE_CHIP_REGS->FUSE_SOC_SPEEDO_1;
}
/* Read a spare bit register from the shadow cache */
uint32_t fuse_get_spare_bit(uint32_t idx) {
if (idx < 32) {
return FUSE_CHIP_REGS->FUSE_SPARE_BIT[idx];
uint32_t fuse_get_spare_bit(uint32_t idx)
{
if (idx >= 32) {
return 0;
}
return FUSE_CHIP_REGS->FUSE_SPARE_BIT[idx];
}
/* Read a reserved ODM register from the shadow cache */
uint32_t fuse_get_reserved_odm(uint32_t idx)
{
if (idx >= 8) {
return 0;
}
return FUSE_CHIP_REGS->FUSE_RESERVED_ODM[idx];
}
uint32_t fuse_get_5x_key_generation(void) {
if ((fuse_get_reserved_odm(4) & 0x800) && fuse_get_reserved_odm(0) == 0x8E61ECAE && fuse_get_reserved_odm(1) == 0xF2BA3BB2) {
return fuse_get_reserved_odm(2) & 0x1F;
} else {
return 0;
}
}
/* Read a reserved ODM register from the shadow cache. */
uint32_t fuse_get_reserved_odm(uint32_t idx) {
if (idx < 8) {
return FUSE_CHIP_REGS->FUSE_RESERVED_ODM[idx];
} else {
return 0;
}
}
/* Get the DRAM ID using values in the shadow cache. */
uint32_t fuse_get_dram_id(void) {
return ((fuse_get_reserved_odm(4) >> 3) & 0x7);
}
/* Derive the Device ID using values in the shadow cache. */
/* Derive the Device ID using values in the shadow cache */
uint64_t fuse_get_device_id(void) {
uint64_t device_id = 0;
uint64_t y_coord = FUSE_CHIP_REGS->FUSE_OPT_Y_COORDINATE & 0x1FF;
uint64_t x_coord = FUSE_CHIP_REGS->FUSE_OPT_X_COORDINATE & 0x1FF;
uint64_t wafer_id = FUSE_CHIP_REGS->FUSE_OPT_WAFER_ID & 0x3F;
uint32_t lot_code = FUSE_CHIP_REGS->FUSE_OPT_LOT_CODE_0;
uint64_t fab_code = FUSE_CHIP_REGS->FUSE_OPT_FAB_CODE & 0x3F;
uint64_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF;
uint64_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF;
uint64_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F;
uint32_t lot_code = FUSE_CHIP_REGS->FUSE_LOT_CODE_0;
uint64_t fab_code = FUSE_CHIP_REGS->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);
@@ -186,41 +203,40 @@ uint64_t fuse_get_device_id(void) {
device_id |= wafer_id << 18;
device_id |= derived_lot_code << 24;
device_id |= fab_code << 50;
return device_id;
}
/* Derive the Hardware Type using values in the shadow cache. */
uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
/* Get the DRAM ID using values in the shadow cache */
uint32_t fuse_get_dram_id(void) {
return (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 3) & 0x7;
}
/* Firmware from versions 1.0.0 to 3.0.2. */
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
/* Derive the Hardware Type using values in the shadow cache */
uint32_t fuse_get_hardware_type(void) {
/* This function is very different between 4.x and < 4.x */
uint32_t hardware_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 2) & 1);
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
static const uint32_t types[] = {0,1,4,3};
hardware_type |= (FUSE_CHIP_REGS->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 hardware_type > 2 ? 3 : hardware_type - 1;
} else if ((FUSE_CHIP_REGS->FUSE_SPARE_BIT[9] & 1) == 0) {
return 0;
} else {
return 3;
}
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
static const uint32_t types[] = {0,1,4,3};
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
hardware_type--;
return (hardware_type > 3) ? 4 : types[hardware_type];
} else { /* Firmware versions from 7.0.0 onwards. */
/* Always return 0 in retail. */
return 0;
}
}
/* Derive the Retail Type using values in the shadow cache. */
/* Derive the Retail Type using values in the shadow cache */
uint32_t fuse_get_retail_type(void) {
/* Retail Type = IS_RETAIL | UNIT_TYPE. */
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
uint32_t retail_type = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3));
/* Retail type = IS_RETAIL | UNIT_TYPE */
uint32_t retail_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 4) | (FUSE_CHIP_REGS->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. */
@@ -233,17 +249,17 @@ uint32_t fuse_get_retail_type(void) {
void fuse_get_hardware_info(void *dst) {
uint32_t hw_info[0x4];
uint32_t ops_reserved = FUSE_CHIP_REGS->FUSE_OPT_OPS_RESERVED & 0x3F;
uint32_t y_coord = FUSE_CHIP_REGS->FUSE_OPT_Y_COORDINATE & 0x1FF;
uint32_t x_coord = FUSE_CHIP_REGS->FUSE_OPT_X_COORDINATE & 0x1FF;
uint32_t wafer_id = FUSE_CHIP_REGS->FUSE_OPT_WAFER_ID & 0x3F;
uint32_t lot_code_0 = FUSE_CHIP_REGS->FUSE_OPT_LOT_CODE_0;
uint32_t lot_code_1 = FUSE_CHIP_REGS->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF;
uint32_t fab_code = FUSE_CHIP_REGS->FUSE_OPT_FAB_CODE & 0x3F;
uint32_t vendor_code = FUSE_CHIP_REGS->FUSE_OPT_VENDOR_CODE & 0xF;
uint32_t unk_hw_fuse = FUSE_CHIP_REGS->_0x120 & 0x3F;
uint32_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF;
uint32_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF;
uint32_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F;
uint32_t lot_code_0 = FUSE_CHIP_REGS->FUSE_LOT_CODE_0;
uint32_t lot_code_1 = FUSE_CHIP_REGS->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
uint32_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F;
uint32_t vendor_code = FUSE_CHIP_REGS->FUSE_VENDOR_CODE & 0xF;
/* Hardware Info = OPS_RESERVED || 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) | (ops_reserved));
/* 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);
@@ -251,53 +267,15 @@ void fuse_get_hardware_info(void *dst) {
memcpy(dst, hw_info, 0x10);
}
/* Get the Key Generation value. */
uint32_t fuse_get_5x_key_generation(void) {
if ((fuse_get_reserved_odm(4) & 0x800) && (fuse_get_reserved_odm(0) == 0x8E61ECAE) && (fuse_get_reserved_odm(1) == 0xF2BA3BB2)) {
return (fuse_get_reserved_odm(2) & 0x1F);
} else {
return 0;
}
}
/* Returns the fuse version expected for the firmware. */
uint32_t fuse_get_expected_fuse_version(uint32_t target_firmware) {
static const uint8_t expected_versions[ATMOSPHERE_TARGET_FIRMWARE_COUNT+1] = {
[ATMOSPHERE_TARGET_FIRMWARE_100] = 1,
[ATMOSPHERE_TARGET_FIRMWARE_200] = 2,
[ATMOSPHERE_TARGET_FIRMWARE_300] = 3,
/* [ATMOSPHERE_TARGET_FIRMWARE_302] = 4, */
[ATMOSPHERE_TARGET_FIRMWARE_400] = 5,
[ATMOSPHERE_TARGET_FIRMWARE_500] = 6,
[ATMOSPHERE_TARGET_FIRMWARE_600] = 7,
[ATMOSPHERE_TARGET_FIRMWARE_620] = 8,
[ATMOSPHERE_TARGET_FIRMWARE_700] = 9,
[ATMOSPHERE_TARGET_FIRMWARE_800] = 9,
[ATMOSPHERE_TARGET_FIRMWARE_810] = 10,
[ATMOSPHERE_TARGET_FIRMWARE_900] = 11,
[ATMOSPHERE_TARGET_FIRMWARE_910] = 12,
[ATMOSPHERE_TARGET_FIRMWARE_1000] = 13,
};
if (target_firmware > ATMOSPHERE_TARGET_FIRMWARE_COUNT) {
generic_panic();
}
if (fuse_get_retail_type() != 0)
return expected_versions[target_firmware];
else
return (target_firmware > ATMOSPHERE_TARGET_FIRMWARE_200) ? 1 : 0;
}
/* Check for RCM bug patches. */
bool fuse_has_rcm_bug_patch(void) {
/* Only check for RCM bug patch once, and cache our result. */
if (!g_has_checked_for_rcm_bug_patch) {
/* Some patched units use XUSB in RCM. */
/* Patched units have this bit set in reserved_sw, according to reports. */
if (FUSE_CHIP_REGS->FUSE_RESERVED_SW & 0x80) {
g_has_rcm_bug_patch = true;
}
/* Other units have a proper ipatch instead. */
/* Also check for an ipatch. */
{
uint32_t word_count = FUSE_CHIP_REGS->FUSE_FIRST_BOOTROM_PATCH_SIZE & 0x7f;
uint32_t word_addr = 191;
@@ -323,4 +301,4 @@ bool fuse_has_rcm_bug_patch(void) {
g_has_checked_for_rcm_bug_patch = true;
return g_has_rcm_bug_patch;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -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_FUSE_H
#define EXOSPHERE_FUSE_H
@@ -24,167 +24,154 @@
/* Exosphere driver for the Tegra X1 FUSE registers. */
typedef struct {
uint32_t FUSE_FUSECTRL;
uint32_t FUSE_FUSEADDR;
uint32_t FUSE_FUSERDATA;
uint32_t FUSE_FUSEWDATA;
uint32_t FUSE_FUSETIME_RD1;
uint32_t FUSE_FUSETIME_RD2;
uint32_t FUSE_FUSETIME_PGM1;
uint32_t FUSE_FUSETIME_PGM2;
uint32_t FUSE_PRIV2INTFC_START;
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_DISABLEREGPROGRAM;
uint32_t FUSE_WRITE_ACCESS_SW;
uint32_t FUSE_DIS_PGM;
uint32_t FUSE_WRITE_ACCESS;
uint32_t FUSE_PWR_GOOD_SW;
uint32_t _0x38;
uint32_t FUSE_PRIV2RESHIFT;
uint32_t _0x40[0x3];
uint32_t FUSE_FUSETIME_RD3;
uint32_t _0x50[0xC];
uint32_t FUSE_PRIVATE_KEY0_NONZERO;
uint32_t FUSE_PRIVATE_KEY1_NONZERO;
uint32_t FUSE_PRIVATE_KEY2_NONZERO;
uint32_t FUSE_PRIVATE_KEY3_NONZERO;
uint32_t FUSE_PRIVATE_KEY4_NONZERO;
uint32_t _0x90[0x1C];
} tegra_fuse_t;
uint32_t _0x38[0x32];
} fuse_registers_t;
typedef struct {
uint32_t FUSE_PRODUCTION_MODE;
uint32_t FUSE_JTAG_SECUREID_VALID;
uint32_t FUSE_ODM_LOCK;
uint32_t FUSE_OPT_OPENGL_EN;
uint32_t _0x4;
uint32_t _0x8;
uint32_t _0xC;
uint32_t FUSE_SKU_INFO;
uint32_t FUSE_CPU_SPEEDO_0_CALIB;
uint32_t FUSE_CPU_IDDQ_CALIB;
uint32_t FUSE_DAC_CRT_CALIB;
uint32_t FUSE_DAC_HDTV_CALIB;
uint32_t FUSE_DAC_SDTV_CALIB;
uint32_t FUSE_OPT_FT_REV;
uint32_t FUSE_CPU_SPEEDO_1_CALIB;
uint32_t FUSE_CPU_SPEEDO_2_CALIB;
uint32_t FUSE_SOC_SPEEDO_0_CALIB;
uint32_t FUSE_SOC_SPEEDO_1_CALIB;
uint32_t FUSE_SOC_SPEEDO_2_CALIB;
uint32_t FUSE_SOC_IDDQ_CALIB;
uint32_t FUSE_RESERVED_PRODUCTION_WP;
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 FUSE_RESERVED_PRODUCTION;
uint32_t FUSE_HDMI_LANE0_CALIB;
uint32_t FUSE_HDMI_LANE1_CALIB;
uint32_t FUSE_HDMI_LANE2_CALIB;
uint32_t FUSE_HDMI_LANE3_CALIB;
uint32_t FUSE_ENCRYPTION_RATE;
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_TSENSOR1_CALIB;
uint32_t FUSE_TSENSOR2_CALIB;
uint32_t FUSE_VSENSOR_CALIB;
uint32_t FUSE_OPT_CP_REV;
uint32_t FUSE_OPT_PFG;
uint32_t FUSE_TSENSOR0_CALIB;
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;
uint32_t FUSE_SECURITY_MODE;
uint32_t FUSE_PRIVATE_KEY[0x5];
uint32_t FUSE_ARM_JTAG_DIS;
uint32_t FUSE_BOOT_DEVICE_INFO;
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_OPT_VP9_DISABLE;
uint32_t FUSE_VP8_ENABLE;
uint32_t FUSE_RESERVED_ODM[0x8];
uint32_t FUSE_OBS_DIS;
uint32_t FUSE_NOR_INFO;
uint32_t FUSE_USB_CALIB;
uint32_t _0xE8;
uint32_t _0xEC;
uint32_t FUSE_SKU_USB_CALIB;
uint32_t FUSE_SKU_DIRECT_CONFIG;
uint32_t FUSE_KFUSE_PRIVKEY_CTRL;
uint32_t FUSE_PACKAGE_INFO;
uint32_t FUSE_OPT_VENDOR_CODE;
uint32_t FUSE_OPT_FAB_CODE;
uint32_t FUSE_OPT_LOT_CODE_0;
uint32_t FUSE_OPT_LOT_CODE_1;
uint32_t FUSE_OPT_WAFER_ID;
uint32_t FUSE_OPT_X_COORDINATE;
uint32_t FUSE_OPT_Y_COORDINATE;
uint32_t FUSE_OPT_SEC_DEBUG_EN;
uint32_t FUSE_OPT_OPS_RESERVED;
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_CALIB;
uint32_t FUSE_TSENSOR3_CALIB;
uint32_t FUSE_SKU_BOND_OUT_L;
uint32_t FUSE_SKU_BOND_OUT_H;
uint32_t FUSE_SKU_BOND_OUT_U;
uint32_t FUSE_SKU_BOND_OUT_V;
uint32_t FUSE_SKU_BOND_OUT_W;
uint32_t FUSE_OPT_SAMPLE_TYPE;
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 FUSE_OPT_SW_RESERVED_0;
uint32_t FUSE_OPT_SW_RESERVED_1;
uint32_t FUSE_TSENSOR4_CALIB;
uint32_t FUSE_TSENSOR5_CALIB;
uint32_t FUSE_TSENSOR6_CALIB;
uint32_t FUSE_TSENSOR7_CALIB;
uint32_t FUSE_OPT_PRIV_SEC_EN;
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 FUSE_FUSE2TSEC_DEBUG_DISABLE;
uint32_t _0x17C;
uint32_t FUSE_TSENSOR_COMMON;
uint32_t FUSE_OPT_CP_BIN;
uint32_t FUSE_OPT_GPU_DISABLE;
uint32_t FUSE_OPT_FT_BIN;
uint32_t FUSE_OPT_DONE_MAP;
uint32_t _0x184;
uint32_t _0x188;
uint32_t _0x18C;
uint32_t _0x190;
uint32_t _0x194;
uint32_t FUSE_APB2JTAG_DISABLE;
uint32_t FUSE_ODM_INFO;
uint32_t _0x198;
uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
uint32_t _0x1A0;
uint32_t _0x1A4;
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
uint32_t _0x1A8;
uint32_t _0x1AC;
uint32_t _0x1B0;
uint32_t _0x1B4;
uint32_t _0x1B8;
uint32_t _0x1BC;
uint32_t FUSE_WOA_SKU_FLAG;
uint32_t FUSE_ECO_RESERVE_1;
uint32_t FUSE_GCPLEX_CONFIG_FUSE;
uint32_t FUSE_PRODUCTION_MONTH;
uint32_t FUSE_RAM_REPAIR_INDICATOR;
uint32_t FUSE_TSENSOR9_CALIB;
uint32_t _0x1D0;
uint32_t FUSE_TSENSOR_8;
uint32_t _0x1D8;
uint32_t FUSE_VMIN_CALIBRATION;
uint32_t FUSE_AGING_SENSOR_CALIBRATION;
uint32_t FUSE_DEBUG_AUTHENTICATION;
uint32_t FUSE_SECURE_PROVISION_INDEX;
uint32_t FUSE_SECURE_PROVISION_INFO;
uint32_t FUSE_OPT_GPU_DISABLE_CP1;
uint32_t FUSE_SPARE_ENDIS;
uint32_t FUSE_ECO_RESERVE_0;
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_CALIB0;
uint32_t FUSE_RESERVED_CALIB1;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1;
uint32_t FUSE_OPT_CPU_DISABLE;
uint32_t FUSE_OPT_CPU_DISABLE_CP1;
uint32_t FUSE_TSENSOR10_CALIB;
uint32_t FUSE_TSENSOR10_CALIB_AUX;
uint32_t FUSE_OPT_RAM_SVOP_DP;
uint32_t FUSE_OPT_RAM_SVOP_PDP;
uint32_t FUSE_OPT_RAM_SVOP_REG;
uint32_t FUSE_OPT_RAM_SVOP_SP;
uint32_t FUSE_OPT_RAM_SVOP_SMPDP;
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1;
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2;
uint32_t FUSE_OPT_CPU_DISABLE_CP2;
uint32_t FUSE_OPT_GPU_DISABLE_CP2;
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 FUSE_RESERVED_FIELD;
uint32_t FUSE_OPT_ECC_EN;
uint32_t _0x254;
uint32_t _0x258;
uint32_t _0x25C;
uint32_t _0x260;
uint32_t _0x264;
@@ -193,42 +180,41 @@ typedef struct {
uint32_t _0x270;
uint32_t _0x274;
uint32_t _0x278;
uint32_t FUSE_SPARE_REALIGNMENT_REG;
uint32_t _0x27C;
uint32_t FUSE_SPARE_BIT[0x20];
} tegra_fuse_chip_t;
} fuse_chip_registers_t;
static inline volatile tegra_fuse_t *fuse_get_regs(void) {
return (volatile tegra_fuse_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x800);
static inline volatile fuse_registers_t *get_fuse_regs(void) {
return (volatile fuse_registers_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x800);
}
static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) {
return (volatile tegra_fuse_chip_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x900);
static inline volatile fuse_chip_registers_t *get_fuse_chip_regs(void) {
return (volatile fuse_chip_registers_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x900);
}
#define FUSE_REGS (fuse_get_regs())
#define FUSE_CHIP_REGS (fuse_chip_get_regs())
#define FUSE_REGS (get_fuse_regs())
#define FUSE_CHIP_REGS (get_fuse_chip_regs())
void fuse_init(void);
void fuse_disable_programming(void);
void fuse_disable_private_key(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(uint32_t target_firmware);
uint32_t fuse_get_retail_type(void);
void fuse_get_hardware_info(void *dst);
uint32_t fuse_get_5x_key_generation(void);
bool fuse_has_rcm_bug_patch(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_expected_fuse_version(uint32_t target_firmware);
uint32_t fuse_get_5x_key_generation(void);
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);
bool fuse_has_rcm_bug_patch(void);
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,
@@ -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 <string.h>
@@ -83,7 +83,7 @@ static void ghash(void *dst, const void *data, size_t data_size, const void *j_b
/* H = aes_ecb_encrypt(zeroes) */
se_aes_128_ecb_encrypt_block(KEYSLOT_SWITCH_TEMPKEY, h, 0x10, x, 0x10);
size_t total_size = data_size;
while (data_size >= 0x10) {
@@ -103,7 +103,7 @@ static void ghash(void *dst, const void *data, size_t data_size, const void *j_b
if (data_size & 0xF) {
gf128_mul(x, x, h);
}
uint64_t xor_size = total_size << 3;
xor_size = __builtin_bswap64(xor_size);
@@ -113,9 +113,9 @@ static void ghash(void *dst, const void *data, size_t data_size, const void *j_b
} else {
p_x[1] ^= xor_size;
}
gf128_mul(x, x, h);
/* If final output block, XOR with encrypted J block. */
if (encrypt) {
se_aes_128_ecb_encrypt_block(KEYSLOT_SWITCH_TEMPKEY, h, 0x10, j_block, 0x10);
@@ -140,22 +140,22 @@ size_t gcm_decrypt_key(void *dst, size_t dst_size, const void *src, size_t src_s
generic_panic();
}
}
uint8_t intermediate_buf[0x400] = {0};
/* Unwrap the key */
unseal_key(KEYSLOT_SWITCH_TEMPKEY, sealed_kek, kek_size, usecase);
decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, KEYSLOT_SWITCH_TEMPKEY, wrapped_key, key_size);
/* Decrypt the GCM keypair, AES-CTR with CTR = blob[:0x10]. */
se_aes_ctr_crypt(KEYSLOT_SWITCH_TEMPKEY, intermediate_buf, dst_size, src + 0x10, src_size - 0x10, src, 0x10);
if (!is_personalized) {
/* Devkit non-personalized keys have no further authentication. */
memcpy(dst, intermediate_buf, src_size - 0x10);
memset(intermediate_buf, 0, sizeof(intermediate_buf));
return src_size - 0x10;
}
}
/* J = GHASH(CTR); */
uint8_t j_block[0x10];
@@ -166,7 +166,7 @@ size_t gcm_decrypt_key(void *dst, size_t dst_size, const void *src, size_t src_s
/* It is supposed to be over the ciphertext. */
uint8_t calc_mac[0x10];
ghash(calc_mac, intermediate_buf, src_size - 0x20, j_block, true);
/* Const-time memcmp. */
const uint8_t *src_bytes = src;
int different = 0;
@@ -184,7 +184,7 @@ size_t gcm_decrypt_key(void *dst, size_t dst_size, const void *src, size_t src_s
if (out_deviceid_high != NULL) {
*out_deviceid_high = intermediate_buf[src_size - 0x28];
}
memcpy(dst, intermediate_buf, src_size - 0x30);
memset(intermediate_buf, 0, sizeof(intermediate_buf));
return src_size - 0x30;
@@ -205,12 +205,10 @@ void gcm_encrypt_key(void *dst, size_t dst_size, const void *src, size_t src_siz
se_generate_random(KEYSLOT_SWITCH_RNGKEY, intermediate_buf, 0x10);
flush_dcache_range(intermediate_buf, intermediate_buf + 0x10);
/* Copy in the src. */
memcpy(intermediate_buf + 0x10, src, src_size);
/* Write Device ID. */
write64be(intermediate_buf, src_size + 0x18, fuse_get_device_id() | (deviceid_high << 56));
/* J = GHASH(CTR); */
uint8_t j_block[0x10];
ghash(j_block, intermediate_buf, 0x10, NULL, false);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
* 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,

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