Compare commits

..

21 Commits

Author SHA1 Message Date
Michael Scire
7b6df8c2f7 boot: remove references to memalign/malloc 2021-01-19 05:23:02 -08:00
Michael Scire
3b2c2ba5a2 ams_mitm: update for new sf semantics 2021-01-19 02:34:02 -08:00
Michael Scire
88a99bc68e dmnt: update for new sf semantics 2021-01-18 18:43:36 -08:00
Michael Scire
2d7a85d14f creport: update for new sf semantics 2021-01-18 17:50:40 -08:00
Michael Scire
2801d00d98 boot2: update for new sf semantics 2021-01-18 17:35:05 -08:00
Michael Scire
57c197ec1c boot: update for new sf-semantics 2021-01-18 17:22:36 -08:00
Michael Scire
2696240566 fatal: update screen task to use native window directly 2021-01-18 16:54:55 -08:00
Michael Scire
ea9d360b14 fatal: wip (pending libnx pr) update for new sf semantics 2021-01-18 08:48:47 -08:00
Michael Scire
a63b97fbbd jpegdec: note libjpeg-turbo TODO 2021-01-18 06:35:14 -08:00
Michael Scire
6c6e698a3e libstrat: move weak HasLaunchedBootProgram to non-lto object file 2021-01-18 06:26:22 -08:00
Michael Scire
15b225f919 loader: fix failure-to-early-return in launch record management 2021-01-18 06:20:13 -08:00
Michael Scire
ac2c713ee0 util::unique_lock, update loader to new sf semantics 2021-01-18 06:18:14 -08:00
Michael Scire
6a2f8e8344 string_view: remove now unecessary comment 2021-01-18 05:44:08 -08:00
Michael Scire
54a1ba2a7e ncm: update for new sf semantics 2021-01-18 05:41:15 -08:00
Michael Scire
2c485f832c util::string_view, update pgl for new sf semantics 2021-01-18 05:20:27 -08:00
Michael Scire
6467f6f07b pm: update for new sf semantics 2021-01-17 23:12:26 -08:00
Michael Scire
4f001b4f4c erpt: update for new sf semantics 2021-01-17 22:55:39 -08:00
Michael Scire
a6e452ed9e ro: reduce memory usage by excising (unused) std::malloc 2021-01-17 22:23:19 -08:00
Michael Scire
fb6a4e28a5 ro: update for new sf semantics 2021-01-17 22:03:26 -08:00
Michael Scire
bc9da91362 sm, spl: update to use new sf semantics 2021-01-17 15:03:51 -08:00
Michael Scire
8956e3bd29 libstrat: convert to experimental new (super-accurate) sf allocation semantics 2021-01-17 07:55:32 -08:00
1002 changed files with 34199 additions and 79471 deletions

View File

@@ -49,8 +49,6 @@ X.X.X</br>
- [ Ex: Kosmos' distribution of Atmosphère ]
- Do you have additional kips or sysmodules you're loading:
- Homebrew software installed: [ * ]
- EmuMMC or SysNAND:
- [ If using an EmuMMC, include whether it's partition-based or file-based. ]
### Additional context?

5
.gitignore vendored
View File

@@ -79,8 +79,9 @@ dkms.conf
*.nam
*.til
# Compiled python files.
# KEYS file for sept-secondary.
*.pyc
sept/sept-secondary/KEYS.py
.**/
@@ -94,5 +95,3 @@ dkms.conf
**/build_nintendo_nx_arm
**/build_nintendo_nx_x64
**/build_nintendo_nx_x86
stratosphere/test/

View File

@@ -1,9 +1,3 @@
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro)
endif
include $(DEVKITPRO)/devkitA64/base_tools
TOPTARGETS := all clean dist-no-debug dist
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
AMSHASH := $(shell git rev-parse --short HEAD)
@@ -32,7 +26,10 @@ mesosphere: exosphere libraries
troposphere: stratosphere
$(MAKE) -C troposphere all
fusee: exosphere mesosphere stratosphere
sept: exosphere
$(MAKE) -C sept all
fusee: exosphere mesosphere stratosphere sept
$(MAKE) -C $@ all
libraries:
@@ -40,7 +37,6 @@ libraries:
clean:
$(MAKE) -C fusee clean
$(MAKE) -C emummc clean
rm -rf out
dist-no-debug: all
@@ -58,46 +54,54 @@ dist-no-debug: all
rm -rf out
mkdir atmosphere-$(AMSVER)
mkdir atmosphere-$(AMSVER)/atmosphere
mkdir atmosphere-$(AMSVER)/sept
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/contents/0100000000000042
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
mkdir -p atmosphere-$(AMSVER)/atmosphere/config_templates
mkdir -p atmosphere-$(AMSVER)/atmosphere/config
mkdir -p atmosphere-$(AMSVER)/atmosphere/flags
touch atmosphere-$(AMSVER)/atmosphere/flags/clean_stratosphere_for_0.19.0.flag
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin
cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/sept/payload.bin
cp sept/sept-primary/sept-primary.bin atmosphere-$(AMSVER)/sept/sept-primary.bin
cp sept/sept-secondary/sept-secondary.bin atmosphere-$(AMSVER)/sept/sept-secondary.bin
cp sept/sept-secondary/sept-secondary_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_templates/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
cp config_templates/exosphere.ini atmosphere-$(AMSVER)/atmosphere/config_templates/exosphere.ini
cp -r config_templates/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches
cp -r config_templates/hbl_html atmosphere-$(AMSVER)/atmosphere/hbl_html
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000008
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000008
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000000D
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000002B
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000032
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000034
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000036
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000037
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000003C
mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000042
cp stratosphere/boot2/boot2.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000008/exefs.nsp
cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000000D/exefs.nsp
cp stratosphere/erpt/erpt.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000002B/exefs.nsp
cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000032/exefs.nsp
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000034/exefs.nsp
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000036/exefs.nsp
cp stratosphere/ro/ro.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000037/exefs.nsp
cp stratosphere/jpegdec/jpegdec.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000003C/exefs.nsp
cp stratosphere/pgl/pgl.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000042/exefs.nsp
@build_romfs atmosphere-$(AMSVER)/stratosphere_romfs atmosphere-$(AMSVER)/atmosphere/stratosphere.romfs
rm -r atmosphere-$(AMSVER)/stratosphere_romfs
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
cp stratosphere/pgl/pgl.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000042/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
touch atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/flags/boot2.flag
cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro
cp troposphere/daybreak/daybreak.nro atmosphere-$(AMSVER)/switch/daybreak.nro
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/sept/payload.bin
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER)-WITHOUT_MESOSPHERE.zip ./*; cd ../;
rm -r atmosphere-$(AMSVER)
mkdir out
@@ -121,6 +125,9 @@ dist: dist-no-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-experimental.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/loader_stub/loader_stub.elf atmosphere-$(AMSVER)-debug/exosphere-loader-stub.elf
cp exosphere/program/program.elf atmosphere-$(AMSVER)-debug/exosphere-program.elf
cp exosphere/warmboot/warmboot.elf atmosphere-$(AMSVER)-debug/exosphere-warmboot.elf
@@ -128,7 +135,6 @@ dist: dist-no-debug
cp exosphere/program/sc7fw/sc7fw.elf atmosphere-$(AMSVER)-debug/exosphere-sc7fw.elf
cp exosphere/program/rebootstub/rebootstub.elf atmosphere-$(AMSVER)-debug/exosphere-rebootstub.elf
cp mesosphere/kernel_ldr/kernel_ldr.elf atmosphere-$(AMSVER)-debug/kernel_ldr.elf
cp mesosphere/kernel/kernel.elf atmosphere-$(AMSVER)-debug/kernel.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

View File

@@ -1,13 +1,9 @@
[eupld]
; Disable uploading error reports to Nintendo
[eupld]
; upload_enabled = u8!0x0
[usb]
; Enable USB 3.0 superspeed for homebrew
; 0 = USB 3.0 support is system default (usually disabled), 1 = USB 3.0 support is enabled.
; usb30_force_enabled = u8!0x0
[ro]
; Control whether RO should ease its validation of NROs.
; (note: this is normally not necessary, and ips patches can be used.)
[ro]
; ease_nro_restriction = u8!0x1
; Atmosphere custom settings
[atmosphere]
@@ -36,23 +32,16 @@
; 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
; Controls whether am sees system settings "DebugModeFlag" as
; enabled or disabled.
; 0 = Disabled (not debug mode), 1 = Enabled (debug mode)
; enable_am_debug_mode = u8!0x0
; Controls whether dns.mitm is enabled
; 0 = Disabled, 1 = Enabled
; enable_dns_mitm = u8!0x1
; Controls whether dns.mitm uses the default redirections in addition to
; whatever is specified in the user's hosts file.
; 0 = Disabled (use hosts file contents), 1 = Enabled (use defaults and hosts file contents)
; add_defaults_to_dns_hosts = u8!0x1
; Controls whether dns.mitm logs to the sd card for debugging
; 0 = Disabled, 1 = Enabled
; enable_dns_mitm_debug_log = u8!0x0
; Controls whether htc is enabled
; 0 = Disabled, 1 = Enabled
; enable_htc = 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

@@ -9,7 +9,7 @@ Building Atmosphère is a very straightforward process that relies almost exclus
+ [PyCryptodome](https://pypi.org/project/pycryptodome) (optional)
## Instructions
1. Follow the guide located [here](https://devkitpro.org/wiki/Getting_Started) to install and configure all the tools necessary for the build process.
1. Follow the guide located [here](https://devkitpro.org/wiki/Getting_Started) to install and configure all the tools necessary for the build process.
2. Install the following packages via (dkp-)pacman:
+ `switch-dev`
@@ -21,4 +21,12 @@ Building Atmosphère is a very straightforward process that relies almost exclus
3. Install the following library via python's package manager `pip`, required by [exosphere](components/exosphere.md):
+ `lz4`
4. Finally, clone the Atmosphère repository and run `make` under its root directory.
4. (Optional) In order to build [sept](components/sept.md) the pycryptodome PyPi package is required, which can be installed by running `pip install pycryptodome` under the installed Python environment of your choice or by installing the complete zip package to support the `make dist` recipe. This is an optional step included for advanced users who have the ability to provide the necessary encryption/signing keys themselves.
5. It is, instead, possible to build [sept](components/sept.md) by providing previously encrypted/signed binaries distributed by official Atmosphère release packages. In order to do so, export the following variables in your current environment:
+ `SEPT_00_ENC_PATH` (must point to the `sept-secondary_00.enc` file)
+ `SEPT_01_ENC_PATH` (must point to the `sept-secondary_01.enc` file)
+ `SEPT_DEV_00_ENC_PATH` (must point to the `sept-secondary_dev_00.enc` file)
+ `SEPT_DEV_01_ENC_PATH` (must point to the `sept-secondary_dev_01.enc` file)
6. Finally, clone the Atmosphère repository and run `make` under its root directory.

View File

@@ -1,141 +1,4 @@
# Changelog
## 0.20.0
+ DRAM training (MTC) was implemented for Mariko hardware, increasing RAM speed from 204MHz to 1600MHz.
+ This significantly optimizes Mariko boot speed, cutting boot time roughly in half.
+ Typical boot time reductions (measured as "select fusee" to "home menu visible"):
+ Normal (Iowa): ~35 seconds -> ~18 seconds.
+ Lite (Hoag): ~65 seconds -> ~30 seconds.
+ NOTE: Work is being started on a re-written `fusee` component, with an eye specifically towards ensuring a good boot speed.
+ With any luck, boot will be much much faster on all units (Mariko and Erista) in an upcoming release.
+ Sept was replaced, and deleted from the repository.
+ Erista units now use a custom TSEC firmware to manage key derivation.
+ For more details, contact SciresM#0524 on discord.
+ This has a number of benefits, including:
+ This greatly simplifies key derivation logic by making it consistent on all firmwares.
+ Fusee no longer accesses/uses keyblobs at all, so units which have accidentally destroyed/lost keyblobs can boot without them.
+ This greatly increases stability (sept was the biggest source of boot failures).
+ This improves boot speed (sept rebooted multiple times, performed hardware init multiple times, and was generally very slow).
+ Atmosphère build process is now much saner.
+ A number of improvements were made to the dmnt cheat engine.
+ Cheats which take in a memory region operand may now use types "2" or "3" to perform accesses relative to the alias/aslr regions, respectively.
+ Support was added for an "else" opcode in the cheat engine, to make writing certain conditional logic more natural.
+ Support was added for a cheat orchestrator homebrew (like edizon) to detach from a cheat process/set the master cheat programmatically.
+ Daybreak now provides a warning when attempting to install a firmware newer than the highest version atmosphère knows it supports.
+ To facilitate this, exosphere now exposes the supported HOS version via an extension ConfigItem.
+ A number of minor issues were fixed, including:
+ Several mesosphere debug SVC implementations were updated to reflect the semantics of the latest kernel.
+ Support was fixed for deriving BIS encryption keys on certain prototype hardware.
+ General system stability improvements to enhance the user's experience.
## 0.19.5
+ Support was added for 12.1.0.
+ LayeredFS support was added for OpenDataStorageWithProgramIndex commands.
+ Certain games using newer (7.0.0+ APIs) which include multiple programs under a single title previously could not be modified.
+ These are now supported as normal, and LayeredFS should have 100% compatibility again.
+ A number of minor issues were fixed, including:
+ The Reboot to Payload NRO was updated to allow the OS to save state prior to rebooting (thanks @AuroraWright)!
+ An issue was fixed that could cause dns.mitm to fail when games requested resolution of an empty string.
+ An issue was fixed that caused a memory leak in the erpt system module.
+ This would eventually cause a system crash after ~540 reports were generated without rebooting.
+ A number of minor improvements were made to improve mesosphere's accuracy.
+ General system stability improvements to enhance the user's experience.
## 0.19.4
+ Support was added for 12.0.3.
+ A number of minor issues were fixed, including:
+ An issue was fixed that could cause heap memory corruption when allocation was highly contended.
+ An issue was fixed that could cause sleep to fail under certain conditions.
+ An issue was fixed that could cause a scheduler slow path to be taken more often than necessary.
+ General system stability improvements to enhance the user's experience.
## 0.19.3
+ Support was added for 12.0.2.
+ A number of minor issues were fixed, including:
+ An issue was fixed in dns.mitm that caused a crash when games attempted to resolve the IP address of nullptr.
+ An issue was fixed in erpt that would cause an abort when booting without having ever booted stock previously.
+ An issue was fixed in (file-based) emummc that caused an error on system format/downloading certain games.
+ General system stability improvements to enhance the user's experience.
## 0.19.2
+ Atmosphère's components were further updated to reflect latest official behaviors as of 12.0.0.
+ Notably, `erpt` was updated to implement the new forced shutdown detection feature.
+ When a forced-shutdown occurs, an erpt_report will be generated and saved to the SD card on the next boot.
+ Atmosphere-libs was updated to use GCC 11 (latest devkitA64/devkitARM releases).
+ Initial inspections show mild-to-moderate optimizer improvements in several important places (kernel is 0x3000 smaller).
+ General system stability improvements to enhance the user's experience.
+ A number of minor issues were fixed, including:
+ A bug was fixed that caused a black screen when attempting to boot firmware versions 2.0.0-4.1.0.
+ A bug was fixed that caused sm to abort when at the session limit, rather than returning error codes.
+ A bug was fixed that allowed for resource exhaustion on 12.0.0, under certain circumstances.
+ Several issues were fixed, and usability and stability were improved.
## 0.19.1
+ An issue was fixed that caused a fatal error when using official `migration` services to transfer data between consoles.
+ An issue was fixed in `ncm` that caused an error when the OS tried to enumerate installed SD card content.
+ Several issues were fixed, and usability and stability were improved.
## 0.19.0
+ Support was added for 12.0.0.
+ `mesosphère` was updated to reflect the latest official kernel behavior.
+ `sm`, `boot2`, `pgl` were updated to reflect the latest official behaviors.
+ **Please Note**: 12.0.0 added a new protocol for IPC ("tipc"), which has been freshly reimplemented in its entirety.
+ It is possible there may be as of yet unfound issues; if there are, please send the appropriate crash reports to SciresM (SciresM#0524 on discord).
+ Homebrew which uses atmosphere extensions (including the mitm API) will need to be re-compiled in order to function on 0.19.0.
+ I apologize for this, but it's unavoidable for technical reasons. If you're affected by this and mad about it, please contact SciresM to complain.
+ `erpt` was partially updated to reflect the latest official behaviors.
+ New features were added to erpt to track the activity of running applets, and to detect when a forced shutdown occurs.
+ These behaviors have been temporarily stubbed, as they are not necessary for 12.0.0 to run (and their outputs won't be saved anywhere).
+ A future atmosphère update will implement these behaviors, in the interest of reflecting official logic as faithfully as we can.
+ Atmosphère no longer uses the /contents/ folder for its own programs.
+ Atmosphère's system modules are now bundled together in the single file "stratosphere.romfs".
+ For those working on developing for atmosphère, executables inside the /contents/ directory will be preferred to those in "stratosphere.romfs".
+ **Please Note**: In order to facilitate this change (and the desired behavior), the first time you boot after extracting a release zip, atmosphère system modules inside /contents/ will be deleted.
+ This will have no impact on user programs (it only removes programs with specific program ids).
+ Improvements were made to mesosphere, including:
+ An extension InfoType was added for getting the current process handle, without having to spawn a thread and do IPC with oneself.
+ An issue was fixed in SvcSetDebugThreadContext.
+ An issue was fixed when doing IPC with user buffers.
+ Support was fixed for toggling the custom setting `usb!usb30_force_enabled` on 9.0.0+.
+ This was broken by Nintendo's introducing a dependency that made USB a requirement to launch before custom settings are parsed.
+ Since the fix, you can now toggle the setting (as you could prior to atmosphère 0.9.4), and it will work as expected.
+ **Please Note**: Enabling USB 3.0 often severely impacts wireless communications.
+ Because of this, the setting will default to off. If you experience issues with it enabled, consider disabling it.
+ A warning was added to daybreak when resetting the console to factory settings.
+ Substantial work was completed towards atmosphere's upcoming implementation of the host target connection protocol.
+ Once completed, users will be able to interact with a Switch running atmosphère via a PC application ("Starlink") currently under development.
+ Planned eventual features for connected consoles include a gdbstub, interacting with memory (for cheat development), streaming gameplay audio and video, and accessing the Switch's SD card filesystem.
+ Switch homebrew will also have access to a (configurable and sandboxed) filesystem on the host PC, while connected.
+ Towards this end, the following was accomplished:
+ The "htc" system module was reimplemented completely.
+ The system module which provides remote access to the SD card was reimplemented completely.
+ This is currently the active focus of atmosphère's development.
+ **Please Note**: Support is not yet completed, and users are disadvised from interacting with the related settings for the time being, unless they particularly know what they're doing.
+ A number of minor issues were fixed, including:
+ A bug was fixed in `dmnt` that could cause a fatal when launching certain games with cheats active.
+ An issue was fixed that could cause an abort in `sm` when using a large number of custom system modules.
+ An issue was fixed that prevented launching gamecards on 1.0.0.
+ Minor issues were fixed in the cheat virtual machine's behavior.
+ Several issues were fixed, and usability and stability were improved.
## 0.18.1
+ A number of minor issues were fixed, including:
+ The new `dns.mitm` module added in 0.18.0 no longer fatal errors when receiving port=nullptr.
+ This fixes youtube ad-blocking, and possibly other usecases.
+ A bug was fixed that caused ams.mitm to incorrectly cache data storages.
+ This potentially broke DLC when using romfs mods, and could have caused other issues (e.g. with custom themes, and maybe other cases).
+ A bug was fixed in power state control module registration.
+ This might fix a weird edge case with system module dependencies on sleep/wake, but probably nobody should notice any differences.
+ A bug was fixed where mesosphere sometimes treated virtual core IDs as though they were physical core IDs.
+ This had zero impact, because for Switch virtual core == physical core, but it could have affected future platforms if it had remained unresolved.
+ Several issues were fixed, and usability and stability were improved.
## 0.18.0
+ A new mitm module was added (`dns.mitm`).
+ This provides a highly configurable mechanism for redirecting DNS resolution requests.
+ By default atmosphère redirects resolution requests for official telemetry servers to a loopback address.
+ Documentation on how to configure `dns.mitm` to meet your more specific needs may be found [here](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/features/dns_mitm.md).
+ The service framework API (`sf`) was refactored to be more accurate to official logic and greatly reduce memory requirements.
+ The comparison of atmosphère module memory usage versus Nintendo's found [here](https://github.com/Atmosphere-NX/Atmosphere/wiki/Memory-Comparisons) was updated to reflect this.
+ **Please Note**: If you are a developer using the libstratosphere service APIs, some updating may be required. Contact SciresM#0524 on discord for assistance if required.
+ A number of deprecations were removed, following a general codebase cleanup:
+ The `sm` extension to not unregister services on connection close was superseded by official opt-in logic in 11.0.0, and has been removed in favor of official logic.
+ This should have zero impact on users.
+ The temporary `hid-mitm` added in 0.9.0 has finally been removed, following over a year of deprecation.
+ There shouldn't be any homebrew in use still affected by this, but the situation will be monitored.
+ If this is somehow still a real issue, an unaffiliated hid mitm sysmodule providing the same functionality can be created and released, separate from atmosphère itself.
+ Several issues were fixed, and usability and stability were improved.
## 0.17.1
+ A number of atmosphère's modules were using more memory than their Nintendo equivalent's in 0.17.0; a number of code generatio tweaks have been applied to fix this across the board.
+ A detailed comparison of atmosphère module memory usage versus Nintendo's was made and can be found [here](https://github.com/Atmosphere-NX/Atmosphere/wiki/Memory-Comparisons).
@@ -152,7 +15,7 @@
+ This also substantially improves power drain when the system is shut off; consoles powered off from Atmosphere should now drain battery at the same reduced rate as original firmware.
+ A number of minor changes were made, including:
+ A number of inconsistencies in the build system were fixed.
+ For those building atmosphère at home, the `boot` sysmodule will no longer rebuild every time make is invoked.
+ Fow those building atmosphère at home, the `boot` sysmodule will no longer rebuild every time make is invoked.
+ This substantially improves build times during development iteration.
+ `sm` was updated to more accurately reflect how official code manages request deferral.
+ `mesosphère` was updated to more accurately reflect official kernel management of the trace buffer.

View File

@@ -33,8 +33,3 @@ in settings as `#.#.#|AMS #.#.#|?` with `? = S` when running under system eMMC o
### System Settings
set_mitm intercepts the `GetSettingsItemValueSize` and `GetSettingsItemValue` commands for all requesters.
It does so in order to enable user configuration of system settings, which are parsed from `/atmosphere/system_settings.ini` on boot. See [here](../../features/configurations.md) for more information on the system settings format.
## dns_mitm
dns_mitm enables intercepting requests to dns resolution services, to enable redirecting requests for specified hostnames.
For documentation, see [here](../../features/dns_mitm.md).

14
docs/components/sept.md Normal file
View File

@@ -0,0 +1,14 @@
# sept
Sept is a payload that facilitates booting Atmosphère when targeting firmware version 7.0.0+.
It consists of a primary and a secondary payload.
## sept-primary
sept-primary is essentially a stand-in for Nintendo's package1ldr, on 7.0.0+. To use it, the caller (normally fusée-secondary) loads the sept-primary binary to `0x4003F000`, loads the 7.0.0+ TSEC firmware to `0x40010F00`, and loads a signed, encrypted payload to `0x40016FE0`.
This signed, encrypted payload is normally sept-secondary.
## sept-secondary
sept-secondary is a payload that performs 7.0.0+ key derivation, and then chainloads to `sept/payload.bin`.
It is normally stored encrypted/signed. Therefore, if one wishes to build sept-secondary instead of using release builds, one must bring their own keys.

View File

@@ -19,8 +19,6 @@ This behavior ensures that cheat codes are only loaded when the user would want
In cases where `dmnt` has not activated the cheat manager, but the user wants to make it do so anyway, the cheat manager's service API provides a `ForceOpenCheatProcess` command that homebrew can use. This command will cause the cheat manager to try to force itself to attach to the process.
In cases where `dmnt` has activated the cheat manager, but the user wants to use an alternate debugger, the cheat manager's service API provides a `ForceCloseCheatProcess` command that homebrew can use. This command will cause the cheat manager to detach itself from the process.
By default, all cheat codes listed in the loaded .txt file will be toggled on. This is configurable by the user by editing the `atmosphere!dmnt_cheats_enabled_by_default` [system setting](configurations.md).
Users may use homebrew programs to toggle cheats on and off at runtime via the cheat manager's service API.
@@ -42,30 +40,30 @@ The following provides documentation of the instruction format for the virtual m
Typically, instruction type is encoded in the upper nybble of the first instruction u32.
### Code Type 0x0: Store Static Value to Memory
Code type 0x0 allows writing a static value to a memory address.
### Code Type 0: Store Static Value to Memory
Code type 0 allows writing a static value to a memory address.
#### Encoding
`0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
+ T: Width of memory write (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
+ R: Register to use as an offset from memory region base.
+ A: Immediate offset to use from memory region base.
+ V: Value to write.
---
### Code Type 0x1: Begin Conditional Block
Code type 0x1 performs a comparison of the contents of memory to a static value.
### Code Type 1: Begin Conditional Block
Code type 1 performs a comparison of the contents of memory to a static value.
If the condition is not met, all instructions until the appropriate End or Else conditional block terminator are skipped.
If the condition is not met, all instructions until the appropriate conditional block terminator are skipped.
#### Encoding
`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
+ T: Width of memory write (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
+ C: Condition to use, see below.
+ A: Immediate offset to use from memory region base.
+ V: Value to compare to.
@@ -80,20 +78,16 @@ If the condition is not met, all instructions until the appropriate End or Else
---
### Code Type 0x2: End Conditional Block
Code type 0x2 marks the end of a conditional block (started by Code Type 0x1 or Code Type 0x8).
When an Else is executed, all instructions until the appropriate End conditional block terminator are skipped.
### Code Type 2: End Conditional Block
Code type 2 marks the end of a conditional block (started by Code Type 1 or Code Type 8).
#### Encoding
`2X000000`
+ X: End type (0 = End, 1 = Else).
`20000000`
---
### Code Type 0x3: Start/End Loop
Code type 0x3 allows for iterating in a loop a fixed number of times.
### Code Type 3: Start/End Loop
Code type 3 allows for iterating in a loop a fixed number of times.
#### Start Loop Encoding
`300R0000 VVVVVVVV`
@@ -108,8 +102,8 @@ Code type 0x3 allows for iterating in a loop a fixed number of times.
---
### Code Type 0x4: Load Register with Static Value
Code type 0x4 allows setting a register to a constant value.
### Code Type 4: Load Register with Static Value
Code type 4 allows setting a register to a constant value.
#### Encoding
`400R0000 VVVVVVVV VVVVVVVV`
@@ -119,28 +113,29 @@ Code type 0x4 allows setting a register to a constant value.
---
### Code Type 0x5: Load Register with Memory Value
Code type 0x5 allows loading a value from memory into a register, either using a fixed address or by dereferencing the destination register.
### Code Type 5: Load Register with Memory Value
Code type 5 allows loading a value from memory into a register, either using a fixed address or by dereferencing the destination register.
#### Load From Fixed Address Encoding
`5TMR00AA AAAAAAAA`
+ T: Width of memory read (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
+ R: Register to load value into.
+ A: Immediate offset to use from memory region base.
#### Load from Register Address Encoding
`5T0R10AA AAAAAAAA`
`5TMR10AA AAAAAAAA`
+ T: Width of memory read (1, 2, 4, or 8 bytes).
+ R: Register to load value into. (This register is also used as the base memory address).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
+ R: Register to load value into.
+ A: Immediate offset to use from register R.
---
### Code Type 0x6: Store Static Value to Register Memory Address
Code type 0x6 allows writing a fixed value to a memory address specified by a register.
### Code Type 6: Store Static Value to Register Memory Address
Code type 6 allows writing a fixed value to a memory address specified by a register.
#### Encoding
`6T0RIor0 VVVVVVVV VVVVVVVV`
@@ -154,10 +149,10 @@ Code type 0x6 allows writing a fixed value to a memory address specified by a re
---
### Code Type 0x7: Legacy Arithmetic
Code type 0x7 allows performing arithmetic on registers.
### Code Type 7: Legacy Arithmetic
Code type 7 allows performing arithmetic on registers.
However, it has been deprecated by Code type 0x9, and is only kept for backwards compatibility.
However, it has been deprecated by Code type 9, and is only kept for backwards compatibility.
#### Encoding
`7T0RC000 VVVVVVVV`
@@ -176,8 +171,8 @@ However, it has been deprecated by Code type 0x9, and is only kept for backwards
---
### Code Type 0x8: Begin Keypress Conditional Block
Code type 0x8 enters or skips a conditional block based on whether a key combination is pressed.
### Code Type 8: Begin Keypress Conditional Block
Code type 8 enters or skips a conditional block based on whether a key combination is pressed.
#### Encoding
`8kkkkkkk`
@@ -218,8 +213,8 @@ Note: This is the direct output of `hidKeysDown()`.
---
### Code Type 0x9: Perform Arithmetic
Code type 0x9 allows performing arithmetic on registers.
### Code Type 9: Perform Arithmetic
Code type 9 allows performing arithmetic on registers.
#### Register Arithmetic Encoding
`9TCRS0s0`
@@ -253,8 +248,8 @@ Code type 0x9 allows performing arithmetic on registers.
---
### Code Type 0xA: Store Register to Memory Address
Code type 0xA allows writing a register to memory.
### Code Type 10: Store Register to Memory Address
Code type 10 allows writing a register to memory.
#### Encoding
`ATSRIOxa (aaaaaaaa)`
@@ -277,13 +272,13 @@ Code type 0xA allows writing a register to memory.
---
### Code Type 0xB: Reserved
Code Type 0xB is currently reserved for future use.
### Code Type 11: Reserved
Code Type 11 is currently reserved for future use.
---
### Code Type 0xC-0xF: Extended-Width Instruction
Code Types 0xC-0xF signal to the VM to treat the upper two nybbles of the first dword as instruction type, instead of just the upper nybble.
### Code Type 12-15: Extended-Width Instruction
Code Types 12-15 signal to the VM to treat the upper two nybbles of the first dword as instruction type, instead of just the upper nybble.
This reserves an additional 64 opcodes for future use.

View File

@@ -1,53 +0,0 @@
# DNS.mitm
As of 0.18.0, atmosphère provides a mechanism for redirecting DNS resolution requests.
By default, atmosphère redirects resolution requests for official telemetry servers, redirecting them to a loopback address.
## Hosts files
DNS.mitm can be configured through the usage of a slightly-extended `hosts` file format, which is parsed only once on system startup.
In particular, hosts files parsed by DNS.mitm have the following extensions to the usual format:
+ `*` is treated as a wildcard character, matching any collection of 0 or more characters wherever it occurs in a hostname.
+ `%` is treated as a stand-in for the value of `nsd!environment_identifier`. This is always `lp1`, on production devices.
If multiple entries in a host file match a domain, the last-defined match is used.
Please note that homebrew may trigger a hosts file re-parse by sending the extension IPC command 65000 ("AtmosphereReloadHostsFile") to a connected `sfdnsres` session.
### Hosts file selection
Atmosphère will try to read hosts from the following file paths, in order, stopping once it successfully performs a file read:
+ (emummc only) `/atmosphere/hosts/emummc_%04lx.txt`, formatted with the emummc's id number (see `emummc.ini`).
+ (emummc only) `/atmosphere/hosts/emummc.txt`.
+ (sysmmc only) `/atmosphere/hosts/sysmmc.txt`.
+ `/atmosphere/hosts/default.txt`
If `/atmosphere/hosts/default.txt` does not exist, atmosphère will create it to contain the defaults.
### Atmosphère defaults
By default, atmosphère's default redirections are parsed **in addition to** the contents of the loaded hosts file.
This is equivalent to thinking of the loaded hosts file as having the atmosphère defaults prepended to it.
This setting is considered desirable, because it minimizes the telemetry risks if a user forgets to update a custom hosts file on a system update which changes the telemetry servers.
This behavior can be opted-out from by setting `atmosphere!add_defaults_to_dns_hosts = u8!0x0` in `system_settings.ini`.
The current default redirections are:
```
# Nintendo telemetry servers
127.0.0.1 receive-%.dg.srv.nintendo.net receive-%.er.srv.nintendo.net
```
## Debugging
On startup (or on hosts file re-parse), DNS.mitm will log both what hosts file it selected and the contents of all redirections it parses to `/atmosphere/logs/dns_mitm_startup.log`.
In addition, if the user sets `atmosphere!enable_dns_mitm_debug_log = u8!0x1` in `system_settings.ini`, DNS.mitm will log all requests to GetHostByName/GetAddrInfo to `/atmosphere/logs/dns_mitm_debug.log`. All redirections will be noted when they occur.
## Opting-out of DNS.mitm entirely
If you wish to disable DNS.mitm entirely, `system_settings.ini` can be edited to set `atmosphere!enable_dns_mitm = u8!0x0`.

View File

@@ -12,6 +12,7 @@ Atmosphère provides six core components, mimicking to some degree the various l
Additionally, Atmosphère also provides the following secondary components:
+ [emummc](components/emummc.md)
+ [sept](components/sept.md)
+ [libraries](components/libraries.md)
## Features

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/m4xw/emuMMC
branch = develop
commit = cbc294c390ed73bb281bc1028a8899c053427112
parent = 38f9a76ba028995ed3274da3a45b0254f09d1f59
commit = 5eed18eb527bbaa63aee5323c26de5b0cca6d28e
parent = 021b29d2dbc8ed0469bc822393e58c9f0d174d57
method = rebase
cmdver = 0.4.1

View File

@@ -32,7 +32,7 @@ CFLAGS += $(INCLUDE) -D__SWITCH__
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(EMUMMCDIR)/emummc.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
ifneq ($(BUILD),$(notdir $(CURDIR)))

View File

@@ -1,201 +0,0 @@
OUTPUT_ARCH(aarch64)
ENTRY(_start)
PHDRS
{
code PT_LOAD FLAGS(5) /* Read | Execute */;
rodata PT_LOAD FLAGS(4) /* Read */;
data PT_LOAD FLAGS(6) /* Read | Write */;
dyn PT_DYNAMIC;
}
SECTIONS
{
/* =========== CODE section =========== */
PROVIDE(__start__ = 0x0);
. = __start__;
__code_start = . ;
.crt0 :
{
KEEP (*(.crt0))
. = ALIGN(8);
} :code
.init :
{
KEEP( *(.init) )
. = ALIGN(8);
} :code
.plt :
{
*(.plt)
*(.iplt)
. = ALIGN(8);
} :code
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
. = ALIGN(8);
} :code
.fini :
{
KEEP( *(.fini) )
. = ALIGN(8);
} :code
/* =========== RODATA section =========== */
. = ALIGN(0x1000);
__rodata_start = . ;
.nx-module-name : { KEEP (*(.nx-module-name)) } :rodata
.rodata :
{
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(8);
} :rodata
.eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } :rodata
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } :rodata
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } :rodata
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } : rodata
.dynamic : { *(.dynamic) } :rodata :dyn
.dynsym : { *(.dynsym) } :rodata
.dynstr : { *(.dynstr) } :rodata
.rela.dyn : { *(.rela.*) } :rodata
.interp : { *(.interp) } :rodata
.hash : { *(.hash) } :rodata
.gnu.hash : { *(.gnu.hash) } :rodata
.gnu.version : { *(.gnu.version) } :rodata
.gnu.version_d : { *(.gnu.version_d) } :rodata
.gnu.version_r : { *(.gnu.version_r) } :rodata
.note.gnu.build-id : { *(.note.gnu.build-id) } :rodata
/* =========== DATA section =========== */
. = ALIGN(0x1000);
__data_start = . ;
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } :data
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } :data
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } : data
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } :data
.tdata ALIGN(8) :
{
__tdata_lma = .;
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(8);
__tdata_lma_end = .;
} :data
.tbss ALIGN(8) :
{
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
. = ALIGN(8);
} :data
.preinit_array ALIGN(8) :
{
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
} :data
.init_array ALIGN(8) :
{
PROVIDE (__init_array_start = .);
KEEP( *(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)) )
KEEP( *(.init_array .ctors) )
PROVIDE (__init_array_end = .);
} :data
.fini_array ALIGN(8) :
{
PROVIDE (__fini_array_start = .);
KEEP( *(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)) )
KEEP( *(.fini_array .dtors) )
PROVIDE (__fini_array_end = .);
} :data
__got_start__ = .;
.got : { *(.got) *(.igot) } :data
.got.plt : { *(.got.plt) *(.igot.plt) } :data
__got_end__ = .;
.data ALIGN(8) :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
} :data
__bss_start__ = .;
.bss ALIGN(8) :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(8);
/* Reserve space for the TLS segment of the main thread */
__tls_start = .;
. += + SIZEOF(.tdata) + SIZEOF(.tbss);
__tls_end = .;
} : data
__bss_end__ = .;
__end__ = ABSOLUTE(.) ;
. = ALIGN(0x1000);
__argdata__ = ABSOLUTE(.) ;
/* ==================
==== Metadata ====
================== */
/* Discard sections that difficult post-processing */
/DISCARD/ : { *(.group .comment .note) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}

View File

@@ -1,8 +0,0 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /emummc.ld) -pie --no-dynamic-linker --spare-dynamic-tags=0 --gc-sections -z text -z nodynamic-undefined-weak --build-id=sha1 --nx-module-name
*startfile:
crti%O%s crtbegin%O%s

View File

@@ -51,10 +51,6 @@
#include "offsets/1020_exfat.h"
#include "offsets/1100.h"
#include "offsets/1100_exfat.h"
#include "offsets/1200.h"
#include "offsets/1200_exfat.h"
#include "offsets/1203.h"
#include "offsets/1203_exfat.h"
#include "../utils/fatal.h"
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
@@ -117,10 +113,6 @@ DEFINE_OFFSET_STRUCT(_1020);
DEFINE_OFFSET_STRUCT(_1020_EXFAT);
DEFINE_OFFSET_STRUCT(_1100);
DEFINE_OFFSET_STRUCT(_1100_EXFAT);
DEFINE_OFFSET_STRUCT(_1200);
DEFINE_OFFSET_STRUCT(_1200_EXFAT);
DEFINE_OFFSET_STRUCT(_1203);
DEFINE_OFFSET_STRUCT(_1203_EXFAT);
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
switch (version) {
@@ -194,14 +186,6 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
return &(GET_OFFSET_STRUCT_NAME(_1100));
case FS_VER_11_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1100_EXFAT));
case FS_VER_12_0_0:
return &(GET_OFFSET_STRUCT_NAME(_1200));
case FS_VER_12_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1200_EXFAT));
case FS_VER_12_0_3:
return &(GET_OFFSET_STRUCT_NAME(_1203));
case FS_VER_12_0_3_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1203_EXFAT));
default:
fatal_abort(Fatal_UnknownVersion);
}

View File

@@ -74,12 +74,6 @@ enum FS_VER
FS_VER_11_0_0,
FS_VER_11_0_0_EXFAT,
FS_VER_12_0_0,
FS_VER_12_0_0_EXFAT,
FS_VER_12_0_3,
FS_VER_12_0_3_EXFAT,
FS_VER_MAX,
};

View File

@@ -1,59 +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_1200_H__
#define __FS_1200_H__
// Accessor vtable getters
#define FS_OFFSET_1200_SDMMC_ACCESSOR_GC 0x154FD0
#define FS_OFFSET_1200_SDMMC_ACCESSOR_SD 0x156DE0
#define FS_OFFSET_1200_SDMMC_ACCESSOR_NAND 0x155500
// Hooks
#define FS_OFFSET_1200_SDMMC_WRAPPER_READ 0x150970
#define FS_OFFSET_1200_SDMMC_WRAPPER_WRITE 0x150A30
#define FS_OFFSET_1200_RTLD 0x688
#define FS_OFFSET_1200_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1200_CLKRST_SET_MIN_V_CLK_RATE 0x14FCC0
// Misc funcs
#define FS_OFFSET_1200_LOCK_MUTEX 0x29350
#define FS_OFFSET_1200_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1200_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150850
#define FS_OFFSET_1200_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1508E0
// Misc Data
#define FS_OFFSET_1200_SD_MUTEX 0xE3D3E8
#define FS_OFFSET_1200_NAND_MUTEX 0xE38768
#define FS_OFFSET_1200_ACTIVE_PARTITION 0xE387A8
#define FS_OFFSET_1200_SDMMC_DAS_HANDLE 0xE20DB0
// NOPs
#define FS_OFFSET_1200_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1200_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E810, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AEC0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081254, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092850, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1200_H__

View File

@@ -1,59 +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_1200_EXFAT_H__
#define __FS_1200_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_1200_EXFAT_SDMMC_ACCESSOR_GC 0x154FD0
#define FS_OFFSET_1200_EXFAT_SDMMC_ACCESSOR_SD 0x156DE0
#define FS_OFFSET_1200_EXFAT_SDMMC_ACCESSOR_NAND 0x155500
// Hooks
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_READ 0x150970
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_WRITE 0x150A30
#define FS_OFFSET_1200_EXFAT_RTLD 0x688
#define FS_OFFSET_1200_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1200_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x14FCC0
// Misc funcs
#define FS_OFFSET_1200_EXFAT_LOCK_MUTEX 0x29350
#define FS_OFFSET_1200_EXFAT_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150850
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1508E0
// Misc Data
#define FS_OFFSET_1200_EXFAT_SD_MUTEX 0xE4B3E8
#define FS_OFFSET_1200_EXFAT_NAND_MUTEX 0xE46768
#define FS_OFFSET_1200_EXFAT_ACTIVE_PARTITION 0xE467A8
#define FS_OFFSET_1200_EXFAT_SDMMC_DAS_HANDLE 0xE2EDB0
// NOPs
#define FS_OFFSET_1200_EXFAT_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1200_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E810, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AEC0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081254, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092850, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1200_EXFAT_H__

View File

@@ -1,60 +0,0 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
* Copyright (c) 2021 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __FS_1203_H__
#define __FS_1203_H__
// Accessor vtable getters
#define FS_OFFSET_1203_SDMMC_ACCESSOR_GC 0x1550E0
#define FS_OFFSET_1203_SDMMC_ACCESSOR_SD 0x156EF0
#define FS_OFFSET_1203_SDMMC_ACCESSOR_NAND 0x155610
// Hooks
#define FS_OFFSET_1203_SDMMC_WRAPPER_READ 0x150A80
#define FS_OFFSET_1203_SDMMC_WRAPPER_WRITE 0x150B40
#define FS_OFFSET_1203_RTLD 0x688
#define FS_OFFSET_1203_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1203_CLKRST_SET_MIN_V_CLK_RATE 0x14FDD0
// Misc funcs
#define FS_OFFSET_1203_LOCK_MUTEX 0x29350
#define FS_OFFSET_1203_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1203_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150960
#define FS_OFFSET_1203_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1509F0
// Misc Data
#define FS_OFFSET_1203_SD_MUTEX 0xE3D3E8
#define FS_OFFSET_1203_NAND_MUTEX 0xE38768
#define FS_OFFSET_1203_ACTIVE_PARTITION 0xE387A8
#define FS_OFFSET_1203_SDMMC_DAS_HANDLE 0xE20DB0
// NOPs
#define FS_OFFSET_1203_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1203_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E920, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AFD0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081364, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092960, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1203_H__

View File

@@ -1,60 +0,0 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
* Copyright (c) 2021 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __FS_1203_EXFAT_H__
#define __FS_1203_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_GC 0x1550E0
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_SD 0x156EF0
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_NAND 0x155610
// Hooks
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_READ 0x150A80
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_WRITE 0x150B40
#define FS_OFFSET_1203_EXFAT_RTLD 0x688
#define FS_OFFSET_1203_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1203_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x14FDD0
// Misc funcs
#define FS_OFFSET_1203_EXFAT_LOCK_MUTEX 0x29350
#define FS_OFFSET_1203_EXFAT_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150960
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1509F0
// Misc Data
#define FS_OFFSET_1203_EXFAT_SD_MUTEX 0xE4B3E8
#define FS_OFFSET_1203_EXFAT_NAND_MUTEX 0xE46768
#define FS_OFFSET_1203_EXFAT_ACTIVE_PARTITION 0xE467A8
#define FS_OFFSET_1203_EXFAT_SDMMC_DAS_HANDLE 0xE2EDB0
// NOPs
#define FS_OFFSET_1203_EXFAT_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1203_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E920, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AFD0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081364, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092960, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1203_EXFAT_H__

View File

@@ -292,36 +292,6 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
{
fp = &f_emu.fp_gpp[sector / f_emu.part_size];
sector = sector % f_emu.part_size;
// Special handling for reads/writes which cross file-boundaries.
if (__builtin_expect(sector + num_sectors > f_emu.part_size, 0))
{
unsigned int remaining = num_sectors;
while (remaining > 0) {
const unsigned int cur_sectors = MIN(remaining, f_emu.part_size - sector);
if (f_lseek(fp, (u64)sector << 9) != FR_OK)
return 0; // Out of bounds.
if (is_write)
{
if (f_write_fast(fp, buf, (u64)cur_sectors << 9) != FR_OK)
return 0;
}
else
{
if (f_read_fast(fp, buf, (u64)cur_sectors << 9) != FR_OK)
return 0;
}
buf = (char *)buf + ((u64)cur_sectors << 9);
remaining -= cur_sectors;
sector = 0;
++fp;
}
return 1;
}
}
else
{
@@ -336,14 +306,14 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
break;
}
if (f_lseek(fp, (u64)sector << 9) != FR_OK)
if (f_lseek(fp, sector << 9) != FR_OK)
return 0; // Out of bounds.
uint64_t res = 0;
if (!is_write)
res = !f_read_fast(fp, buf, (u64)num_sectors << 9);
res = !f_read_fast(fp, buf, num_sectors << 9);
else
res = !f_write_fast(fp, buf, (u64)num_sectors << 9);
res = !f_write_fast(fp, buf, num_sectors << 9);
return res;
}
@@ -358,13 +328,13 @@ uint64_t sdmmc_wrapper_controller_open(int mmc_id)
if (_this != NULL)
{
// Lock eMMC xfer while SD card is being initialized by FS.
if (mmc_id == FS_SDMMC_SD)
if (_this == sdmmc_accessor_get(FS_SDMMC_SD))
mutex_lock_handler(FS_SDMMC_EMMC); // Recursive Mutex, handler will lock SD as well if custom_driver
result = _this->vtab->sdmmc_accessor_controller_open(_this);
// Unlock eMMC.
if (mmc_id == FS_SDMMC_SD)
if (_this == sdmmc_accessor_get(FS_SDMMC_SD))
mutex_unlock_handler(FS_SDMMC_EMMC);
return result;

View File

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

View File

@@ -20,13 +20,13 @@
namespace ams::secmon::loader {
NORETURN void UncompressAndExecute(const void *program, const void *boot_code) {
NORETURN void UncompressAndExecute() {
/* Uncompress the program image. */
Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), program, program_lz4_size);
Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), program_lz4, program_lz4_size);
/* Copy the boot image to the end of IRAM */
u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer<u8>() - boot_code_lz4_size;
std::memcpy(relocated_boot_code, boot_code, boot_code_lz4_size);
std::memcpy(relocated_boot_code, boot_code_lz4, boot_code_lz4_size);
/* Uncompress the boot image. */
Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, boot_code_lz4_size);

View File

@@ -98,8 +98,8 @@ _start:
ldr x20, =0x7C020000
mov sp, x20
adr x0, program_lz4
adr x1, boot_code_lz4
/* Call our init array functions. */
bl __libc_init_array
/* Uncompress the program and iram boot code images. */
b _ZN3ams6secmon6loader20UncompressAndExecuteEPKvS3_
b _ZN3ams6secmon6loader20UncompressAndExecuteEv

View File

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

View File

@@ -1,4 +1,4 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /program.ld) --gc-sections --nmagic
%(old_link) -T %:getenv(TOPDIR /program.ld) --gc-sections --nmagic -nostdlib -nostartfiles

View File

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

View File

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

View File

@@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
/* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */
/* TODO: Update on next change of keys. */
/* Mariko Development Master Kek Source. */
.byte 0x75, 0x2D, 0x2E, 0xF3, 0x2F, 0x3F, 0xFE, 0x65, 0xF4, 0xA9, 0x83, 0xB4, 0xED, 0x42, 0x63, 0xBA
.byte 0xF9, 0x37, 0xCF, 0x9A, 0xBD, 0x86, 0xBB, 0xA9, 0x9C, 0x9E, 0x03, 0xC4, 0xFC, 0xBC, 0x3B, 0xCE
/* Mariko Production Master Kek Source. */
.byte 0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1
.byte 0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82
/* Development Master Key Vectors. */
.byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */
@@ -102,7 +102,6 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0xEC, 0xE1, 0x46, 0x89, 0x37, 0xFD, 0xD2, 0x15, 0x8C, 0x3F, 0x24, 0x82, 0xEF, 0x49, 0x68, 0x04 /* Master key 07 encrypted with Master key 08. */
.byte 0x43, 0x3D, 0xC5, 0x3B, 0xEF, 0x91, 0x02, 0x21, 0x61, 0x54, 0x63, 0x8A, 0x35, 0xE7, 0xCA, 0xEE /* Master key 08 encrypted with Master key 09. */
.byte 0x6C, 0x2E, 0xCD, 0xB3, 0x34, 0x61, 0x77, 0xF5, 0xF9, 0xB1, 0xDD, 0x61, 0x98, 0x19, 0x3E, 0xD4 /* Master key 09 encrypted with Master key 0A. */
.byte 0x21, 0x88, 0x6B, 0x10, 0x9E, 0x83, 0xD6, 0x52, 0xAB, 0x08, 0xDB, 0x6D, 0x39, 0xFF, 0x1C, 0x9C /* Master key 0A encrypted with Master key 0B. */
/* Production Master Key Vectors. */
.byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */
@@ -116,37 +115,33 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29 /* Master key 07 encrypted with Master key 08. */
.byte 0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80 /* Master key 08 encrypted with Master key 09. */
.byte 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A /* Master key 09 encrypted with Master key 0A. */
.byte 0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98 /* Master key 0A encrypted with Master key 0B. */
/* Device Master Key Source Sources. */
.byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */
.byte 0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C /* 5.0.0 Device Master Key Source Source. */
.byte 0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4 /* 6.0.0 Device Master Key Source Source. */
.byte 0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17 /* 6.2.0 Device Master Key Source Source. */
.byte 0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D /* 7.0.0 Device Master Key Source Source. */
.byte 0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE /* 8.1.0 Device Master Key Source Source. */
.byte 0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49 /* 9.0.0 Device Master Key Source Source. */
.byte 0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94 /* 9.1.0 Device Master Key Source Source. */
.byte 0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6 /* 12.1.0 Device Master Key Source Source. */
.byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */
.byte 0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C /* 5.0.0 Device Master Key Source Source. */
.byte 0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4 /* 6.0.0 Device Master Key Source Source. */
.byte 0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17 /* 6.2.0 Device Master Key Source Source. */
.byte 0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D /* 7.0.0 Device Master Key Source Source. */
.byte 0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE /* 8.1.0 Device Master Key Source Source. */
.byte 0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49 /* 9.0.0 Device Master Key Source Source. */
.byte 0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94 /* 9.1.0 Device Master Key Source Source. */
/* Development Device Master Kek Sources. */
.byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */
.byte 0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8 /* 5.0.0 Device Master Kek Source. */
.byte 0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5 /* 6.0.0 Device Master Kek Source. */
.byte 0x20, 0xAB, 0xF2, 0x0F, 0x05, 0xE3, 0xDE, 0x2E, 0xA1, 0xFB, 0x37, 0x5E, 0x8B, 0x22, 0x1A, 0x38 /* 6.2.0 Device Master Kek Source. */
.byte 0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE /* 7.0.0 Device Master Kek Source. */
.byte 0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87 /* 8.1.0 Device Master Kek Source. */
.byte 0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F /* 9.0.0 Device Master Kek Source. */
.byte 0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B /* 9.1.0 Device Master Kek Source. */
.byte 0xC4, 0xBB, 0xF3, 0x9F, 0xA3, 0xAA, 0x00, 0x99, 0x7C, 0x97, 0xAD, 0x91, 0x8F, 0xE8, 0x45, 0xCB /* 12.1.0 Device Master Kek Source. */
.byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */
.byte 0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8 /* 5.0.0 Device Master Kek Source. */
.byte 0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5 /* 6.0.0 Device Master Kek Source. */
.byte 0x20, 0xAB, 0xF2, 0x0F, 0x05, 0xE3, 0xDE, 0x2E, 0xA1, 0xFB, 0x37, 0x5E, 0x8B, 0x22, 0x1A, 0x38 /* 6.2.0 Device Master Kek Source. */
.byte 0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE /* 7.0.0 Device Master Kek Source. */
.byte 0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87 /* 8.1.0 Device Master Kek Source. */
.byte 0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F /* 9.0.0 Device Master Kek Source. */
.byte 0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B /* 9.1.0 Device Master Kek Source. */
/* Production Device Master Kek Sources. */
.byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */
.byte 0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E /* 5.0.0 Device Master Kek Source. */
.byte 0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF /* 6.0.0 Device Master Kek Source. */
.byte 0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB /* 6.2.0 Device Master Kek Source. */
.byte 0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E /* 7.0.0 Device Master Kek Source. */
.byte 0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D /* 8.1.0 Device Master Kek Source. */
.byte 0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED /* 9.0.0 Device Master Kek Source. */
.byte 0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36 /* 9.1.0 Device Master Kek Source. */
.byte 0xC2, 0x65, 0x34, 0x6E, 0xC7, 0xC6, 0x5D, 0x97, 0x3E, 0x34, 0x5C, 0x6B, 0xB3, 0x7E, 0xC6, 0xE3 /* 12.1.0 Device Master Kek Source. */
.byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */
.byte 0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E /* 5.0.0 Device Master Kek Source. */
.byte 0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF /* 6.0.0 Device Master Kek Source. */
.byte 0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB /* 6.2.0 Device Master Kek Source. */
.byte 0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E /* 7.0.0 Device Master Kek Source. */
.byte 0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D /* 8.1.0 Device Master Kek Source. */
.byte 0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED /* 9.0.0 Device Master Kek Source. */
.byte 0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36 /* 9.1.0 Device Master Kek Source. */

View File

@@ -94,7 +94,7 @@ namespace ams::secmon::boot {
}
/* Check that the key generation is one that we can use. */
static_assert(pkg1::KeyGeneration_Count == 12);
static_assert(pkg1::KeyGeneration_Count == 11);
if (key_generation >= pkg1::KeyGeneration_Count) {
return false;
}

View File

@@ -272,19 +272,7 @@ namespace ams::secmon::smc {
void GetSecureDataImpl(u8 *dst, SecureData which, bool tweak) {
/* Compute the appropriate AES-CTR. */
{
/* Ensure that the SE sees consistent data. */
hw::FlushDataCache(dst, AesKeySize);
hw::DataSynchronizationBarrierInnerShareable();
/* Perform the appropriate AES operation. */
se::ComputeAes128Ctr(dst, AesKeySize, pkg1::AesKeySlot_Device, SecureDataSource, AesKeySize, GetSecureDataCounter(which), AesKeySize);
hw::DataSynchronizationBarrierInnerShareable();
/* Ensure the CPU sees consistent data. */
hw::FlushDataCache(dst, AesKeySize);
hw::DataSynchronizationBarrierInnerShareable();
}
se::ComputeAes128Ctr(dst, AesKeySize, pkg1::AesKeySlot_Device, SecureDataSource, AesKeySize, GetSecureDataCounter(which), AesKeySize);
/* Tweak, if we should. */
if (tweak) {

View File

@@ -47,9 +47,9 @@ namespace ams::secmon::smc {
[fuse::DramId_IcosaSamsung4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IcosaHynix4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IcosaMicron4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IowaHynix1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_AulaHynix1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IcosaSamsung6GB] = pkg1::MemorySize_6GB,
[fuse::DramId_HoagHynix1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_CopperHynix4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_CopperMicron4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IowaX1X2Samsung4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IowaSansung4GB] = pkg1::MemorySize_4GB,
@@ -243,7 +243,7 @@ namespace ams::secmon::smc {
(static_cast<u64>(ATMOSPHERE_RELEASE_VERSION_MINOR & 0xFF) << 48) |
(static_cast<u64>(ATMOSPHERE_RELEASE_VERSION_MICRO & 0xFF) << 40) |
(static_cast<u64>(GetKeyGeneration()) << 32) |
(static_cast<u64>(GetTargetFirmware()) << 0);
(static_cast<u64>(GetTargetFirmware()) << 00);
break;
case ConfigItem::ExosphereNeedsReboot:
/* We are executing, so we aren't in the process of rebooting. */
@@ -286,16 +286,6 @@ namespace ams::secmon::smc {
/* Get the log configuration. */
args.r[1] = (static_cast<u64>(static_cast<u8>(secmon::GetLogPort())) << 32) | static_cast<u64>(secmon::GetLogBaudRate());
break;
case ConfigItem::ExosphereForceEnableUsb30:
/* Get whether usb 3.0 should be force-enabled. */
args.r[1] = GetSecmonConfiguration().IsUsb30ForceEnabled();
break;
case ConfigItem::ExosphereSupportedHosVersion:
/* Get information about the supported hos version. */
args.r[1] = (static_cast<u64>(ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR & 0xFF) << 24) |
(static_cast<u64>(ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR & 0xFF) << 16) |
(static_cast<u64>(ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO & 0xFF) << 8);
break;
default:
return SmcResult::InvalidArgument;
}

View File

@@ -40,18 +40,16 @@ namespace ams::secmon::smc {
Package2Hash = 17,
/* Extension config items for exosphere. */
ExosphereApiVersion = 65000,
ExosphereNeedsReboot = 65001,
ExosphereNeedsShutdown = 65002,
ExosphereGitCommitHash = 65003,
ExosphereHasRcmBugPatch = 65004,
ExosphereBlankProdInfo = 65005,
ExosphereAllowCalWrites = 65006,
ExosphereEmummcType = 65007,
ExospherePayloadAddress = 65008,
ExosphereLogConfiguration = 65009,
ExosphereForceEnableUsb30 = 65010,
ExosphereSupportedHosVersion = 65011,
ExosphereApiVersion = 65000,
ExosphereNeedsReboot = 65001,
ExosphereNeedsShutdown = 65002,
ExosphereGitCommitHash = 65003,
ExosphereHasRcmBugPatch = 65004,
ExosphereBlankProdInfo = 65005,
ExosphereAllowCalWrites = 65006,
ExosphereEmummcType = 65007,
ExospherePayloadAddress = 65008,
ExosphereLogConfiguration = 65009,
};
SmcResult SmcGetConfigUser(SmcArguments &args);

View File

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

View File

@@ -36,6 +36,7 @@ namespace ams::warmboot {
void Main(const Metadata *metadata) {
/* Ensure that we're running under vaguely sane conditions. */
AMS_ABORT_UNLESS(metadata->magic == Metadata::Magic);
AMS_ABORT_UNLESS(metadata->target_firmware <= ams::TargetFirmware_Max);
/* Restrict the bpmp's access to dram. */
if (metadata->target_firmware >= TargetFirmware_4_0_0) {

View File

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

View File

@@ -17,6 +17,8 @@
#include "../../../fusee/fusee-primary/fusee-primary-main/src/fs_utils.h"
#elif defined(FUSEE_STAGE2_SRC)
#include "../../../fusee/fusee-secondary/src/device_partition.h"
#elif defined(SEPT_STAGE2_SRC)
#include "../../../sept/sept-secondary/src/fs_utils.h"
#endif
#ifdef FUSEE_STAGE2_SRC

View File

@@ -30,6 +30,8 @@
#include "../../../fusee/fusee-primary/fusee-primary-main/src/timers.h"
#elif defined(FUSEE_STAGE2_SRC)
#include "../../../fusee/fusee-secondary/src/timers.h"
#elif defined(SEPT_STAGE2_SRC)
#include "../../../sept/sept-secondary/src/timers.h"
#endif
#define UNSTUFF_BITS(resp,start,size) \
@@ -100,7 +102,7 @@ static int sdmmc_device_send_r1_cmd(sdmmc_device_t *device, uint32_t opcode, uin
if (resp_mask) {
resp &= ~(resp_mask);
}
/* We got an error state. */
if (is_sdmmc_device_r1_error(resp)) {
return 0;
@@ -353,7 +355,7 @@ static int sdmmc_sd_decode_scr(sdmmc_device_t *device, uint8_t *scr) {
if (device->scr.sda_spec3) {
device->scr.cmds = UNSTUFF_BITS(resp, 32, 2);
}
/* Unknown SCR structure version. */
if (UNSTUFF_BITS(resp, 60, 4)) {
return 0;
@@ -463,7 +465,7 @@ static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool i
if (is_uhs_en) {
arg |= SD_OCR_S18R;
}
cmd.opcode = SD_APP_OP_COND;
cmd.arg = arg;
cmd.flags = SDMMC_RSP_R3;
@@ -914,7 +916,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
if (!sdmmc_sd_decode_csd(device, csd)) {
sdmmc_warn(sdmmc, "Got unknown CSD structure (0x%08x)!", device->csd.structure);
}
/* If we never switched to 1.8V, change the bus speed mode. */
if (!device->is_180v) {
/* Reconfigure the internal clock. */
@@ -1153,7 +1155,7 @@ static int sdmmc_mmc_send_op_cond(sdmmc_device_t *device, SdmmcBusVoltage bus_vo
if (resp & SD_OCR_CCS) {
device->is_block_sdhc = true;
}
return 1;
}
@@ -1437,7 +1439,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
if (!sdmmc_mmc_decode_csd(device, csd)) {
sdmmc_warn(sdmmc, "Got unknown CSD structure (0x%08x)!", device->csd.structure);
}
/* Reconfigure the internal clock. */
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_LEGACY)) {
sdmmc_error(sdmmc, "Failed to apply the correct bus speed!");
@@ -1496,7 +1498,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
} else {
sdmmc_info(sdmmc, "BKOPS is disabled!");
}
/* Switch to high speed mode. */
if (!sdmmc_mmc_select_timing(device, bus_speed)) {
sdmmc_error(sdmmc, "Failed to switch to high speed mode!");

View File

@@ -41,6 +41,15 @@
#include "../../../fusee/fusee-secondary/src/gpio.h"
#include "../../../fusee/fusee-secondary/src/pmc.h"
#include "../../../fusee/fusee-secondary/src/max7762x.h"
#elif defined(SEPT_STAGE2_SRC)
#include "../../../sept/sept-secondary/src/car.h"
#include "../../../sept/sept-secondary/src/fuse.h"
#include "../../../sept/sept-secondary/src/pinmux.h"
#include "../../../sept/sept-secondary/src/timers.h"
#include "../../../sept/sept-secondary/src/apb_misc.h"
#include "../../../sept/sept-secondary/src/gpio.h"
#include "../../../sept/sept-secondary/src/pmc.h"
#include "../../../sept/sept-secondary/src/max7762x.h"
#endif
#include "../log.h"

View File

@@ -39,7 +39,6 @@ DEFINES := -D__BPMP__ -DFUSEE_MTC_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -
CFLAGS := \
-g \
-gdwarf-4 \
-O2 \
-fomit-frame-pointer \
-ffunction-sections \
@@ -47,9 +46,6 @@ CFLAGS := \
-std=gnu11 \
-Werror \
-Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \
$(ARCH) $(DEFINES)
@@ -57,8 +53,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g -gdwarf-4 $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS :=

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FUSEE_CAR_H
#define FUSEE_CAR_H
@@ -489,16 +489,7 @@ typedef struct {
uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
uint32_t sdmmc4_pllc4_out1_shaper_ctrl; /* _SDMMC4_PLLC4_OUT1_SHAPER_CTRL_0, 0x73c */
uint32_t sdmmc4_pllc4_out2_shaper_ctrl; /* _SDMMC4_PLLC4_OUT2_SHAPER_CTRL_0, 0x740 */
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
uint32_t _0x748[(0x774-0x748) / sizeof(uint32_t)]; // TODO
uint32_t pllm_ss_cfg; /* _PLLM_SS_CFG_0, 0x744 */
uint32_t pllm_ss_ctrl1; /* _PLLM_SS_CTRL1_0, 0x778 */
uint32_t pllm_ss_ctrl2; /* _PLLM_SS_CTRL2_0, 0x77C */
uint32_t pllmb_ss_cfg; /* _PLLMB_SS_CFG_0, 0x780 */
uint32_t pllmb_ss_ctrl1; /* _PLLMB_SS_CTRL1_0, 0x784 */
uint32_t pllmb_ss_ctrl2; /* _PLLMB_SS_CTRL2_0, 0x788 */
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
} tegra_car_t;
static inline volatile tegra_car_t *car_get_regs(void) {

View File

@@ -19,7 +19,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef FUSEE_EMC_H_
#define FUSEE_EMC_H_
@@ -393,7 +393,6 @@
#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
#define EMC_DIG_DLL_STATUS 0x2c4
#define EMC_DIG_DLL_STATUS_DLL_LOCK (1 << 15)
#define EMC_DIG_DLL_STATUS_DLL_LOCK_B01 (1 << 2)
#define EMC_DIG_DLL_STATUS_DLL_PRIV_UPDATED (1 << 17)
#define EMC_DIG_DLL_STATUS_DLL_OUT_SHIFT 0
#define EMC_DIG_DLL_STATUS_DLL_OUT_MASK \
@@ -1066,10 +1065,6 @@
#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQSN_TX_E_DCC (1 << 16)
#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_CMD_TX_E_DCC (1 << 24)
#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQS_E_IVREF_B01 (1 << 10)
#define EMC_PMACRO_COMMON_PAD_TX_CTRL 0xc68
#define EMC_PMACRO_BRICK_MAPPING_0 0xc80
#define EMC_PMACRO_BRICK_MAPPING_1 0xc84
@@ -1131,8 +1126,4 @@
#define EMC_PMACRO_DSR_VTTGEN_CTRL_0 0xc6c
// B01
#define EMC_PMACRO_DLL_CFG_0 0x5E4
#define EMC_PMACRO_DLL_CFG_1 0x5E8
#endif

View File

@@ -28,28 +28,28 @@ static stage2_mtc_args_t *g_mtc_args;
int main(int argc, void **argv) {
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
/* Check argc. */
if (argc != MTC_ARGC) {
return 1;
}
/* Extract arguments from argv. */
g_mtc_args = &g_mtc_args_store;
memcpy(g_mtc_args, (stage2_mtc_args_t *)argv[MTC_ARGV_ARGUMENT_STRUCT], sizeof(*g_mtc_args));
log_level = g_mtc_args->log_level;
/* Override the global logging level. */
log_set_log_level(log_level);
if (log_level != SCREEN_LOG_LEVEL_NONE) {
/* Set framebuffer address. */
g_framebuffer = (void *)0xC0000000;
/* Zero-fill the framebuffer and register it as printk provider. */
video_init(g_framebuffer);
}
/* Train DRAM. */
train_dram();

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,7 @@
#define TEGRA21_MAX_TABLE_ID_LEN 50
#define TEGRA_EMC_ISO_USE_FREQ_MAX_NUM 12
#define PLL_C_DIRECT_FLOOR 333500000
#define EMC_STATUS_UPDATE_TIMEOUT 2000
#define EMC_STATUS_UPDATE_TIMEOUT 1000
#define TEGRA_EMC_DEFAULT_CLK_LATENCY_US 2000
#define TEGRA_EMC_MODE_REG_17 0x00110000

File diff suppressed because it is too large Load Diff

View File

@@ -1,689 +0,0 @@
/*
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2018 CTCaer <ctcaer@gmail.com>
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FUSEE_MTC_B01_H_
#define FUSEE_MTC_B01_H_
#include "mtc.h"
typedef struct {
uint32_t ptfv_dqsosc_movavg_c0d0u0;
uint32_t ptfv_dqsosc_movavg_c0d0u1;
uint32_t ptfv_dqsosc_movavg_c0d1u0;
uint32_t ptfv_dqsosc_movavg_c0d1u1;
uint32_t ptfv_dqsosc_movavg_c1d0u0;
uint32_t ptfv_dqsosc_movavg_c1d0u1;
uint32_t ptfv_dqsosc_movavg_c1d1u0;
uint32_t ptfv_dqsosc_movavg_c1d1u1;
uint32_t ptfv_write_samples;
uint32_t ptfv_dvfs_samples;
uint32_t ptfv_movavg_weight;
uint32_t ptfv_config_ctrl;
} t210_emc_ptfv_list_table;
typedef struct {
uint32_t emc_rc;
uint32_t emc_rfc;
uint32_t emc_rfcpb;
uint32_t emc_refctrl2;
uint32_t emc_rfc_slr;
uint32_t emc_ras;
uint32_t emc_rp;
uint32_t emc_r2w;
uint32_t emc_w2r;
uint32_t emc_r2p;
uint32_t emc_w2p;
uint32_t emc_r2r;
uint32_t emc_tppd;
uint32_t emc_trtm;
uint32_t emc_twtm;
uint32_t emc_tratm;
uint32_t emc_twatm;
uint32_t emc_tr2ref;
uint32_t emc_ccdmw;
uint32_t emc_rd_rcd;
uint32_t emc_wr_rcd;
uint32_t emc_rrd;
uint32_t emc_rext;
uint32_t emc_wext;
uint32_t emc_wdv_chk;
uint32_t emc_wdv;
uint32_t emc_wsv;
uint32_t emc_wev;
uint32_t emc_wdv_mask;
uint32_t emc_ws_duration;
uint32_t emc_we_duration;
uint32_t emc_quse;
uint32_t emc_quse_width;
uint32_t emc_ibdly;
uint32_t emc_obdly;
uint32_t emc_einput;
uint32_t emc_mrw6;
uint32_t emc_einput_duration;
uint32_t emc_puterm_extra;
uint32_t emc_puterm_width;
uint32_t emc_qrst;
uint32_t emc_qsafe;
uint32_t emc_rdv;
uint32_t emc_rdv_mask;
uint32_t emc_rdv_early;
uint32_t emc_rdv_early_mask;
uint32_t emc_refresh;
uint32_t emc_burst_refresh_num;
uint32_t emc_pre_refresh_req_cnt;
uint32_t emc_pdex2wr;
uint32_t emc_pdex2rd;
uint32_t emc_pchg2pden;
uint32_t emc_act2pden;
uint32_t emc_ar2pden;
uint32_t emc_rw2pden;
uint32_t emc_cke2pden;
uint32_t emc_pdex2cke;
uint32_t emc_pdex2mrr;
uint32_t emc_txsr;
uint32_t emc_txsrdll;
uint32_t emc_tcke;
uint32_t emc_tckesr;
uint32_t emc_tpd;
uint32_t emc_tfaw;
uint32_t emc_trpab;
uint32_t emc_tclkstable;
uint32_t emc_tclkstop;
uint32_t emc_mrw7;
uint32_t emc_trefbw;
uint32_t emc_odt_write;
uint32_t emc_fbio_cfg5;
uint32_t emc_fbio_cfg7;
uint32_t emc_cfg_dig_dll;
uint32_t emc_cfg_dig_dll_period;
uint32_t emc_pmacro_ib_rxrt;
uint32_t emc_cfg_pipe_1;
uint32_t emc_cfg_pipe_2;
uint32_t emc_pmacro_quse_ddll_rank0_4;
uint32_t emc_pmacro_quse_ddll_rank0_5;
uint32_t emc_pmacro_quse_ddll_rank1_4;
uint32_t emc_pmacro_quse_ddll_rank1_5;
uint32_t emc_mrw8;
uint32_t emc_pmacro_ob_ddll_long_dq_rank1_4;
uint32_t emc_pmacro_ob_ddll_long_dq_rank1_5;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_0;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_1;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_2;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_3;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_4;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_5;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_0;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_1;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_2;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_3;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_4;
uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_5;
uint32_t emc_pmacro_ddll_long_cmd_0;
uint32_t emc_pmacro_ddll_long_cmd_1;
uint32_t emc_pmacro_ddll_long_cmd_2;
uint32_t emc_pmacro_ddll_long_cmd_3;
uint32_t emc_pmacro_ddll_long_cmd_4;
uint32_t emc_pmacro_ddll_short_cmd_0;
uint32_t emc_pmacro_ddll_short_cmd_1;
uint32_t emc_pmacro_ddll_short_cmd_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte0_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte1_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte2_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte3_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte4_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte5_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte6_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte7_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd0_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd1_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd2_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd3_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte0_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte1_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte2_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte3_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte4_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte5_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte6_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte7_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd0_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd0_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd0_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd0_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd1_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd1_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd1_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd1_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd2_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd2_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd2_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd2_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd3_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd3_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd3_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_cmd3_3;
uint32_t emc_txdsrvttgen;
uint32_t emc_fdpd_ctrl_dq;
uint32_t emc_fdpd_ctrl_cmd;
uint32_t emc_fbio_spare;
uint32_t emc_zcal_interval;
uint32_t emc_zcal_wait_cnt;
uint32_t emc_mrs_wait_cnt;
uint32_t emc_mrs_wait_cnt2;
uint32_t emc_auto_cal_channel;
uint32_t emc_pmacro_dll_cfg_0;
uint32_t emc_pmacro_dll_cfg_1;
uint32_t emc_pmacro_dll_cfg_2;
uint32_t emc_pmacro_autocal_cfg_common;
uint32_t emc_pmacro_zctrl;
uint32_t emc_cfg;
uint32_t emc_cfg_pipe;
uint32_t emc_dyn_self_ref_control;
uint32_t emc_qpop;
uint32_t emc_dqs_brlshft_0;
uint32_t emc_dqs_brlshft_1;
uint32_t emc_cmd_brlshft_2;
uint32_t emc_cmd_brlshft_3;
uint32_t emc_pmacro_pad_cfg_ctrl;
uint32_t emc_pmacro_data_pad_rx_ctrl;
uint32_t emc_pmacro_cmd_pad_rx_ctrl;
uint32_t emc_pmacro_data_rx_term_mode;
uint32_t emc_pmacro_cmd_rx_term_mode;
uint32_t emc_pmacro_cmd_pad_tx_ctrl;
uint32_t emc_pmacro_data_pad_tx_ctrl;
uint32_t emc_pmacro_vttgen_ctrl_0;
uint32_t emc_pmacro_vttgen_ctrl_1;
uint32_t emc_pmacro_vttgen_ctrl_2;
uint32_t emc_pmacro_brick_ctrl_rfu1;
uint32_t emc_pmacro_cmd_brick_ctrl_fdpd;
uint32_t emc_pmacro_brick_ctrl_rfu2;
uint32_t emc_pmacro_data_brick_ctrl_fdpd;
uint32_t emc_pmacro_bg_bias_ctrl_0;
uint32_t emc_cfg_3;
uint32_t emc_pmacro_tx_pwrd_0;
uint32_t emc_pmacro_tx_pwrd_1;
uint32_t emc_pmacro_tx_pwrd_2;
uint32_t emc_pmacro_tx_pwrd_3;
uint32_t emc_pmacro_tx_pwrd_4;
uint32_t emc_pmacro_tx_pwrd_5;
uint32_t emc_config_sample_delay;
uint32_t emc_pmacro_tx_sel_clk_src_0;
uint32_t emc_pmacro_tx_sel_clk_src_1;
uint32_t emc_pmacro_tx_sel_clk_src_2;
uint32_t emc_pmacro_tx_sel_clk_src_3;
uint32_t emc_pmacro_tx_sel_clk_src_4;
uint32_t emc_pmacro_tx_sel_clk_src_5;
uint32_t emc_pmacro_ddll_bypass;
uint32_t emc_pmacro_ddll_pwrd_0;
uint32_t emc_pmacro_ddll_pwrd_1;
uint32_t emc_pmacro_ddll_pwrd_2;
uint32_t emc_pmacro_cmd_ctrl_0;
uint32_t emc_pmacro_cmd_ctrl_1;
uint32_t emc_pmacro_cmd_ctrl_2;
uint32_t emc_pmacro_data_pi_ctrl;
uint32_t emc_pmacro_cmd_pi_ctrl;
uint32_t emc_tr_timing_0;
uint32_t emc_tr_dvfs;
uint32_t emc_tr_ctrl_1;
uint32_t emc_tr_rdv;
uint32_t emc_tr_qpop;
uint32_t emc_tr_rdv_mask;
uint32_t emc_mrw14;
uint32_t emc_tr_qsafe;
uint32_t emc_tr_qrst;
uint32_t emc_training_ctrl;
uint32_t emc_training_settle;
uint32_t emc_training_vref_settle;
uint32_t emc_training_ca_fine_ctrl;
uint32_t emc_training_ca_ctrl_misc;
uint32_t emc_training_ca_ctrl_misc1;
uint32_t emc_training_ca_vref_ctrl;
uint32_t emc_training_quse_cors_ctrl;
uint32_t emc_training_quse_fine_ctrl;
uint32_t emc_training_quse_ctrl_misc;
uint32_t emc_training_quse_vref_ctrl;
uint32_t emc_training_read_fine_ctrl;
uint32_t emc_training_read_ctrl_misc;
uint32_t emc_training_read_vref_ctrl;
uint32_t emc_training_write_fine_ctrl;
uint32_t emc_training_write_ctrl_misc;
uint32_t emc_training_write_vref_ctrl;
uint32_t emc_training_mpc;
uint32_t emc_mrw15;
} t210b01_emc_burst_regs;
typedef struct {
uint32_t emc0_mrw10;
uint32_t emc1_mrw10;
uint32_t emc0_mrw11;
uint32_t emc1_mrw11;
uint32_t emc0_mrw12;
uint32_t emc1_mrw12;
uint32_t emc0_mrw13;
uint32_t emc1_mrw13;
} t210_emc_burst_reg_per_ch;
typedef struct {
uint32_t emc_pmacro_ib_ddll_long_dqs_rank0_0;
uint32_t emc_pmacro_ib_ddll_long_dqs_rank0_1;
uint32_t emc_pmacro_ib_ddll_long_dqs_rank0_2;
uint32_t emc_pmacro_ib_ddll_long_dqs_rank0_3;
uint32_t emc_pmacro_ib_ddll_long_dqs_rank1_0;
uint32_t emc_pmacro_ib_ddll_long_dqs_rank1_1;
uint32_t emc_pmacro_ib_ddll_long_dqs_rank1_2;
uint32_t emc_pmacro_ib_ddll_long_dqs_rank1_3;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte0_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte0_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte0_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte1_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte1_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte1_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte2_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte2_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte2_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte3_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte3_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte3_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte4_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte4_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte4_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte5_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte5_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte5_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte6_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte6_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte6_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte7_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte7_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank0_byte7_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte0_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte0_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte0_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte1_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte1_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte1_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte2_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte2_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte2_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte3_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte3_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte3_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte4_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte4_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte4_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte5_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte5_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte5_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte6_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte6_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte6_2;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte7_0;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte7_1;
uint32_t emc_pmacro_ib_ddll_short_dq_rank1_byte7_2;
uint32_t emc_pmacro_ib_vref_dqs_0;
uint32_t emc_pmacro_ib_vref_dqs_1;
uint32_t emc_pmacro_ib_vref_dq_0;
uint32_t emc_pmacro_ib_vref_dq_1;
uint32_t emc_pmacro_ob_ddll_long_dq_rank0_0;
uint32_t emc_pmacro_ob_ddll_long_dq_rank0_1;
uint32_t emc_pmacro_ob_ddll_long_dq_rank0_2;
uint32_t emc_pmacro_ob_ddll_long_dq_rank0_3;
uint32_t emc_pmacro_ob_ddll_long_dq_rank0_4;
uint32_t emc_pmacro_ob_ddll_long_dq_rank0_5;
uint32_t emc_pmacro_ob_ddll_long_dq_rank1_0;
uint32_t emc_pmacro_ob_ddll_long_dq_rank1_1;
uint32_t emc_pmacro_ob_ddll_long_dq_rank1_2;
uint32_t emc_pmacro_ob_ddll_long_dq_rank1_3;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte0_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte0_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte0_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte1_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte1_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte1_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte2_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte2_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte2_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte3_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte3_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte3_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte4_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte4_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte4_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte5_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte5_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte5_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte6_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte6_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte6_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte7_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte7_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_byte7_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd0_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd0_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd0_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd1_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd1_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd1_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd2_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd2_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd2_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd3_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd3_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank0_cmd3_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte0_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte0_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte0_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte1_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte1_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte1_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte2_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte2_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte2_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte3_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte3_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte3_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte4_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte4_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte4_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte5_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte5_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte5_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte6_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte6_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte6_2;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte7_0;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte7_1;
uint32_t emc_pmacro_ob_ddll_short_dq_rank1_byte7_2;
uint32_t emc_pmacro_quse_ddll_rank0_0;
uint32_t emc_pmacro_quse_ddll_rank0_1;
uint32_t emc_pmacro_quse_ddll_rank0_2;
uint32_t emc_pmacro_quse_ddll_rank0_3;
uint32_t emc_pmacro_quse_ddll_rank1_0;
uint32_t emc_pmacro_quse_ddll_rank1_1;
uint32_t emc_pmacro_quse_ddll_rank1_2;
uint32_t emc_pmacro_quse_ddll_rank1_3;
} t210_emc_trim_regs;
typedef struct {
uint32_t emc_cmd_brlshft_0;
uint32_t emc_cmd_brlshft_1;
uint32_t emc0_data_brlshft_0;
uint32_t emc1_data_brlshft_0;
uint32_t emc0_data_brlshft_1;
uint32_t emc1_data_brlshft_1;
uint32_t emc_quse_brlshft_0;
uint32_t emc_quse_brlshft_1;
uint32_t emc_quse_brlshft_2;
uint32_t emc_quse_brlshft_3;
} t210_emc_trim_perch_regs;
typedef struct {
uint32_t emc0_training_opt_dqs_ib_vref_rank0;
uint32_t emc1_training_opt_dqs_ib_vref_rank0;
uint32_t emc0_training_opt_dqs_ib_vref_rank1;
uint32_t emc1_training_opt_dqs_ib_vref_rank1;
} t210_emc_vref_perch_regs;
typedef struct {
uint32_t t_rp;
uint32_t t_fc_lpddr4;
uint32_t t_rfc;
uint32_t t_pdex;
uint32_t rl;
} t210_emc_dram_timings;
typedef struct {
uint32_t emc0_training_rw_offset_ib_byte0;
uint32_t emc1_training_rw_offset_ib_byte0;
uint32_t emc0_training_rw_offset_ib_byte1;
uint32_t emc1_training_rw_offset_ib_byte1;
uint32_t emc0_training_rw_offset_ib_byte2;
uint32_t emc1_training_rw_offset_ib_byte2;
uint32_t emc0_training_rw_offset_ib_byte3;
uint32_t emc1_training_rw_offset_ib_byte3;
uint32_t emc0_training_rw_offset_ib_misc;
uint32_t emc1_training_rw_offset_ib_misc;
uint32_t emc0_training_rw_offset_ob_byte0;
uint32_t emc1_training_rw_offset_ob_byte0;
uint32_t emc0_training_rw_offset_ob_byte1;
uint32_t emc1_training_rw_offset_ob_byte1;
uint32_t emc0_training_rw_offset_ob_byte2;
uint32_t emc1_training_rw_offset_ob_byte2;
uint32_t emc0_training_rw_offset_ob_byte3;
uint32_t emc1_training_rw_offset_ob_byte3;
uint32_t emc0_training_rw_offset_ob_misc;
uint32_t emc1_training_rw_offset_ob_misc;
} t210_emc_training_mod_regs;
typedef struct {
uint32_t mc_emem_arb_cfg;
uint32_t mc_emem_arb_outstanding_req;
uint32_t mc_emem_arb_refpb_hp_ctrl;
uint32_t mc_emem_arb_refpb_bank_ctrl;
uint32_t mc_emem_arb_timing_rcd;
uint32_t mc_emem_arb_timing_rp;
uint32_t mc_emem_arb_timing_rc;
uint32_t mc_emem_arb_timing_ras;
uint32_t mc_emem_arb_timing_faw;
uint32_t mc_emem_arb_timing_rrd;
uint32_t mc_emem_arb_timing_rap2pre;
uint32_t mc_emem_arb_timing_wap2pre;
uint32_t mc_emem_arb_timing_r2r;
uint32_t mc_emem_arb_timing_w2w;
uint32_t mc_emem_arb_timing_r2w;
uint32_t mc_emem_arb_timing_ccdmw;
uint32_t mc_emem_arb_timing_w2r;
uint32_t mc_emem_arb_timing_rfcpb;
uint32_t mc_emem_arb_da_turns;
uint32_t mc_emem_arb_da_covers;
uint32_t mc_emem_arb_misc0;
uint32_t mc_emem_arb_misc1;
uint32_t mc_emem_arb_misc2;
uint32_t mc_emem_arb_ring1_throttle;
uint32_t mc_emem_arb_dhyst_ctrl;
uint32_t mc_emem_arb_dhyst_timeout_util_0;
uint32_t mc_emem_arb_dhyst_timeout_util_1;
uint32_t mc_emem_arb_dhyst_timeout_util_2;
uint32_t mc_emem_arb_dhyst_timeout_util_3;
uint32_t mc_emem_arb_dhyst_timeout_util_4;
uint32_t mc_emem_arb_dhyst_timeout_util_5;
uint32_t mc_emem_arb_dhyst_timeout_util_6;
uint32_t mc_emem_arb_dhyst_timeout_util_7;
} t210_emc_burst_mc_regs;
typedef struct {
uint32_t mc_mll_mpcorer_ptsa_rate;
uint32_t mc_ftop_ptsa_rate;
uint32_t mc_ptsa_grant_decrement;
uint32_t mc_latency_allowance_xusb_0;
uint32_t mc_latency_allowance_xusb_1;
uint32_t mc_latency_allowance_tsec_0;
uint32_t mc_latency_allowance_sdmmca_0;
uint32_t mc_latency_allowance_sdmmcaa_0;
uint32_t mc_latency_allowance_sdmmc_0;
uint32_t mc_latency_allowance_sdmmcab_0;
uint32_t mc_latency_allowance_ppcs_0;
uint32_t mc_latency_allowance_ppcs_1;
uint32_t mc_latency_allowance_mpcore_0;
uint32_t mc_latency_allowance_hc_0;
uint32_t mc_latency_allowance_hc_1;
uint32_t mc_latency_allowance_avpc_0;
uint32_t mc_latency_allowance_gpu_0;
uint32_t mc_latency_allowance_gpu2_0;
uint32_t mc_latency_allowance_nvenc_0;
uint32_t mc_latency_allowance_nvdec_0;
uint32_t mc_latency_allowance_vic_0;
uint32_t mc_latency_allowance_vi2_0;
uint32_t mc_latency_allowance_isp2_0;
uint32_t mc_latency_allowance_isp2_1;
} t210_emc_la_scale_regs;
typedef struct {
uint32_t rev;
char dvfs_ver[60];
uint32_t rate_khz;
uint32_t min_volt;
uint32_t gpu_min_volt;
char clock_src[32];
uint32_t clk_src_emc;
uint32_t pll_en_ssc;
uint32_t needs_training;
uint32_t training_pattern;
uint32_t trained;
uint32_t periodic_training;
uint32_t trained_dram_clktree_c0d0u0;
uint32_t trained_dram_clktree_c0d0u1;
uint32_t trained_dram_clktree_c0d1u0;
uint32_t trained_dram_clktree_c0d1u1;
uint32_t trained_dram_clktree_c1d0u0;
uint32_t trained_dram_clktree_c1d0u1;
uint32_t trained_dram_clktree_c1d1u0;
uint32_t trained_dram_clktree_c1d1u1;
uint32_t current_dram_clktree_c0d0u0;
uint32_t current_dram_clktree_c0d0u1;
uint32_t current_dram_clktree_c0d1u0;
uint32_t current_dram_clktree_c0d1u1;
uint32_t current_dram_clktree_c1d0u0;
uint32_t current_dram_clktree_c1d0u1;
uint32_t current_dram_clktree_c1d1u0;
uint32_t current_dram_clktree_c1d1u1;
uint32_t emc_fbio_cfg7;
uint32_t run_clocks;
uint32_t tree_margin;
uint32_t num_burst;
uint32_t num_burst_per_ch;
uint32_t num_trim;
uint32_t num_trim_per_ch;
uint32_t num_mc_regs;
uint32_t num_up_down;
uint32_t vref_num;
uint32_t training_mod_num;
uint32_t dram_timing_num;
t210_emc_ptfv_list_table ptfv_list;
union {
t210b01_emc_burst_regs burst_regs;
uint32_t burst_regs_arr[sizeof(t210b01_emc_burst_regs) / sizeof(uint32_t)];
};
union {
t210_emc_burst_reg_per_ch burst_reg_per_ch;
uint32_t burst_reg_per_ch_arr[sizeof(t210_emc_burst_reg_per_ch) / sizeof(uint32_t)];
};
union {
t210b01_emc_burst_regs shadow_regs_ca_train;
uint32_t shadow_regs_ca_train_arr[sizeof(t210b01_emc_burst_regs) / sizeof(uint32_t)];
};
union {
t210b01_emc_burst_regs shadow_regs_rdwr_train;
uint32_t shadow_regs_rdwr_train_arr[sizeof(t210b01_emc_burst_regs) / sizeof(uint32_t)];
};
union {
t210_emc_trim_regs trim_regs;
uint32_t trim_regs_arr[sizeof(t210_emc_trim_regs) / sizeof(uint32_t)];
};
union {
t210_emc_trim_perch_regs trim_perch_regs;
uint32_t trim_perch_regs_arr[sizeof(t210_emc_trim_perch_regs) / sizeof(uint32_t)];
};
union {
t210_emc_vref_perch_regs vref_perch_regs;
uint32_t vref_perch_regs_arr[sizeof(t210_emc_vref_perch_regs) / sizeof(uint32_t)];
};
t210_emc_dram_timings dram_timings;
uint32_t zq_op_cc_long_zcal;
uint32_t zq_op_cc_short_zcal;
uint32_t zcal_wait_time_ps_cc_long_zcal;
uint32_t zcal_wait_time_ps_cc_short_zcal;
uint32_t tZQCAL_lpddr4;
uint32_t zqcal_before_cc_cutoff;
uint32_t opt_cc_short_zcal;
uint32_t opt_short_zcal;
uint32_t opt_do_sw_qrst;
uint32_t save_restore_clkstop_pd;
uint32_t opt_E90;
uint32_t cya_allow_ref_cc;
uint32_t ref_b4_sref_en;
uint32_t cya_issue_pc_ref;
union {
t210_emc_training_mod_regs training_mod_regs;
uint32_t training_mod_regs_arr[sizeof(t210_emc_training_mod_regs) / sizeof(uint32_t)];
};
uint32_t save_restore_mod_regs[12];
union {
t210_emc_burst_mc_regs burst_mc_regs;
uint32_t burst_mc_regs_arr[sizeof(t210_emc_burst_mc_regs) / sizeof(uint32_t)];
};
union {
t210_emc_la_scale_regs la_scale_regs;
uint32_t la_scale_regs_arr[sizeof(t210_emc_la_scale_regs) / sizeof(uint32_t)];
};
uint32_t unk_0;
uint32_t vtt_vdda_ctrl_0;
uint32_t src_clock_div;
uint32_t vtt_vdda_dual_channel;
uint32_t vtt_vdda_ctrl_1;
uint32_t vtt_vdda_ctrl_2;
uint32_t vtt_vdda_ctrl_3;
uint32_t vtt_vdda_ctrl_4;
uint32_t misc_cfg_0;
uint32_t misc_cfg_1;
uint32_t misc_cfg_2;
uint32_t unk_1;
uint32_t unk_2;
uint32_t pipe_clk_delay;
uint32_t clkchange_delay;
uint32_t pllm_ss_cfg;
uint32_t pllm_ss_ctrl1;
uint32_t pllm_ss_ctrl2;
uint32_t pllmb_ss_cfg;
uint32_t pllmb_ss_ctrl1;
uint32_t pllmb_ss_ctrl2;
uint32_t pllmb_divm;
uint32_t pllmb_divn;
uint32_t pllmb_divp;
uint32_t min_mrs_wait;
uint32_t ramp_wait;
uint32_t emc_mrw;
uint32_t emc_mrw2;
uint32_t emc_mrw3;
uint32_t emc_mrw4;
uint32_t emc_mrw9;
uint32_t emc_mrs;
uint32_t emc_emrs;
uint32_t emc_emrs2;
uint32_t emc_auto_cal_config;
uint32_t emc_auto_cal_config2;
uint32_t emc_auto_cal_config3;
uint32_t emc_auto_cal_config4;
uint32_t emc_auto_cal_config5;
uint32_t emc_auto_cal_config6;
uint32_t emc_auto_cal_config7;
uint32_t emc_auto_cal_config8;
uint32_t emc_cfg_2;
uint32_t emc_sel_dpd_ctrl;
uint32_t emc_fdpd_ctrl_cmd_no_ramp;
uint32_t emc_tr_ctrl_0;
uint32_t dll_clk_src;
uint32_t clk_out_enb_x_0_clk_enb_emc_dll;
uint32_t latency;
uint32_t pllm_misc1_0_pllm_clamp_ph90;
} tegra_b01_emc_timing_t;
_Static_assert(sizeof(tegra_b01_emc_timing_t) == 0x10CC);
void train_dram_mariko(void);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#include <stdarg.h>
#include "utils.h"
@@ -31,18 +31,18 @@ __attribute__((noreturn)) void fatal_error(const char *fmt, ...) {
if (log_get_log_level() == SCREEN_LOG_LEVEL_NONE) {
/* Zero-fill the framebuffer and register it as printk provider. */
video_init((void *)0xC0000000);
/* Override the global logging level. */
log_set_log_level(SCREEN_LOG_LEVEL_ERROR);
}
/* Display fatal error. */
va_list args;
print(SCREEN_LOG_LEVEL_ERROR, "Fatal error: ");
va_start(args, fmt);
vprint(SCREEN_LOG_LEVEL_ERROR, fmt, args);
va_end(args);
while (true) {
/* Lock. */
}

View File

@@ -46,7 +46,6 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
CFLAGS := \
-g \
-gdwarf-4 \
-O2 \
-fomit-frame-pointer \
-ffunction-sections \
@@ -54,9 +53,6 @@ CFLAGS := \
-std=gnu11 \
-Werror \
-Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \
$(ARCH) $(DEFINES)
@@ -64,8 +60,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g -gdwarf-4 $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS :=

View File

@@ -39,7 +39,6 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
CFLAGS := \
-g \
-gdwarf-4 \
-O2 \
-fomit-frame-pointer \
-ffunction-sections \
@@ -47,9 +46,6 @@ CFLAGS := \
-std=gnu11 \
-Werror \
-Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \
$(ARCH) $(DEFINES)
@@ -57,8 +53,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g -gdwarf-4 $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS :=

View File

@@ -158,12 +158,7 @@ static void config_se_brom(void) {
/* Bootrom part we skipped. */
uint32_t sbk[4] = {fuse_chip->FUSE_PRIVATE_KEY[0], fuse_chip->FUSE_PRIVATE_KEY[1], fuse_chip->FUSE_PRIVATE_KEY[2], fuse_chip->FUSE_PRIVATE_KEY[3]};
for (int i = 0; i < 4; ++i) {
if (sbk[i] != 0xFFFFFFFF) {
set_aes_keyslot(0xE, sbk, 0x10);
break;
}
}
set_aes_keyslot(0xE, sbk, 0x10);
/* Lock SBK from being read. */
se->SE_CRYPTO_KEYTABLE_ACCESS[0xE] = 0x7E;
@@ -252,7 +247,7 @@ void nx_hwinit(bool enable_log) {
} else {
uint8_t val = 0x40;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
val = 0x58;
val = 0x60;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
val = 0x38;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1);

View File

@@ -48,7 +48,6 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE2_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
CFLAGS := \
-g \
-gdwarf-4 \
-O2 \
-fomit-frame-pointer \
-ffunction-sections \
@@ -56,9 +55,6 @@ CFLAGS := \
-std=gnu11 \
-Werror \
-Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \
$(ARCH) $(DEFINES)
@@ -66,8 +62,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g -gdwarf-4 $(ARCH) $(INCLUDE) $(DEFINES)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
ASFLAGS := -g $(ARCH) $(INCLUDE) $(DEFINES)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS :=
@@ -92,8 +88,8 @@ export KIPDIRS := $(AMS)/stratosphere/loader $(AMS)/stratosphere/ncm $(AMS)/stra
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
$(AMS)/exosphere $(AMS)/exosphere/warmboot $(AMS)/exosphere/program/rebootstub \
$(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/emummc $(AMS)/mesosphere \
$(KIPDIRS)
$(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/sept/sept-primary \
$(AMS)/sept/sept-secondary $(AMS)/emummc $(AMS)/mesosphere $(AMS)/mesosphere/kernel_ldr $(KIPDIRS)
export DEPSDIR := $(CURDIR)/$(BUILD)
@@ -103,7 +99,9 @@ SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
KIPFILES := loader.kip ncm.kip pm.kip sm.kip ams_mitm.kip spl.kip boot.kip
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin \
exosphere.bin warmboot.bin rebootstub.bin thermosphere.bin splash_screen.bin \
emummc.kip mesosphere.bin mariko_fatal.bin $(KIPFILES)
sept-primary.bin sept-secondary_00.enc sept-secondary_01.enc emummc.kip \
sept-secondary_dev_00.enc sept-secondary_dev_01.enc mesosphere.bin kernel_ldr.bin \
mariko_fatal.bin $(KIPFILES)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
@@ -131,7 +129,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
.PHONY: $(BUILD) clean all
.PHONY: check_fusee_primary check_exosphere check_emummc check_thermosphere check_stratosphere check_libraries
.PHONY: check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_stratosphere check_libraries
#---------------------------------------------------------------------------------
all: $(BUILD)
@@ -142,6 +140,9 @@ check_fusee_primary:
check_exosphere:
@$(MAKE) -C $(AMS)/exosphere all
check_sept:
@$(MAKE) -C $(AMS)/sept all
check_emummc:
@$(MAKE) -C $(AMS)/emummc EMUMMCDIR=$(AMS)/emummc all
@@ -158,7 +159,7 @@ check_libraries:
@$(MAKE) -C $(AMS)/libraries all
$(BUILD): check_fusee_primary check_exosphere check_emummc check_thermosphere check_libraries check_stratosphere check_mesosphere
$(BUILD): check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_libraries check_stratosphere check_mesosphere
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
@@ -171,6 +172,7 @@ clean:
@$(MAKE) -C $(AMS)/libraries clean
@$(MAKE) -C $(AMS)/mesosphere clean
@$(MAKE) -C $(AMS)/stratosphere clean
@$(MAKE) -C $(AMS)/sept clean
@$(MAKE) -C $(AMS)/emummc clean
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
@@ -210,6 +212,31 @@ fusee_primary.bin.o fusee_primary_bin.h: fusee-primary.bin
@echo $(notdir $<)
@$(_bin2o)
sept_primary.bin.o sept_primary_bin.h: sept-primary.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
sept_secondary_00.enc.o sept_secondary_00_enc.h: sept-secondary_00.enc
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
sept_secondary_01.enc.o sept_secondary_01_enc.h: sept-secondary_01.enc
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
sept_secondary_dev_00.enc.o sept_secondary_dev_00_enc.h: sept-secondary_dev_00.enc
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
sept_secondary_dev_01.enc.o sept_secondary_dev_01_enc.h: sept-secondary_dev_01.enc
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
%.bin.o %_bin.h: %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)

View File

@@ -244,6 +244,12 @@ SECTIONS
PROVIDE(__pm_kip_size__ = pm_kip_end - pm_kip);
PROVIDE(__rebootstub_bin_start__ = rebootstub_bin - __start__);
PROVIDE(__rebootstub_bin_size__ = rebootstub_bin_end - rebootstub_bin);
PROVIDE(__sept_primary_bin_start__ = sept_primary_bin - __start__);
PROVIDE(__sept_primary_bin_size__ = sept_primary_bin_end - sept_primary_bin);
PROVIDE(__sept_secondary_00_enc_start__ = sept_secondary_00_enc - __start__);
PROVIDE(__sept_secondary_00_enc_size__ = sept_secondary_00_enc_end - sept_secondary_00_enc);
PROVIDE(__sept_secondary_01_enc_start__ = sept_secondary_01_enc - __start__);
PROVIDE(__sept_secondary_01_enc_size__ = sept_secondary_01_enc_end - sept_secondary_01_enc);
PROVIDE(__sm_kip_start__ = sm_kip - __start__);
PROVIDE(__sm_kip_size__ = sm_kip_end - sm_kip);
PROVIDE(__spl_kip_start__ = spl_kip - __start__);
@@ -260,6 +266,4 @@ SECTIONS
PROVIDE(__mesosphere_bin_size__ = mesosphere_bin_end - mesosphere_bin);
PROVIDE(__mariko_fatal_bin_start__ = mariko_fatal_bin - __start__);
PROVIDE(__mariko_fatal_bin_size__ = mariko_fatal_bin_end - mariko_fatal_bin);
PROVIDE(__tsec_keygen_bin_start__ = tsec_keygen_bin - __start__);
PROVIDE(__tsec_keygen_bin_size__ = tsec_keygen_bin_end - tsec_keygen_bin);
}

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FUSEE_CAR_H
#define FUSEE_CAR_H
@@ -51,7 +51,7 @@ typedef enum {
CARDEVICE_USB2 = ((1 << 5) | 0x1A),
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
CARDEVICE_TSEC = ((2 << 5) | 0x13),
CARDEVICE_MSELECT = ((3 << 5) | 0x3),
CARDEVICE_MSELECT = ((3 << 5) | 0x8),
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
CARDEVICE_SE = ((3 << 5) | 0x1F),
@@ -489,7 +489,7 @@ typedef struct {
uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
uint32_t sdmmc4_pllc4_out1_shaper_ctrl; /* _SDMMC4_PLLC4_OUT1_SHAPER_CTRL_0, 0x73c */
uint32_t sdmmc4_pllc4_out2_shaper_ctrl; /* _SDMMC4_PLLC4_OUT2_SHAPER_CTRL_0, 0x740 */
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
} tegra_car_t;
static inline volatile tegra_car_t *car_get_regs(void) {

View File

@@ -91,12 +91,6 @@ typedef enum {
FS_VER_11_0_0,
FS_VER_11_0_0_EXFAT,
FS_VER_12_0_0,
FS_VER_12_0_0_EXFAT,
FS_VER_12_0_3,
FS_VER_12_0_3_EXFAT,
FS_VER_MAX,
} emummc_fs_ver_t;

View File

@@ -33,7 +33,6 @@
#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_FLAG_FORCE_ENABLE_USB_30 (1 << 7u)
#define EXOSPHERE_LOG_FLAG_INVERTED (1 << 0u)

View File

@@ -348,7 +348,6 @@ uint32_t fuse_get_regulator(void) {
static const uint32_t fuse_version_increment_firmwares[] = {
ATMOSPHERE_TARGET_FIRMWARE_12_0_2,
ATMOSPHERE_TARGET_FIRMWARE_11_0_0,
ATMOSPHERE_TARGET_FIRMWARE_10_0_0,
ATMOSPHERE_TARGET_FIRMWARE_9_1_0,

View File

@@ -426,12 +426,6 @@ static const uint8_t g_fs_hashes[FS_VER_MAX][0x8] = {
"\xE3\x99\x15\x6E\x84\x4E\xB0\xAA", /* FS_VER_11_0_0 */
"\x0B\xA1\x5B\xB3\x04\xB5\x05\x63", /* FS_VER_11_0_0_EXFAT */
"\xDC\x2A\x08\x49\x96\xBB\x3C\x01", /* FS_VER_12_0_0 */
"\xD5\xA5\xBF\x36\x64\x0C\x49\xEA", /* FS_VER_12_0_0_EXFAT */
"\xC8\x67\x62\xBE\x19\xA5\x1F\xA0", /* FS_VER_12_0_3 */
"\xE1\xE8\xD3\xD6\xA2\xFE\x0B\x10", /* FS_VER_12_0_3_EXFAT */
};
kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size, emummc_fs_ver_t *out_fs_ver) {

View File

@@ -21,6 +21,12 @@
#include "kernel_patches.h"
#include "ips.h"
#define u8 uint8_t
#define u32 uint32_t
#include "kernel_ldr_bin.h"
#undef u8
#undef u32
#define MAKE_BRANCH(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
#define MAKE_NOP 0xD503201F
@@ -562,7 +568,6 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv)[] = {0xA9B
*/
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1100, proc_id_send)[] = {0xE0, 0x03, 0x15, 0xAA, 0xA8, 0x02, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0x88, 0x4A, 0x3C, 0x8B, 0x09, 0xFC, 0x60, 0xD3, 0x00, 0x25, 0x00, 0x29};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_send)[] = {0xA9BF2FEA, 0xF94043EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/*
stp x10, x11, [sp, #-0x10]!
ldr x11, [sp, #0xE0]
@@ -591,63 +596,6 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_send)[] = {0xA9B
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1100, proc_id_recv)[] = {0x08, 0x03, 0x40, 0xF9, 0xE0, 0x03, 0x18, 0xAA, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x7F, 0x40, 0xF9, 0x09, 0xFC, 0x60, 0xD3, 0xEA, 0x5B, 0x40, 0xF9};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_recv)[] = {0xA9BF2FEA, 0xF94073EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/*
stp x10, x11, [sp, #-0x10]!
ldr x11, [sp, #0x98]
mov w10, #3
lsl x10, x10, #2
ldr x10, [x11, x10]
mov x9, #0x0000ffffffffffff
and x8, x10, x9
mov x9, #0xffff000000000000
and x10, x10, x9
mov x9, #0xfffe000000000000
cmp x10, x9
beq #0x20
stp x8, x9, [sp, #-0x10]!
ldr x8, [x22]
ldr x8, [x8, #0x38]
mov x0, x22
blr x8
ldp x8, x9, [sp],#0x10
mov x8, x0
ldp x10, x11, [sp],#0x10
mov x0, x8
*/
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1200, proc_id_send)[] = {0xE0, 0x03, 0x16, 0xAA, 0xC8, 0x02, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0xA8, 0x4A, 0x3B, 0x8B, 0x09, 0xFC, 0x60, 0xD3, 0x00, 0x25, 0x00, 0x29};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1200, proc_id_send)[] = {0xA9BF2FEA, 0xF9404FEB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002C8, 0xF9401D08, 0xAA1603E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/*
stp x10, x11, [sp, #-0x10]!
ldr x11, [sp, #0xE0]
mov w10, #3
lsl x10, x10, #2
ldr x10, [x11, x10]
mov x9, #0x0000ffffffffffff
and x8, x10, x9
mov x9, #0xffff000000000000
and x10, x10, x9
mov x9, #0xfffe000000000000
cmp x10, x9
beq #0x20
stp x8, x9, [sp, #-0x10]!
ldr x8, [x28]
ldr x8, [x8, #0x38]
mov x0, x28
blr x8
ldp x8, x9, [sp],#0x10
mov x8, x0
ldp x10, x11, [sp],#0x10
mov x0, x8
*/
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1200, proc_id_recv)[] = {0x88, 0x03, 0x40, 0xF9, 0xE0, 0x03, 0x1C, 0xAA, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0x08, 0x4B, 0x3A, 0x8B, 0x09, 0xFC, 0x60, 0xD3, 0x00, 0x25, 0x00, 0x29};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1200, proc_id_recv)[] = {0xA9BF2FEA, 0xF94073EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/* svcControlCodeMemory Patches */
/* b.eq -> nop */
static const instruction_t MAKE_KERNEL_PATCH_NAME(500, svc_control_codememory)[] = {MAKE_NOP};
@@ -657,7 +605,6 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(800, svc_control_codememory)[
static const instruction_t MAKE_KERNEL_PATCH_NAME(900, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1200, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(500, system_memory_increase)[] = {0x52A3C008}; /* MOV W8, #0x1E000000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(600, system_memory_increase)[] = {0x52A3B008}; /* MOV W8, #0x1D800000 */
@@ -666,7 +613,6 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(800, system_memory_increase)[
static const instruction_t MAKE_KERNEL_PATCH_NAME(900, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, system_memory_increase)[] = {0x52A3B015}; /* MOV W21, #0x1D800000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(1200, system_memory_increase)[] = {0x52A3B015}; /* MOV W21, #0x1D800000 */
/* Hook Definitions. */
static const kernel_patch_t g_kernel_patches_100[] = {
@@ -989,35 +935,6 @@ static const kernel_patch_t g_kernel_patches_1101[] = {
}
};
static const kernel_patch_t g_kernel_patches_1200[] = {
{ /* Send Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(1200, proc_id_send),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1200, proc_id_send))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_PATCH_NAME(1200, proc_id_send)
},
{ /* Receive Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(1200, proc_id_recv),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1200, proc_id_recv))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_PATCH_NAME(1200, proc_id_recv)
},
{ /* svcControlCodeMemory Patch. */
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1200, svc_control_codememory))/sizeof(instruction_t),
.payload = MAKE_KERNEL_PATCH_NAME(1200, svc_control_codememory),
.patch_offset = 0x2FCB4,
},
{ /* System Memory Increase Patch. */
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1200, system_memory_increase))/sizeof(instruction_t),
.payload = MAKE_KERNEL_PATCH_NAME(1200, system_memory_increase),
.patch_offset = 0x4809C,
}
};
#define KERNEL_PATCHES(vers) .num_patches = sizeof(g_kernel_patches_##vers)/sizeof(kernel_patch_t), .patches = g_kernel_patches_##vers,
/* Kernel Infos. */
@@ -1121,15 +1038,6 @@ static const kernel_info_t g_kernel_infos[] = {
.embedded_ini_ptr = 0x180,
.free_code_space_offset = 0x49EE8,
KERNEL_PATCHES(1101)
},
{ /* 12.0.0. */
.hash = {0x8D, 0x4A, 0x1E, 0xFC, 0xCC, 0x6C, 0xFE, 0x6C, 0x45, 0x14, 0x13, 0xA1, 0x7F, 0xF6, 0xDF, 0xFD, 0x7E, 0x5D, 0xD1, 0x38, 0xCE, 0x86, 0x11, 0x8B, 0x58, 0x5F, 0x89, 0x67, 0x84, 0x48, 0xA8, 0x17, },
.hash_offset = 0x1C4,
.hash_size = 0x68000 - 0x1C4,
.embedded_ini_offset = 0x68000,
.embedded_ini_ptr = 0x180,
.free_code_space_offset = 0x48810,
KERNEL_PATCHES(1200)
}
};

View File

@@ -26,6 +26,19 @@
#define AL16 ALIGN(16)
static const uint8_t AL16 keyblob_seeds[MASTERKEY_REVISION_MAX][0x10] = {
{0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3}, /* Keyblob seed 00. */
{0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC}, /* Keyblob seed 01. */
{0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B}, /* Keyblob seed 02. */
{0x2D, 0x1F, 0x48, 0x80, 0xED, 0xEC, 0xED, 0x3E, 0x3C, 0xF2, 0x48, 0xB5, 0x65, 0x7D, 0xF7, 0xBE}, /* Keyblob seed 03. */
{0xBB, 0x5A, 0x01, 0xF9, 0x88, 0xAF, 0xF5, 0xFC, 0x6C, 0xFF, 0x07, 0x9E, 0x13, 0x3C, 0x39, 0x80}, /* Keyblob seed 04. */
{0xD8, 0xCC, 0xE1, 0x26, 0x6A, 0x35, 0x3F, 0xCC, 0x20, 0xF3, 0x2D, 0x3B, 0x51, 0x7D, 0xE9, 0xC0} /* Keyblob seed 05. */
};
static const uint8_t AL16 keyblob_mac_seed[0x10] = {
0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5
};
static const uint8_t AL16 masterkey_seed[0x10] = {
0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C
};
@@ -42,52 +55,165 @@ static const uint8_t AL16 masterkey_4x_seed[0x10] = {
0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66
};
static const uint8_t AL16 keyblob_seed_00[0x10] = {
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3
};
static const uint8_t AL16 master_kek_seed_erista[0x10] = { /* TODO: Update on next change of keys. */
0x84, 0x67, 0xB6, 0x7F, 0x13, 0x11, 0xAE, 0xE6, 0x58, 0x9B, 0x19, 0xAF, 0x13, 0x6C, 0x80, 0x7A /* Erista MasterKek seed 0B. */
};
static const uint8_t AL16 master_devkey_seed_erista[0x10] = {
0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6
/* TODO: Bother adding 8.1.0 here? We'll never call into here... */
static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_800 - MASTERKEY_REVISION_600_610][0x10] = {
{0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, /* MasterKek seed 06. */
{0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, /* MasterKek seed 07. */
};
static const uint8_t AL16 master_kek_seed_mariko[0x10] = { /* TODO: Update on next change of keys. */
0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1, /* Mariko MasterKek seed 0B. */
0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82, /* Mariko MasterKek seed 0A. */
};
/* Derive all Switch keys. */
int derive_nx_keydata_erista(uint32_t target_firmware) {
static nx_dec_keyblob_t AL16 g_dec_keyblobs[32];
static int get_keyblob(nx_keyblob_t *dst, uint32_t revision, const nx_keyblob_t *keyblobs, uint32_t available_revision) {
if (revision >= 0x20) {
return -1;
/* TODO: what should we do? */
}
if (keyblobs != NULL) {
*dst = keyblobs[revision];
} else {
return -1;
/* TODO: what should we do? */
}
return 0;
}
static bool safe_memcmp(uint8_t *a, uint8_t *b, size_t sz) {
uint8_t different = 0;
for (unsigned int i = 0; i < sz; i++) {
different |= a[i] ^ b[i];
}
return different != 0;
}
static int decrypt_keyblob(const nx_keyblob_t *keyblobs, uint32_t revision, uint32_t available_revision) {
nx_keyblob_t AL16 keyblob;
uint8_t AL16 work_buffer[0x10];
unsigned int keyslot = revision == MASTERKEY_REVISION_100_230 ? 0xF : KEYSLOT_SWITCH_TEMPKEY;
/* Get whether we're using dev keys. */
const bool is_retail = fuse_get_hardware_state() != 0;
if (get_keyblob(&keyblob, revision, keyblobs, available_revision) != 0) {
return -1;
}
/* Derive Keyblob Key 00. */
se_aes_ecb_decrypt_block(0xC, work_buffer, 0x10, keyblob_seed_00, 0x10);
decrypt_data_into_keyslot(0xF, 0xE, work_buffer, 0x10);
se_aes_ecb_decrypt_block(0xD, work_buffer, 0x10, keyblob_seeds[revision], 0x10);
decrypt_data_into_keyslot(keyslot, 0xE, work_buffer, 0x10);
decrypt_data_into_keyslot(0xB, keyslot, keyblob_mac_seed, 0x10);
/* Derive master kek. */
decrypt_data_into_keyslot(0xE, is_retail ? 0xD : 0xB, master_kek_seed_erista, 0x10);
/* Validate keyblob. */
se_compute_aes_128_cmac(0xB, work_buffer, 0x10, keyblob.mac + sizeof(keyblob.mac), sizeof(keyblob) - sizeof(keyblob.mac));
if (safe_memcmp(keyblob.mac, work_buffer, 0x10)) {
return -1;
}
/* Derive master key, device master key. */
decrypt_data_into_keyslot(0xD, 0xE, masterkey_seed, 0x10);
decrypt_data_into_keyslot(0xE, 0xE, masterkey_4x_seed, 0x10);
/* Decrypt keyblob. */
se_aes_ctr_crypt(keyslot, &g_dec_keyblobs[revision], sizeof(g_dec_keyblobs[revision]), keyblob.data, sizeof(keyblob.data), keyblob.ctr, sizeof(keyblob.ctr));
return 0;
}
/* Derive device keys. */
decrypt_data_into_keyslot(0xA, 0xF, devicekey_4x_seed, 0x10);
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
int load_package1_key(uint32_t revision) {
if (revision > MASTERKEY_REVISION_600_610) {
return -1;
}
/* Derive firmware specific device key. */
se_aes_ecb_decrypt_block(0xA, work_buffer, 0x10, master_devkey_seed_erista, 0x10);
decrypt_data_into_keyslot(0xC, 0xE, work_buffer, 0x10);
set_aes_keyslot(0xB, g_dec_keyblobs[revision].package1_key, 0x10);
return 0;
}
/* Clear keyslots 0xB/0xE. */
clear_aes_keyslot(0xB);
/* Derive all Switch keys. */
int derive_nx_keydata_erista(uint32_t target_firmware, const nx_keyblob_t *keyblobs, uint32_t available_revision, const void *tsec_key, void *tsec_root_keys, unsigned int *out_keygen_type) {
uint8_t AL16 work_buffer[0x10];
uint8_t AL16 zeroes[0x10] = {0};
/* Initialize keygen type. */
*out_keygen_type = 0;
/* TODO: Set keyslot flags properly in preparation of derivation. */
set_aes_keyslot_flags(0xE, 0x15);
set_aes_keyslot_flags(0xD, 0x15);
/* Set the TSEC key. */
set_aes_keyslot(0xD, tsec_key, 0x10);
/* Decrypt all keyblobs, setting keyslot 0xF correctly. */
for (unsigned int rev = 0; rev <= MASTERKEY_REVISION_600_610; rev++) {
int ret = decrypt_keyblob(keyblobs, rev, available_revision);
if (ret) {
return ret;
}
}
/* Do 6.2.0+ keygen. */
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
uint32_t desired_keyblob;
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) {
/* NOTE: We load in the current key for all >= 8.1.0 firmwares to reduce sept binaries. */
desired_keyblob = MASTERKEY_REVISION_910_CURRENT;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
desired_keyblob = MASTERKEY_REVISION_700_800;
} else {
desired_keyblob = MASTERKEY_REVISION_620;
}
/* Try emulation result. */
for (unsigned int rev = MASTERKEY_REVISION_620; rev < MASTERKEY_REVISION_MAX; rev++) {
void *tsec_root_key = (void *)((uintptr_t)tsec_root_keys + 0x10 * (rev - MASTERKEY_REVISION_620));
if (memcmp(tsec_root_key, zeroes, 0x10) != 0) {
/* We got a valid key from emulation. */
set_aes_keyslot(0xD, tsec_root_key, 0x10);
se_aes_ecb_decrypt_block(0xD, work_buffer, 0x10, new_master_kek_seeds[rev - MASTERKEY_REVISION_620], 0x10);
memcpy(g_dec_keyblobs[rev].master_kek, work_buffer, 0x10);
}
}
if (memcmp(g_dec_keyblobs[desired_keyblob].master_kek, zeroes, 0x10) == 0) {
/* Try reading the keys from a file. */
const char *keyfile = fuse_get_hardware_state() != 0 ? "atmosphere/prod.keys" : "atmosphere/dev.keys";
FILE *extkey_file = fopen(keyfile, "r");
AL16 fusee_extkeys_t extkeys = {0};
if (extkey_file == NULL) {
fatal_error("Error: failed to read %s, needed for 6.2.0+ key derivation!", keyfile);
}
extkeys_initialize_keyset(&extkeys, extkey_file);
fclose(extkey_file);
for (unsigned int rev = MASTERKEY_REVISION_620; rev < MASTERKEY_REVISION_MAX; rev++) {
if (memcmp(extkeys.tsec_root_keys[rev - MASTERKEY_REVISION_620], zeroes, 0x10) != 0) {
set_aes_keyslot(0xD, extkeys.tsec_root_keys[rev - MASTERKEY_REVISION_620], 0x10);
se_aes_ecb_decrypt_block(0xD, work_buffer, 0x10, new_master_kek_seeds[rev - MASTERKEY_REVISION_620], 0x10);
memcpy(g_dec_keyblobs[rev].master_kek, work_buffer, 0x10);
} else {
memcpy(g_dec_keyblobs[rev].master_kek, extkeys.master_keks[rev], 0x10);
}
}
}
if (memcmp(g_dec_keyblobs[available_revision].master_kek, zeroes, 0x10) == 0) {
fatal_error("Error: failed to derive master_kek_%02x!", available_revision);
}
}
/* Clear the SBK. */
clear_aes_keyslot(0xE);
/* Get needed data. */
set_aes_keyslot(0xD, g_dec_keyblobs[available_revision].master_kek, 0x10);
/* Also set the Package1 key for the revision that is stored on the eMMC boot0 partition. */
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
load_package1_key(available_revision);
}
/* Derive keys for Exosphere, lock critical keyslots. */
decrypt_data_into_keyslot(0xA, 0xF, devicekey_4x_seed, 0x10);
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
decrypt_data_into_keyslot(0xC, 0xD, masterkey_4x_seed, 0x10);
decrypt_data_into_keyslot(0xD, 0xD, masterkey_seed, 0x10);
/* Setup master key revision, derive older master keys for use. */
return mkey_detect_revision(fuse_get_hardware_state() != 0);
}

View File

@@ -27,8 +27,29 @@ typedef enum BisPartition {
BisPartition_UserSystem = 2,
} BisPartition;
int derive_nx_keydata_erista(uint32_t target_firmware);
typedef struct {
union {
uint8_t keys[9][0x10];
struct {
uint8_t master_kek[0x10];
uint8_t _keys[7][0x10];
uint8_t package1_key[0x10];
};
};
} nx_dec_keyblob_t;
typedef struct nx_keyblob_t {
uint8_t mac[0x10];
uint8_t ctr[0x10];
union {
uint8_t data[0x90];
nx_dec_keyblob_t dec_blob;
};
} nx_keyblob_t;
int derive_nx_keydata_erista(uint32_t target_firmware, const nx_keyblob_t *keyblobs, uint32_t available_revision, const void *tsec_key, void *tsec_root_key, unsigned int *out_keygen_type);
int derive_nx_keydata_mariko(uint32_t target_firmware);
int load_package1_key(uint32_t revision);
void derive_bis_key(void *dst, BisPartition partition_id, uint32_t target_firmware);
#endif

View File

@@ -44,7 +44,6 @@ static const uint8_t mkey_vectors_dev[MASTERKEY_REVISION_MAX][0x10] = {
{0xEC, 0xE1, 0x46, 0x89, 0x37, 0xFD, 0xD2, 0x15, 0x8C, 0x3F, 0x24, 0x82, 0xEF, 0x49, 0x68, 0x04}, /* Master key 07 encrypted with Master key 08. */
{0x43, 0x3D, 0xC5, 0x3B, 0xEF, 0x91, 0x02, 0x21, 0x61, 0x54, 0x63, 0x8A, 0x35, 0xE7, 0xCA, 0xEE}, /* Master key 08 encrypted with Master key 09. */
{0x6C, 0x2E, 0xCD, 0xB3, 0x34, 0x61, 0x77, 0xF5, 0xF9, 0xB1, 0xDD, 0x61, 0x98, 0x19, 0x3E, 0xD4}, /* Master key 09 encrypted with Master key 0A. */
{0x21, 0x88, 0x6B, 0x10, 0x9E, 0x83, 0xD6, 0x52, 0xAB, 0x08, 0xDB, 0x6D, 0x39, 0xFF, 0x1C, 0x9C}, /* Master key 0A encrypted with Master key 0B. */
};
/* Retail unit keys. */
@@ -60,19 +59,17 @@ static const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] = {
{0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29}, /* Master key 07 encrypted with Master key 08. */
{0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80}, /* Master key 08 encrypted with Master key 09. */
{0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A}, /* Master key 09 encrypted with Master key 0A. */
{0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98}, /* Master key 0A encrypted with Master key 0B. */
};
static const uint8_t new_device_key_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
{0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */
{0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.x New Device Key Source. */
{0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */
{0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17}, /* 6.2.0 New Device Key Source. */
{0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D}, /* 7.0.0 New Device Key Source. */
{0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE}, /* 8.1.0 New Device Key Source. */
{0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49}, /* 9.0.0 New Device Key Source. */
{0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94}, /* 9.1.0 New Device Key Source. */
{0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6}, /* 12.1.0 New Device Key Source. */
{0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */
{0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.x New Device Key Source. */
{0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */
{0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17}, /* 6.2.0 New Device Key Source. */
{0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D}, /* 7.0.0 New Device Key Source. */
{0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE}, /* 8.1.0 New Device Key Source. */
{0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49}, /* 9.0.0 New Device Key Source. */
{0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94}, /* 9.1.0 New Device Key Source. */
};
static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
@@ -83,8 +80,7 @@ static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x
{0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E}, /* 7.0.0 New Device Keygen Source. */
{0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D}, /* 8.1.0 New Device Keygen Source. */
{0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED}, /* 9.0.0 New Device Keygen Source. */
{0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36}, /* 9.1.0 New Device Keygen Source. */
{0xC2, 0x65, 0x34, 0x6E, 0xC7, 0xC6, 0x5D, 0x97, 0x3E, 0x34, 0x5C, 0x6B, 0xB3, 0x7E, 0xC6, 0xE3}, /* 12.1.0 New Device Keygen Source. */
{0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36}, /* 9.1.0 New Device Keygen Source to be added on next change-of-keys. */
};
static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
@@ -95,8 +91,7 @@ static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS
{0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE}, /* 7.0.0 New Device Keygen Source. */
{0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87}, /* 8.1.0 New Device Keygen Source. */
{0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F}, /* 9.0.0 New Device Keygen Source. */
{0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B}, /* 9.1.0 New Device Keygen Source. */
{0xC4, 0xBB, 0xF3, 0x9F, 0xA3, 0xAA, 0x00, 0x99, 0x7C, 0x97, 0xAD, 0x91, 0x8F, 0xE8, 0x45, 0xCB}, /* 12.1.0 New Device Keygen Source. */
{0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B}, /* 9.1.0 New Device Keygen Source to be added on next change-of-keys. */
};
/* Determine the current SoC for Mariko specific code. */
@@ -185,8 +180,8 @@ void derive_new_device_keys(bool is_retail, unsigned int keygen_keyslot, unsigne
if (relative_revision > mkey_get_revision()) {
break;
} else if (relative_revision == mkey_get_revision()) {
/* On Erista, this will already be derived. */
if (is_mariko) {
/* On 7.0.0 erista, sept will have derived this key for us already. */
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0 || is_mariko) {
decrypt_data_into_keyslot(is_mariko ? KEYSLOT_SWITCH_DEVICEKEY_MARIKO : KEYSLOT_SWITCH_DEVICEKEY, KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10);
}
} else {

View File

@@ -19,8 +19,8 @@
/* This is glue code to enable master key support across versions. */
/* TODO: Update to 0xD on release of new master key. */
#define MASTERKEY_REVISION_MAX 0xC
/* TODO: Update to 0xC on release of new master key. */
#define MASTERKEY_REVISION_MAX 0xB
#define MASTERKEY_REVISION_100_230 0x00
#define MASTERKEY_REVISION_300 0x01
@@ -32,8 +32,7 @@
#define MASTERKEY_REVISION_700_800 0x07
#define MASTERKEY_REVISION_810 0x08
#define MASTERKEY_REVISION_900 0x09
#define MASTERKEY_REVISION_910_1203 0x0A
#define MASTERKEY_REVISION_C10_CURRENT 0x0B
#define MASTERKEY_REVISION_910_CURRENT 0x0A
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)

View File

@@ -44,6 +44,7 @@
#include "masterkey.h"
#include "package1.h"
#include "package2.h"
#include "smmu.h"
#include "tsec.h"
#include "lp0.h"
#include "loader.h"
@@ -58,8 +59,11 @@
#include "exosphere_bin.h"
#include "mariko_fatal_bin.h"
#include "mesosphere_bin.h"
#include "sept_secondary_00_enc.h"
#include "sept_secondary_01_enc.h"
#include "sept_secondary_dev_00_enc.h"
#include "sept_secondary_dev_01_enc.h"
#include "warmboot_bin.h"
#include "tsec_keygen_bin.h"
#include "emummc_kip.h"
#undef u8
#undef u32
@@ -252,24 +256,6 @@ static int stratosphere_ini_handler(void *user, const char *section, const char
return 1;
}
static int system_settings_ini_handler(void *user, const char *section, const char *name, const char *value) {
uint32_t *flags = (uint32_t *)user;
if (strcmp(section, "usb") == 0) {
if (strcmp(name, "usb30_force_enabled") == 0) {
if (strcmp(value, "u8!0x1") == 0) {
*flags |= EXOSPHERE_FLAG_FORCE_ENABLE_USB_30;
} else if (strcmp(value, "u8!0x0") == 0) {
*flags &= ~(EXOSPHERE_FLAG_FORCE_ENABLE_USB_30);
}
} else {
return 0;
}
} else {
return 0;
}
return 1;
}
static bool is_nca_present(const char *nca_name) {
char path[0x100];
snprintf(path, sizeof(path), "system:/contents/registered/%s.nca", nca_name);
@@ -281,15 +267,7 @@ static bool is_nca_present(const char *nca_name) {
static uint32_t nxboot_get_specific_target_firmware(uint32_t target_firmware){
#define CHECK_NCA(NCA_ID, VERSION) do { if (is_nca_present(NCA_ID)) { return ATMOSPHERE_TARGET_FIRMWARE_##VERSION; } } while(0)
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_1_0) {
CHECK_NCA("9d9d83d68d9517f245f3e8cd7f93c416", 12_1_0);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_2) {
CHECK_NCA("a1863a5c0e1cedd442f5e60b0422dc15", 12_0_3);
CHECK_NCA("63d928b5a3016fe8cc0e76d2f06f4e98", 12_0_2);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_0) {
CHECK_NCA("e65114b456f9d0b566a80e53bade2d89", 12_0_1);
CHECK_NCA("bd4185843550fbba125b20787005d1d2", 12_0_0);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0) {
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0) {
CHECK_NCA("56211c7a5ed20a5332f5cdda67121e37", 11_0_1);
CHECK_NCA("594c90bcdbcccad6b062eadba0cd0e7e", 11_0_0);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
@@ -392,12 +370,6 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
return ATMOSPHERE_TARGET_FIRMWARE_10_0_0;
} else if (memcmp(package1loader_header->build_timestamp, "20201030", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_11_0_0;
} else if (memcmp(package1loader_header->build_timestamp, "20210129", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_12_0_0;
} else if (memcmp(package1loader_header->build_timestamp, "20210422", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_12_0_2;
} else if (memcmp(package1loader_header->build_timestamp, "20210607", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_12_1_0;
} else {
fatal_error("[NXBOOT] Unable to identify package1!\n");
}
@@ -565,15 +537,6 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
/* Apply lcd vendor. */
exo_cfg.lcd_vendor = display_get_lcd_vendor();
/* Read and parse system settings.ini to determine usb 3.0 enable. */
char *settings_ini = calloc(1, 0x20000);
if (read_from_file(settings_ini, 0x1FFFF, "atmosphere/config/system_settings.ini")) {
if (ini_parse_string(settings_ini, system_settings_ini_handler, &exo_cfg.flags[0]) < 0) {
fatal_error("[NXBOOT] Failed to parse system_settings.ini!\n");
}
}
free(settings_ini);
if ((exo_cfg.target_firmware < ATMOSPHERE_TARGET_FIRMWARE_MIN) || (exo_cfg.target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX)) {
fatal_error("[NXBOOT] Invalid Exosphere target firmware!\n");
}
@@ -605,15 +568,6 @@ static void nxboot_configure_stratosphere(uint32_t target_firmware) {
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0 && !(fuse_get_reserved_odm(7) & ~0x00001FFF)) {
kip_patches_set_enable_nogc();
}
/* NOTE: 12.0.0 added a new lotus firmware, but did not burn a fuse. */
/* This is literally undetectable using normal fuses.... */
/* C'est la vie. */
/* Check if the fuses are < 12.0.0, but firmware is >= 12.0.0 */
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_2 && !(fuse_get_reserved_odm(7) & ~0x00003FFF)) {
kip_patches_set_enable_nogc();
}
}
}
@@ -720,11 +674,18 @@ static void nxboot_move_bootconfig() {
free(bootconfig);
}
static bool get_and_clear_has_run_sept(void) {
bool has_run_sept = (MAKE_EMC_REG(EMC_SCRATCH0) & 0x80000000) != 0;
MAKE_EMC_REG(EMC_SCRATCH0) &= ~0x80000000;
return has_run_sept;
}
static void get_mariko_warmboot_path(char *dst, size_t dst_size, uint32_t version) {
snprintf(dst, dst_size, "warmboot_mariko/wb_%02" PRIx32 ".bin", version);
}
/* This is the main function responsible for booting Horizon. */
static nx_keyblob_t __attribute__((aligned(16))) g_keyblobs[32];
uint32_t nxboot_main(void) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
loader_ctx_t *loader_ctx = get_loader_ctx();
@@ -734,6 +695,8 @@ uint32_t nxboot_main(void) {
size_t package2_size;
void *tsec_fw;
size_t tsec_fw_size;
const void *sept_secondary_enc = NULL;
size_t sept_secondary_enc_size = 0;
void *warmboot_fw;
size_t warmboot_fw_size;
void *warmboot_memaddr;
@@ -743,6 +706,7 @@ uint32_t nxboot_main(void) {
size_t mesosphere_size;
void *emummc;
size_t emummc_size;
uint32_t available_revision;
FILE *boot0, *pk2file;
void *exosphere_memaddr;
exo_emummc_config_t exo_emummc_cfg;
@@ -830,7 +794,7 @@ uint32_t nxboot_main(void) {
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
}
} else {
if (package1_read_and_parse_boot0_erista(&package1loader, &package1loader_size, boot0) == -1) {
if (package1_read_and_parse_boot0_erista(&package1loader, &package1loader_size, g_keyblobs, &available_revision, boot0) == -1) {
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
}
}
@@ -846,26 +810,103 @@ uint32_t nxboot_main(void) {
}
/* Handle TSEC and Sept (Erista only). */
uint8_t tsec_key[0x10] = {0};
uint8_t tsec_root_keys[0x20][0x10] = {0};
if (!is_mariko) {
/* Use Atmosphere's tsec_keygen implementation. */
tsec_fw_size = tsec_keygen_bin_size;
tsec_fw = memalign(0x100, tsec_fw_size);
/* Read the TSEC firmware from a file, otherwise from PK1L. */
if (loader_ctx->tsecfw_path[0] != '\0') {
tsec_fw_size = get_file_size(loader_ctx->tsecfw_path);
if ((tsec_fw_size != 0) && (tsec_fw_size != 0xF00 && tsec_fw_size != 0x2900 && tsec_fw_size != 0x3000 && tsec_fw_size != 0x3300)) {
fatal_error("[NXBOOT] TSEC firmware from %s has a wrong size!\n", loader_ctx->tsecfw_path);
} else if (tsec_fw_size == 0) {
fatal_error("[NXBOOT] Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path);
}
if (tsec_fw == NULL) {
fatal_error("[NXBOOT] Out of memory!\n");
/* Allocate memory for the TSEC firmware. */
tsec_fw = memalign(0x100, tsec_fw_size);
if (tsec_fw == NULL) {
fatal_error("[NXBOOT] Out of memory!\n");
}
if (read_from_file(tsec_fw, tsec_fw_size, loader_ctx->tsecfw_path) != tsec_fw_size) {
fatal_error("[NXBOOT] Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path);
}
if (tsec_fw_size == 0x3000) {
if (fuse_get_hardware_state() != 0) {
sept_secondary_enc = sept_secondary_00_enc;
sept_secondary_enc_size = sept_secondary_00_enc_size;
} else {
sept_secondary_enc = sept_secondary_dev_00_enc;
sept_secondary_enc_size = sept_secondary_dev_00_enc_size;
}
} else if (tsec_fw_size == 0x3300) {
if (fuse_get_hardware_state() != 0) {
sept_secondary_enc = sept_secondary_01_enc;
sept_secondary_enc_size = sept_secondary_01_enc_size;
} else {
sept_secondary_enc = sept_secondary_dev_01_enc;
sept_secondary_enc_size = sept_secondary_dev_01_enc_size;
}
} else {
fatal_error("[NXBOOT] Unable to identify sept revision to run.");
}
} else {
if (!package1_get_tsec_fw(&tsec_fw, package1loader, package1loader_size)) {
fatal_error("[NXBOOT] Failed to read the TSEC firmware from Package1loader!\n");
}
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) {
if (fuse_get_hardware_state() != 0) {
sept_secondary_enc = sept_secondary_01_enc;
sept_secondary_enc_size = sept_secondary_01_enc_size;
} else {
sept_secondary_enc = sept_secondary_dev_01_enc;
sept_secondary_enc_size = sept_secondary_dev_01_enc_size;
}
tsec_fw_size = 0x3300;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
if (fuse_get_hardware_state() != 0) {
sept_secondary_enc = sept_secondary_00_enc;
sept_secondary_enc_size = sept_secondary_00_enc_size;
} else {
sept_secondary_enc = sept_secondary_dev_00_enc;
sept_secondary_enc_size = sept_secondary_dev_00_enc_size;
}
tsec_fw_size = 0x3000;
} else if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
tsec_fw_size = 0x2900;
} else {
tsec_fw_size = 0xF00;
}
}
memcpy(tsec_fw, tsec_keygen_bin, tsec_fw_size);
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Loaded firmware from eMMC...\n");
if (tsec_fw_size == 0) {
fatal_error("[NXBOOT] Could not read the warmboot firmware from Package1!\n");
}
/* Get the TSEC keys. */
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
/* Detect whether we need to run sept-secondary in order to derive keys. */
if (!get_and_clear_has_run_sept()) {
reboot_to_sept(tsec_fw, tsec_fw_size, sept_secondary_enc, sept_secondary_enc_size);
} else {
if (mkey_detect_revision(fuse_get_hardware_state() != 0) != 0) {
fatal_error("[NXBOOT] Sept derived incorrect keys!\n");
}
}
get_and_clear_has_run_sept();
} else if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
uint8_t tsec_keys[0x20] = {0};
/* Get the TSEC keys into the security engine. */
int tsec_res = tsec_run_fw(tsec_fw, tsec_fw_size);
if (tsec_res != 0) {
volatile tegra_tsec_t *tsec = tsec_get_regs();
fatal_error("[NXBOOT] Failed to run TSEC firmware %d %08x %08x!\n", tsec_res, tsec->TSEC_FALCON_MAILBOX0, tsec->TSEC_FALCON_MAILBOX1);
/* Emulate the TSEC payload on 6.2.0+. */
smmu_emulate_tsec((void *)tsec_keys, package1loader, package1loader_size, package1loader);
/* Copy back the keys. */
memcpy((void *)tsec_key, (void *)tsec_keys, 0x10);
memcpy((void *)tsec_root_keys, (void *)tsec_keys + 0x10, 0x10);
} else {
/* Run the TSEC payload and get the key. */
if (tsec_get_key(tsec_key, 1, tsec_fw, tsec_fw_size) != 0) {
fatal_error("[NXBOOT] Failed to get TSEC key!\n");
}
}
}
@@ -878,8 +919,8 @@ uint32_t nxboot_main(void) {
if (derive_nx_keydata_mariko(target_firmware) != 0) {
fatal_error("[NXBOOT] Mariko key derivation failed!\n");
}
} else {
if (derive_nx_keydata_erista(target_firmware) != 0) {
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) { /* If on 7.0.0+, sept has already derived keys for us (Erista only). */
if (derive_nx_keydata_erista(target_firmware, g_keyblobs, available_revision, tsec_key, tsec_root_keys, &keygen_type) != 0) {
fatal_error("[NXBOOT] Erista key derivation failed!\n");
}
}
@@ -1139,6 +1180,9 @@ uint32_t nxboot_main(void) {
/* Clean up. */
free(package1loader);
if (loader_ctx->tsecfw_path[0] != '\0') {
free(tsec_fw);
}
if (loader_ctx->warmboot_path[0] != '\0') {
free(warmboot_fw);
}

View File

@@ -24,10 +24,18 @@
#include "mc.h"
#include "nxboot.h"
#include "se.h"
#include "smmu.h"
#include "timers.h"
#include "sysreg.h"
/* Determine the current SoC for Mariko specific code. */
static bool is_soc_mariko() {
return (fuse_get_soc_type() == 1);
}
void nxboot_finish(uint32_t boot_memaddr) {
bool is_mariko = is_soc_mariko();
/* Boot up Exosphère. */
MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 0;
MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X;
@@ -35,8 +43,26 @@ void nxboot_finish(uint32_t boot_memaddr) {
/* Terminate the display. */
display_end();
/* Boot CPU0. */
cluster_boot_cpu0(boot_memaddr);
if (is_mariko) {
/* Boot CPU0. */
cluster_boot_cpu0(boot_memaddr);
} else {
/* Check if SMMU emulation has been used. */
uint32_t smmu_magic = *(uint32_t *)(SMMU_AARCH64_PAYLOAD_ADDR + 0xFC);
if (smmu_magic == 0xDEADC0DE) {
/* Clear the magic. */
*(uint32_t *)(SMMU_AARCH64_PAYLOAD_ADDR + 0xFC) = 0;
/* Pass the boot address to the already running payload. */
*(uint32_t *)(SMMU_AARCH64_PAYLOAD_ADDR + 0xF0) = boot_memaddr;
/* Wait a while. */
mdelay(500);
} else {
/* Boot CPU0. */
cluster_boot_cpu0(boot_memaddr);
}
}
/* Wait for Exosphère to wake up. */
while (MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE == 0) {

View File

@@ -58,12 +58,16 @@ bool package1_is_custom_public_key(const void *bct, bool mariko) {
}
}
int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, FILE *boot0) {
int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, nx_keyblob_t *keyblobs, uint32_t *revision, FILE *boot0) {
nvboot_config_table *bct; /* Normal firmware BCT, primary. TODO: check? */
nv_bootloader_info *pk1l_info; /* TODO: check? */
size_t fpos, pk1l_offset;
union {
nx_keyblob_t keyblob;
uint8_t sector[0x200];
} d;
if (package1loader == NULL || package1loader_size == NULL || boot0 == NULL) {
if (package1loader == NULL || package1loader_size == NULL || keyblobs == NULL || revision == NULL || boot0 == NULL) {
errno = EINVAL;
return -1;
}
@@ -101,6 +105,7 @@ int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1
return -1;
}
*revision = pk1l_info->version - 1;
*package1loader_size = pk1l_info->length;
pk1l_offset = 0x4000 * pk1l_info->start_blk + 0x200 * pk1l_info->start_page;
@@ -123,6 +128,14 @@ int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1
return -1;
}
/* Read the full keyblob area.*/
for (size_t i = 0; i < 32; i++) {
if (!fread(d.sector, 0x200, 1, boot0)) {
return -1;
}
keyblobs[i] = d.keyblob;
}
return 0;
}
@@ -198,6 +211,24 @@ bool package1_get_tsec_fw(void **tsec_fw, const void *package1loader, size_t pac
return false;
}
size_t package1_get_encrypted_package1(package1_header_t **package1, uint8_t *ctr, const void *package1loader, size_t package1loader_size) {
const uint8_t *crypt_hdr = (const uint8_t *)package1loader + 0x4000 - 0x20;
if (package1loader_size < 0x4000) {
return 0; /* Shouldn't happen, ever. */
}
memcpy(ctr, crypt_hdr + 0x10, 0x10);
(*package1) = (package1_header_t *)(crypt_hdr + 0x20);
return *(uint32_t *)crypt_hdr;
}
bool package1_decrypt(package1_header_t *package1, size_t package1_size, const uint8_t *ctr) {
uint8_t __attribute__((aligned(16))) ctrbuf[16];
memcpy(ctrbuf, ctr, 16);
se_aes_ctr_crypt(0xB, package1, package1_size, package1, package1_size, ctrbuf, 16);
return memcmp(package1->magic, "PK11", 4) == 0;
}
void *package1_get_warmboot_fw(const package1_header_t *package1) {
/*
The layout of pk1 changes between versions.

View File

@@ -59,10 +59,14 @@ typedef struct {
bool package1_is_custom_public_key(const void *bct, bool mariko);
int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, FILE *boot0);
int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, nx_keyblob_t *keyblobs, uint32_t *revision, FILE *boot0);
int package1_read_and_parse_boot0_mariko(void **package1loader, size_t *package1loader_size, FILE *boot0);
bool package1_get_tsec_fw(void **tsec_fw, const void *package1loader, size_t package1loader_size);
size_t package1_get_encrypted_package1(package1_header_t **package1, uint8_t *ctr, const void *package1loader, size_t package1loader_size);
/* Must be aligned to 16 bytes. */
bool package1_decrypt(package1_header_t *package1, size_t package1_size, const uint8_t *ctr);
void *package1_get_warmboot_fw(const package1_header_t *package1);
#endif

View File

@@ -250,7 +250,7 @@ static bool package2_validate_metadata(package2_meta_t *metadata, uint8_t data[]
/* Perform version checks. */
/* We will be compatible with all package2s released before current, but not newer ones. */
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_1202_CURRENT) {
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_1100_CURRENT) {
return true;
}

View File

@@ -41,8 +41,7 @@
#define PACKAGE2_MAXVER_900 0xC
#define PACKAGE2_MAXVER_910_920 0xD
#define PACKAGE2_MAXVER_1000 0xE
#define PACKAGE2_MAXVER_1100 0xF
#define PACKAGE2_MAXVER_1202_CURRENT 0x10
#define PACKAGE2_MAXVER_1100_CURRENT 0xF
#define PACKAGE2_MINVER_100 0x3
#define PACKAGE2_MINVER_200 0x4
@@ -57,8 +56,7 @@
#define PACKAGE2_MINVER_900 0xD
#define PACKAGE2_MINVER_910_920 0xE
#define PACKAGE2_MINVER_1000 0xF
#define PACKAGE2_MINVER_1100 0x10
#define PACKAGE2_MINVER_1202_CURRENT 0x11
#define PACKAGE2_MINVER_1100_CURRENT 0x10
#define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull))

View File

@@ -0,0 +1,284 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "smmu.h"
#include "cluster.h"
#include "mc.h"
#include "timers.h"
#include "tsec.h"
#define TSEC_KEYGEN_MAX_RETRIES 25
void *smmu_heap = (void *)SMMU_HEAP_BASE_ADDR;
static void safe_memcpy(void *dst, void *src, uint32_t sz) {
/* Aligned memcpy to read MMIO correctly. */
for (size_t i = 0; i < (sz/4); i++) {
((volatile uint32_t *)dst)[i] = ((volatile uint32_t *)src)[i];
}
}
static void smmu_flush_ppsb() {
/* Read-back barrier for interactions between the PPSB and the APB/AHB. */
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
}
static void smmu_flush_regs() {
/* Flush all TLB and PTC entries. */
MAKE_MC_REG(MC_SMMU_PTC_FLUSH) = 0;
smmu_flush_ppsb();
MAKE_MC_REG(MC_SMMU_TLB_FLUSH) = 0;
smmu_flush_ppsb();
}
static void *smmu_alloc_page(uint32_t page_count) {
void *cur_page = smmu_heap;
smmu_heap += (page_count * SMMU_PAGE_SIZE);
memset(cur_page, 0, (page_count * SMMU_PAGE_SIZE));
return cur_page;
}
static uint32_t *smmu_alloc_pdir() {
uint32_t *pdir = (uint32_t *)smmu_alloc_page(1);
for (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++) {
pdir[pdn] = _PDE_VACANT(pdn);
}
return pdir;
}
static uint32_t *smmu_locate_pte(uint32_t *pdir_page, uint32_t iova) {
uint32_t ptn = SMMU_ADDR_TO_PFN(iova);
uint32_t pdn = SMMU_ADDR_TO_PDN(iova);
uint32_t *pdir = pdir_page;
uint32_t *ptbl;
if (pdir[pdn] != _PDE_VACANT(pdn)) {
/* Mapped entry table already exists. */
ptbl = (uint32_t *)SMMU_EX_PTBL_PAGE(pdir[pdn]);
} else {
/* Allocate page table. */
ptbl = (uint32_t *)smmu_alloc_page(1);
uint32_t addr = SMMU_PDN_TO_ADDR(pdn);
for (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE) {
ptbl[pn] = _PTE_VACANT(addr);
}
pdir[pdn] = SMMU_MK_PDE((uint32_t)ptbl, _PDE_ATTR | _PDE_NEXT);
smmu_flush_regs();
}
return &ptbl[ptn % SMMU_PTBL_COUNT];
}
static void smmu_map(uint32_t *pdir, uint32_t addr, uint32_t ptpage, int pcount, uint32_t pte_attr) {
for (int i = 0; i < pcount; i++) {
uint32_t *pte = smmu_locate_pte(pdir, addr);
*pte = SMMU_PFN_TO_PTE(SMMU_ADDR_TO_PFN(ptpage), pte_attr);
addr += SMMU_PAGE_SIZE;
ptpage += SMMU_PAGE_SIZE;
}
smmu_flush_regs();
}
static uint32_t *smmu_setup_tsec_as(uint32_t asid) {
/* Allocate the page directory. */
uint32_t *pdir_page = smmu_alloc_pdir();
/* Set the PTB ASID and point it to the PDIR. */
MAKE_MC_REG(MC_SMMU_PTB_ASID) = asid;
MAKE_MC_REG(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((uint32_t)pdir_page, _PDIR_ATTR);
smmu_flush_ppsb();
/* Assign the ASID to TSEC. */
MAKE_MC_REG(MC_SMMU_TSEC_ASID) = SMMU_ASID_ENABLE((asid << 24) | (asid << 16) | (asid << 8) | asid);
smmu_flush_ppsb();
return pdir_page;
}
static void smmu_clear_tsec_as(uint32_t asid) {
/* Set the PTB ASID and clear it's data. */
MAKE_MC_REG(MC_SMMU_PTB_ASID) = asid;
MAKE_MC_REG(MC_SMMU_PTB_DATA) = 0;
/* Clear the ASID from TSEC. */
MAKE_MC_REG(MC_SMMU_TSEC_ASID) = SMMU_ASID_DISABLE;
smmu_flush_ppsb();
}
static void smmu_enable() {
/* AARCH64 payload for enabling the SMMU. */
/* Write 1 to MC_SMMU_CONFIG, read back and write the result to 0x40003F80. */
/* This will leave the CPU waiting until 0x40003FF0 is set to Exosphère's address. */
static const uint32_t aarch64_payload[20] = {
0x52800020, 0x58000162, 0x58000183, 0xB9000040,
0xB9400041, 0xB9000061, 0x58000142, 0xF9400040,
0xF100001F, 0x54FFFFA0, 0xD61F0000, 0x00000000,
0x70019010, 0x00000000, 0x40003F80, 0x00000000,
0x40003FF0, 0x00000000, 0x00000000, 0x00000000
};
/* Reset Translation Enable Registers. */
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_0) = 0xFFFFFFFF;
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_1) = 0xFFFFFFFF;
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_2) = 0xFFFFFFFF;
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_3) = 0xFFFFFFFF;
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_4) = 0xFFFFFFFF;
/* Setup initial TLB and PTC configuration. */
MAKE_MC_REG(MC_SMMU_PTB_ASID) = 0;
MAKE_MC_REG(MC_SMMU_PTB_DATA) = 0;
MAKE_MC_REG(MC_SMMU_TLB_CONFIG) = 0x30000030;
MAKE_MC_REG(MC_SMMU_PTC_CONFIG) = 0x2800003F;
smmu_flush_regs();
/* Power on the CCPLEX to enable the SMMU globally (requires a secure write). */
volatile uint32_t *aarch64_payload_res = (volatile uint32_t *)(SMMU_AARCH64_PAYLOAD_ADDR + 0x80);
memset((void *)SMMU_AARCH64_PAYLOAD_ADDR, 0, 0x100);
memcpy((void *)SMMU_AARCH64_PAYLOAD_ADDR, aarch64_payload, 20 * 4);
cluster_boot_cpu0(SMMU_AARCH64_PAYLOAD_ADDR);
mdelay(500);
if (*aarch64_payload_res != 1) {
fatal_error("[SMMU]: Failed to enable SMMU!\n");
}
/* Write magic for nxboot. */
*(uint32_t *)(SMMU_AARCH64_PAYLOAD_ADDR + 0xFC) = 0xDEADC0DE;
/* Flush TLB and PTC entries. */
smmu_flush_regs();
}
void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_size, void *package1_dec) {
volatile tegra_tsec_t *tsec = tsec_get_regs();
/* Backup IRAM to DRAM. */
memcpy((void *)SMMU_IRAM_BACKUP_ADDR, (void *)0x40010000, 0x30000);
/* Copy package1 into IRAM. */
memcpy((void *)0x40010000, package1, package1_size);
/* Setup TSEC's address space. */
uint32_t *pdir = smmu_setup_tsec_as(1);
/* Allocate pages for MMIO and IRAM. */
volatile uint32_t *car_page = smmu_alloc_page(1);
volatile uint32_t *fuse_page = smmu_alloc_page(1);
volatile uint32_t *pmc_page = smmu_alloc_page(1);
volatile uint32_t *flow_page = smmu_alloc_page(1);
volatile uint32_t *se_page = smmu_alloc_page(1);
volatile uint32_t *mc_page = smmu_alloc_page(1);
volatile uint32_t *iram_pages = smmu_alloc_page(48);
volatile uint32_t *expv_page = smmu_alloc_page(1);
/* Map all necessary pages. */
smmu_map(pdir, 0x60006000, (uint32_t)car_page, 1, _READABLE | _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x7000F000, (uint32_t)fuse_page, 1, _READABLE | _NONSECURE);
smmu_map(pdir, 0x7000E000, (uint32_t)pmc_page, 1, _READABLE | _NONSECURE);
smmu_map(pdir, 0x60007000, (uint32_t)flow_page, 1, _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x70012000, (uint32_t)se_page, 1, _READABLE | _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x70019000, (uint32_t)mc_page, 1, _READABLE | _NONSECURE);
smmu_map(pdir, 0x40010000, (uint32_t)iram_pages, 48, _READABLE | _WRITABLE | _NONSECURE);
smmu_map(pdir, 0x6000F000, (uint32_t)expv_page, 1, _READABLE | _WRITABLE | _NONSECURE);
/* Enable the SMMU. */
smmu_enable();
/* Loop retrying TSEC firmware execution, in case we lose the SE keydata race. */
uint32_t key_buf[0x20/4] = {0};
unsigned int retries = 0;
while (true) {
if (retries++ > TSEC_KEYGEN_MAX_RETRIES) {
fatal_error("[SMMU] TSEC key generation race was lost too many times!");
}
/* Load the TSEC firmware from IRAM. */
if (tsec_load_fw((void *)(0x40010000 + 0xE00), 0x2900) < 0) {
fatal_error("[SMMU]: Failed to load TSEC firmware!\n");
}
/* Disable the aperture since it has precedence over the SMMU. */
mc_disable_ahb_redirect();
/* Clear all pages. */
memset((void *)car_page, 0, SMMU_PAGE_SIZE);
memset((void *)fuse_page, 0, SMMU_PAGE_SIZE);
memset((void *)pmc_page, 0, SMMU_PAGE_SIZE);
memset((void *)flow_page, 0, SMMU_PAGE_SIZE);
memset((void *)se_page, 0, SMMU_PAGE_SIZE);
memset((void *)mc_page, 0, SMMU_PAGE_SIZE);
memset((void *)iram_pages, 0, 48 * SMMU_PAGE_SIZE);
memset((void *)expv_page, 0, SMMU_PAGE_SIZE);
/* Copy CAR, MC and FUSE. */
safe_memcpy((void *)car_page, (void *)0x60006000, 0x1000);
safe_memcpy((void *)mc_page, (void *)0x70019000, 0x1000);
safe_memcpy((void *)&fuse_page[0x800/4], (void *)0x7000F800, 0x400);
/* Copy IRAM. */
memcpy((void *)iram_pages, (void *)0x40010000, 0x30000);
/* TSEC wants CLK_RST_CONTROLLER_CLK_SOURCE_TSEC_0 to be equal to 2. */
car_page[0x1F4/4] = 2;
/* TSEC wants the aperture fully open. */
mc_page[0x65C/4] = 0;
mc_page[0x660/4] = 0x80000000;
/* Run the TSEC firmware. */
tsec_run_fw();
/* Extract the keys from SE. */
volatile uint32_t *key_data = (volatile uint32_t *)((void *)se_page + 0x320);
uint32_t old_key_data = *key_data;
uint32_t buf_counter = 0;
while (!(tsec->TSEC_FALCON_CPUCTL & 0x10)) {
const uint32_t new_key_data = *key_data;
if (new_key_data != old_key_data) {
old_key_data = new_key_data;
key_buf[buf_counter] = new_key_data;
buf_counter++;
}
}
/* Enable back the aperture. */
mc_enable_ahb_redirect();
if (buf_counter == 8) {
break;
}
}
/* Check if the TSEC firmware wrote over the exception vectors. */
volatile uint32_t *tsec_done_check = (volatile uint32_t *)((void *)expv_page + 0x200);
if (!(*tsec_done_check)) {
fatal_error("[SMMU]: Failed to emulate the TSEC firmware!\n");
}
/* Copy back the extracted keys. */
memcpy((void *)tsec_keys, (void *)key_buf, 0x20);
/* Manually disable TSEC clocks. */
tsec_disable_clkrst();
/* Clear TSEC's address space. */
smmu_clear_tsec_as(1);
/* Return the decrypted package1 from emulated IRAM. */
memcpy(package1_dec, (void *)iram_pages, package1_size);
/* Restore IRAM from DRAM. */
memcpy((void *)0x40010000, (void *)SMMU_IRAM_BACKUP_ADDR, 0x30000);
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FUSEE_SMMU_H_
#define FUSEE_SMMU_H_
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#define SMMU_HEAP_BASE_ADDR 0x81000000
#define SMMU_IRAM_BACKUP_ADDR 0x82000000
#define SMMU_AARCH64_PAYLOAD_ADDR 0x40003F00
#define SMMU_PAGE_SHIFT 12
#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT)
#define SMMU_PDIR_COUNT 1024
#define SMMU_PDIR_SIZE (sizeof(uint32_t) * SMMU_PDIR_COUNT)
#define SMMU_PTBL_COUNT 1024
#define SMMU_PTBL_SIZE (sizeof(uint32_t) * SMMU_PTBL_COUNT)
#define SMMU_PDIR_SHIFT 12
#define SMMU_PDE_SHIFT 12
#define SMMU_PTE_SHIFT 12
#define SMMU_PFN_MASK 0x000fffff
#define SMMU_PDE_NEXT_SHIFT 28
#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12)
#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22)
#define SMMU_PDN_TO_ADDR(pdn) ((pdn) << 22)
#define _READABLE (1 << 31)
#define _WRITABLE (1 << 30)
#define _NONSECURE (1 << 29)
#define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT)
#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PDE_ATTR_N (_PDE_ATTR | _PDE_NEXT)
#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR)
#define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE)
#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)
#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr))
#define SMMU_MK_PDE(page, attr) (((page) >> SMMU_PDE_SHIFT) | (attr))
#define SMMU_EX_PTBL_PAGE(pde) (((pde) & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT)
#define SMMU_PFN_TO_PTE(pfn, attr) ((pfn) | (attr))
#define SMMU_ASID_ENABLE(asid) ((asid) | (1 << 31))
#define SMMU_ASID_DISABLE 0
#define SMMU_ASID_ASID(n) ((n) & ~SMMU_ASID_ENABLE(0))
void smmu_emulate_tsec(void *tsec_keys, const void *package1, size_t package1_size, void *package1_dec);
#endif

View File

@@ -108,7 +108,6 @@ _metadata:
#define CONTENT_TYPE_KLD 9
#define CONTENT_TYPE_KRN 10
#define CONTENT_TYPE_EXF 11
#define CONTENT_TYPE_TKG 12
#define CONTENT_FLAG_NONE (0 << 0)
@@ -214,6 +213,39 @@ _content_headers:
.asciz "rebootstub"
.align 5
/* sept_primary content header */
.word __sept_primary_bin_start__
.word __sept_primary_bin_size__
.byte CONTENT_TYPE_SP1
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.word 0xCCCCCCCC
.asciz "sept_primary"
.align 5
/* sept_secondary 00 content header */
.word __sept_secondary_00_enc_start__
.word __sept_secondary_00_enc_size__
.byte CONTENT_TYPE_SP2
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.word 0xCCCCCCCC
.asciz "septsecondary00"
.align 5
/* sept_secondary 01 content header */
.word __sept_secondary_01_enc_start__
.word __sept_secondary_01_enc_size__
.byte CONTENT_TYPE_SP2
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.word 0xCCCCCCCC
.asciz "septsecondary01"
.align 5
/* sm content header */
.word __sm_kip_start__
.word __sm_kip_size__
@@ -269,17 +301,6 @@ _content_headers:
.asciz "exosphere_fatal"
.align 5
/* tsec_keygen content header */
.word __tsec_keygen_bin_start__
.word __tsec_keygen_bin_size__
.byte CONTENT_TYPE_TKG
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.byte CONTENT_FLAG_NONE
.word 0xCCCCCCCC
.asciz "tsec_keygen"
.align 5
_content_headers_end:
/* No need to include this in normal programs: */

View File

@@ -14,16 +14,15 @@
* 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 "tsec.h"
#include "di.h"
#include "timers.h"
#include "car.h"
#include "mc.h"
static int tsec_dma_wait_idle()
{
volatile tegra_tsec_t *tsec = tsec_get_regs();
volatile tegra_tsec_t *tsec = tsec_get_regs();
uint32_t timeout = (get_time_ms() + 10000);
while (!(tsec->TSEC_FALCON_DMATRFCMD & 2))
@@ -31,13 +30,13 @@ static int tsec_dma_wait_idle()
if (get_time_ms() > timeout)
return 0;
}
return 1;
}
static int tsec_dma_phys_to_flcn(bool is_imem, uint32_t flcn_offset, uint32_t phys_offset)
{
volatile tegra_tsec_t *tsec = tsec_get_regs();
volatile tegra_tsec_t *tsec = tsec_get_regs();
uint32_t cmd = 0;
if (!is_imem)
@@ -53,16 +52,16 @@ static int tsec_dma_phys_to_flcn(bool is_imem, uint32_t flcn_offset, uint32_t ph
}
static int tsec_kfuse_wait_ready()
{
{
uint32_t timeout = (get_time_ms() + 10000);
/* Wait for STATE_DONE. */
while (!(KFUSE_STATE & 0x10000))
{
if (get_time_ms() > timeout)
return 0;
}
/* Check for STATE_CRCPASS. */
if (!(KFUSE_STATE & 0x20000))
return 0;
@@ -92,19 +91,19 @@ void tsec_disable_clkrst()
clkrst_disable(CARDEVICE_HOST1X);
}
static int tsec_run_fw_impl(const void *tsec_fw, size_t tsec_fw_size)
int tsec_get_key(uint8_t *key, uint32_t rev, const void *tsec_fw, size_t tsec_fw_size)
{
volatile tegra_tsec_t *tsec = tsec_get_regs();
/* Enable clocks. */
tsec_enable_clkrst();
/* Make sure KFUSE is ready. */
if (!tsec_kfuse_wait_ready())
{
/* Disable clocks. */
tsec_disable_clkrst();
return -1;
}
@@ -113,16 +112,16 @@ static int tsec_run_fw_impl(const void *tsec_fw, size_t tsec_fw_size)
tsec->TSEC_FALCON_IRQMSET = 0xFFF2;
tsec->TSEC_FALCON_IRQDEST = 0xFFF0;
tsec->TSEC_FALCON_ITFEN = 3;
/* Make sure the DMA block is idle. */
if (!tsec_dma_wait_idle())
{
/* Disable clocks. */
tsec_disable_clkrst();
return -2;
}
/* Load firmware. */
tsec->TSEC_FALCON_DMATRFBASE = (uint32_t)tsec_fw >> 8;
for (uint32_t addr = 0; addr < tsec_fw_size; addr += 0x100)
@@ -131,71 +130,128 @@ static int tsec_run_fw_impl(const void *tsec_fw, size_t tsec_fw_size)
{
/* Disable clocks. */
tsec_disable_clkrst();
return -3;
}
}
/* Write magic value to HOST1X scratch register. */
MAKE_HOST1X_REG(0x3300) = 0x34C2E1DA;
/* Execute firmware. */
tsec->TSEC_FALCON_MAILBOX1 = 0;
tsec->TSEC_FALCON_MAILBOX0 = 1;
tsec->TSEC_FALCON_MAILBOX0 = rev;
tsec->TSEC_FALCON_BOOTVEC = 0;
tsec->TSEC_FALCON_CPUCTL = 2;
/* Make sure the DMA block is idle. */
if (!tsec_dma_wait_idle())
{
/* Disable clocks. */
tsec_disable_clkrst();
return -4;
}
uint32_t timeout = (get_time_ms() + 4000);
while (!(tsec->TSEC_FALCON_CPUCTL & 0x10)) {
if (get_time_ms() > timeout) {
uint32_t timeout = (get_time_ms() + 2000);
while (!tsec->TSEC_FALCON_MAILBOX1)
{
if (get_time_ms() > timeout)
{
/* Disable clocks. */
tsec_disable_clkrst();
return -5;
}
}
if (tsec->TSEC_FALCON_MAILBOX1 != 0xB0B0B0B0)
{
/* Disable clocks. */
tsec_disable_clkrst();
return -6;
}
/* Clear magic value from HOST1X scratch register. */
MAKE_HOST1X_REG(0x3300) = 0;
/* Fetch result from SOR1. */
uint32_t tmp[0x4] = {0};
tmp[0] = SOR1_DP_HDCP_BKSV_LSB;
tmp[1] = SOR1_TMDS_HDCP_BKSV_LSB;
tmp[2] = SOR1_TMDS_HDCP_CN_MSB;
tmp[3] = SOR1_TMDS_HDCP_CN_LSB;
/* Clear SOR1 registers. */
SOR1_DP_HDCP_BKSV_LSB = 0;
SOR1_TMDS_HDCP_BKSV_LSB = 0;
SOR1_TMDS_HDCP_CN_MSB = 0;
SOR1_TMDS_HDCP_CN_LSB = 0;
/* Copy back the key. */
memcpy(key, &tmp, 0x10);
return 0;
}
int tsec_run_fw(const void *tsec_fw, size_t tsec_fw_size) {
/* Ensure that the ahb redirect is enabled. */
mc_enable_ahb_redirect();
int tsec_load_fw(const void *tsec_fw, size_t tsec_fw_size)
{
volatile tegra_tsec_t *tsec = tsec_get_regs();
/* Get bom/tom */
uint32_t bom = MAKE_MC_REG(MC_IRAM_BOM);
uint32_t tom = MAKE_MC_REG(MC_IRAM_TOM);
/* Enable clocks. */
tsec_enable_clkrst();
/* Make sure KFUSE is ready. */
if (!tsec_kfuse_wait_ready())
{
/* Disable clocks. */
tsec_disable_clkrst();
return -1;
}
/* Override the ahb redirect extents. */
MAKE_MC_REG(MC_IRAM_BOM) = 0x40000000;
MAKE_MC_REG(MC_IRAM_TOM) = 0x80000000;
/* Configure Falcon. */
tsec->TSEC_FALCON_DMACTL = 0;
tsec->TSEC_FALCON_IRQMSET = 0xFFF2;
tsec->TSEC_FALCON_IRQDEST = 0xFFF0;
tsec->TSEC_FALCON_ITFEN = 3;
/* Make sure the DMA block is idle. */
if (!tsec_dma_wait_idle())
{
/* Disable clocks. */
tsec_disable_clkrst();
return -2;
}
/* Load firmware. */
tsec->TSEC_FALCON_DMATRFBASE = (uint32_t)tsec_fw >> 8;
for (uint32_t addr = 0; addr < tsec_fw_size; addr += 0x100)
{
if (!tsec_dma_phys_to_flcn(true, addr, addr))
{
/* Disable clocks. */
tsec_disable_clkrst();
return -3;
}
}
/* Run the fw. */
int res = tsec_run_fw_impl(tsec_fw, tsec_fw_size);
return 0;
}
/* Reset the ahb redirect extents. */
MAKE_MC_REG(MC_IRAM_BOM) = bom;
MAKE_MC_REG(MC_IRAM_TOM) = tom;
return res;
void tsec_run_fw()
{
volatile tegra_tsec_t *tsec = tsec_get_regs();
/* Write magic value to HOST1X scratch register. */
MAKE_HOST1X_REG(0x3300) = 0x34C2E1DA;
/* Execute firmware. */
tsec->TSEC_FALCON_MAILBOX1 = 0;
tsec->TSEC_FALCON_MAILBOX0 = 1;
tsec->TSEC_FALCON_BOOTVEC = 0;
tsec->TSEC_FALCON_CPUCTL = 2;
}

View File

@@ -14,7 +14,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 FUSEE_TSEC_H_
#define FUSEE_TSEC_H_
@@ -306,7 +306,8 @@ static inline volatile tegra_tsec_t *tsec_get_regs(void)
void tsec_enable_clkrst();
void tsec_disable_clkrst();
int tsec_run_fw(const void *tsec_fw, size_t tsec_fw_size);
int tsec_get_key(uint8_t *key, uint32_t rev, const void *tsec_fw, size_t tsec_fw_size);
int tsec_load_fw(const void *tsec_fw, size_t tsec_fw_size);
void tsec_run_fw();
#endif

View File

@@ -34,6 +34,7 @@
#define u8 uint8_t
#define u32 uint32_t
#include "fusee_primary_bin.h"
#include "sept_primary_bin.h"
#include "rebootstub_bin.h"
#undef u8
#undef u32
@@ -130,8 +131,42 @@ __attribute__((noreturn)) void reboot_to_fusee_primary(void) {
reboot_to_payload();
}
__attribute__((noreturn)) void reboot_to_sept(const void *tsec_fw, size_t tsec_fw_length, const void *stage2, size_t stage2_size) {
if (is_soc_mariko()) {
/* Reboot to sept isn't possible on mariko, so just do normal reboot. */
shutdown_system(true);
} else {
/* Copy tsec firmware. */
for (size_t i = 0; i < tsec_fw_length; i += sizeof(uint32_t)) {
write32le((void *)0x40010F00, i, read32le(tsec_fw, i));
}
MAKE_REG32(0x40010EFC) = tsec_fw_length;
/* Copy stage 2. */
for (size_t i = 0; i < stage2_size; i += sizeof(uint32_t)) {
write32le((void *)0x40016FE0, i, read32le(stage2, i));
}
/* Copy sept into IRAM low. */
for (size_t i = 0; i < sept_primary_bin_size; i += sizeof(uint32_t)) {
write32le((void *)0x4003F000, i, read32le(sept_primary_bin, i));
}
/* Patch SDRAM init to perform an SVC immediately after second write */
APBDEV_PMC_SCRATCH45_0 = 0x2E38DFFF;
APBDEV_PMC_SCRATCH46_0 = 0x6001DC28;
/* Set SVC handler to jump to reboot stub in IRAM. */
APBDEV_PMC_SCRATCH33_0 = 0x4003F000;
APBDEV_PMC_SCRATCH40_0 = 0x6000F208;
/* Trigger warm reboot. */
pmc_reboot(1 << 0);
while (true) { }
}
}
__attribute__((noreturn)) void reboot_to_iram_payload(void *payload, size_t payload_size) {
/* Copy payload into IRAM low. */
/* Copy sept into IRAM low. */
for (size_t i = 0; i < payload_size; i += sizeof(uint32_t)) {
write32le((void *)0x40010000, i, read32le(payload, i));
}

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FUSEE_UTILS_H
#define FUSEE_UTILS_H
@@ -121,6 +121,7 @@ static inline bool check_32bit_address_range_in_program(uintptr_t addr, size_t s
__attribute__((noreturn)) void watchdog_reboot(void);
__attribute__((noreturn)) void pmc_reboot(uint32_t scratch0);
__attribute__((noreturn)) void reboot_to_fusee_primary(void);
__attribute__((noreturn)) void reboot_to_sept(const void *tsec_fw, size_t tsec_fw_length, const void *stage2, size_t stage2_size);
__attribute__((noreturn)) void reboot_to_iram_payload(void *payload, size_t payload_size);
__attribute__((noreturn)) void wait_for_button_and_reboot(void);
void wait_for_button(void);

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
branch = master
commit = 87a1de0b1d489c25a85e187a5bf059f6872465d1
parent = 9296a563036ef20664a2752c03a9695597d4c2b4
commit = 6c11c07e2a7f03952a4e70eb89b47bf528de39c6
parent = 9e104bb83f1302e9f126542fbf57c7f666aae953
method = merge
cmdver = 0.4.1

View File

@@ -18,7 +18,7 @@ endif
ATMOSPHERE_BUILD_SETTINGS ?=
export ATMOSPHERE_DEFINES := -DATMOSPHERE
export ATMOSPHERE_SETTINGS := -fPIE -g -gdwarf-4 $(ATMOSPHERE_BUILD_SETTINGS)
export ATMOSPHERE_SETTINGS := -fPIE -g $(ATMOSPHERE_BUILD_SETTINGS)
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
-Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation

View File

@@ -8,25 +8,19 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../common.mk
#---------------------------------------------------------------------------------
ifeq ($(strip $(ATMOSPHERE_ARCH_NAME)),arm64)
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
else ifeq ($(strip $(ATMOSPHERE_ARCH_NAME)),arm)
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Werror -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Werror -fno-non-call-exceptions
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
endif
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -fno-rtti -fno-use-cxa-atexit -nostdlib -nostartfiles -g -gdwarf-4 $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -fno-rtti -fno-use-cxa-atexit -nostdlib -nostartfiles -g $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,__cxa_throw \

View File

@@ -12,7 +12,7 @@ export CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -nostdlib -nostartfiles -g -gdwarf-4 $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -nostdlib -nostartfiles -g $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,__cxa_throw \

View File

@@ -34,8 +34,7 @@ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,_Unwind_Resume \
-Wl,--wrap,_ZSt19__throw_logic_errorPKc \
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
-Wl,--wrap,_ZNSt11logic_errorC2EPKc \
-Wl,--wrap,exit
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
export LDFLAGS = -specs=$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/stratosphere.specs -specs=$(DEVKITPRO)/libnx/switch.specs $(SETTINGS) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)

View File

@@ -16,10 +16,7 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
#---------------------------------------------------------------------------------
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Wextra -Werror -flto -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Wextra -Werror -flto -fno-non-call-exceptions
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
@@ -96,8 +93,6 @@ clean-$(strip $1):
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1))
@for i in $$(GCH_DIRS) $$(ATMOSPHERE_BUILD_DIR) $$(ATMOSPHERE_LIBRARY_DIR); do [ -d $$$$i ] && rmdir --ignore-fail-on-non-empty $$$$i || true; done
.PHONY: $(strip $1) clean-$(strip $1) $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
endef
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
@@ -119,7 +114,7 @@ $(eval $(call ATMOSPHERE_ADD_TARGET, audit, $(TARGET)_audit.a, \
ALL_GCH_IDENTIFIERS := $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(ATMOSPHERE_BOARD_NAME)_$(ATMOSPHERE_ARCH_NAME)_$(config))
ALL_GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(foreach id,$(ALL_GCH_IDENTIFIERS),$(hdr)/$(id)))
.PHONY: clean all
.PHONY: clean all $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
@[ -d $@ ] || mkdir -p $@

View File

@@ -16,10 +16,7 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
#---------------------------------------------------------------------------------
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
@@ -96,8 +93,6 @@ clean-$(strip $1):
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1))
@for i in $$(GCH_DIRS) $$(ATMOSPHERE_BUILD_DIR) $$(ATMOSPHERE_LIBRARY_DIR); do [ -d $$$$i ] && rmdir --ignore-fail-on-non-empty $$$$i || true; done
.PHONY: $(strip $1) clean-$(strip $1) $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
endef
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
@@ -119,7 +114,7 @@ $(eval $(call ATMOSPHERE_ADD_TARGET, audit, $(TARGET)_audit.a, \
ALL_GCH_IDENTIFIERS := $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(ATMOSPHERE_BOARD_NAME)_$(ATMOSPHERE_ARCH_NAME)_$(config))
ALL_GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(foreach id,$(ALL_GCH_IDENTIFIERS),$(hdr)/$(id)))
.PHONY: clean all
.PHONY: clean all $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
@[ -d $@ ] || mkdir -p $@

View File

@@ -51,9 +51,9 @@ namespace ams::fuse {
DramId_IcosaSamsung4GB = 0,
DramId_IcosaHynix4GB = 1,
DramId_IcosaMicron4GB = 2,
DramId_IowaHynix1y4GB = 3,
DramId_AulaHynix1y4GB = 3,
DramId_IcosaSamsung6GB = 4,
DramId_HoagHynix1y4GB = 5,
DramId_CopperHynix4GB = 5,
DramId_CopperMicron4GB = 6,
DramId_IowaX1X2Samsung4GB = 7,
DramId_IowaSansung4GB = 8,

View File

@@ -20,18 +20,17 @@ namespace ams::pkg1 {
enum KeyGeneration : int {
KeyGeneration_1_0_0 = 0x00,
KeyGeneration_3_0_0 = 0x01,
KeyGeneration_3_0_1 = 0x02,
KeyGeneration_4_0_0 = 0x03,
KeyGeneration_5_0_0 = 0x04,
KeyGeneration_6_0_0 = 0x05,
KeyGeneration_6_2_0 = 0x06,
KeyGeneration_7_0_0 = 0x07,
KeyGeneration_8_1_0 = 0x08,
KeyGeneration_9_0_0 = 0x09,
KeyGeneration_9_1_0 = 0x0A,
KeyGeneration_12_1_0 = 0x0B,
KeyGeneration_1_0_0 = 0x00,
KeyGeneration_3_0_0 = 0x01,
KeyGeneration_3_0_1 = 0x02,
KeyGeneration_4_0_0 = 0x03,
KeyGeneration_5_0_0 = 0x04,
KeyGeneration_6_0_0 = 0x05,
KeyGeneration_6_2_0 = 0x06,
KeyGeneration_7_0_0 = 0x07,
KeyGeneration_8_1_0 = 0x08,
KeyGeneration_9_0_0 = 0x09,
KeyGeneration_9_1_0 = 0x0A,
KeyGeneration_Count,

View File

@@ -23,8 +23,8 @@ namespace ams::pkg2 {
constexpr inline int PayloadCount = 3;
constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x13 in Nintendo's code. */
constexpr inline int CurrentBootloaderVersion = 0xF;
constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x10 in Nintendo's code. */
constexpr inline int CurrentBootloaderVersion = 0xE;
struct Package2Meta {
using Magic = util::FourCC<'P','K','2','1'>;

View File

@@ -29,7 +29,6 @@ namespace ams::secmon {
SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess = (1u << 4),
SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary = (1u << 5),
SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc = (1u << 6),
SecureMonitorConfigurationFlag_ForceEnableUsb30 = (1u << 7),
SecureMonitorConfigurationFlag_Default = SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel,
};
@@ -102,7 +101,6 @@ namespace ams::secmon {
constexpr bool EnableUserModePerformanceCounterAccess() const { return (this->flags[0] & SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess) != 0; }
constexpr bool ShouldUseBlankCalibrationBinary() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary) != 0; }
constexpr bool AllowWritingToCalibrationBinarySysmmc() const { return (this->flags[0] & SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc) != 0; }
constexpr bool IsUsb30ForceEnabled() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ForceEnableUsb30) != 0; }
constexpr bool IsDevelopmentFunctionEnabled(bool for_kern) const { return for_kern ? this->IsDevelopmentFunctionEnabledForKernel() : this->IsDevelopmentFunctionEnabledForUser(); }
};

View File

@@ -165,7 +165,6 @@ namespace ams::fuse {
}
constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = {
TargetFirmware_12_0_2,
TargetFirmware_11_0_0,
TargetFirmware_10_0_0,
TargetFirmware_9_1_0,

View File

@@ -88,8 +88,6 @@ clean-$(strip $1):
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1))
@for i in $$(GCH_DIRS) $$(ATMOSPHERE_BUILD_DIR) $$(ATMOSPHERE_LIBRARY_DIR); do [ -d $$$$i ] && rmdir --ignore-fail-on-non-empty $$$$i || true; done
.PHONY: $(strip $1) clean-$(strip $1) $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
endef
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
@@ -111,7 +109,7 @@ $(eval $(call ATMOSPHERE_ADD_TARGET, audit, $(TARGET)_audit.a, \
ALL_GCH_IDENTIFIERS := $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(ATMOSPHERE_BOARD_NAME)_$(ATMOSPHERE_ARCH_NAME)_$(config))
ALL_GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(foreach id,$(ALL_GCH_IDENTIFIERS),$(hdr)/$(id)))
.PHONY: clean all
.PHONY: clean all $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
@[ -d $@ ] || mkdir -p $@
@@ -142,8 +140,6 @@ $(OFILES_SRC) : $(HFILES_BIN)
kern_libc_generic.o: CFLAGS += -fno-builtin
kern_k_auto_object.o: CXXFLAGS += -fno-lto
#---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin
#---------------------------------------------------------------------------------

View File

@@ -14,11 +14,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <mesosphere/kern_select_assembly_offsets.h>
namespace ams::kern::init {
struct alignas(util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE)) KInitArguments {
struct KInitArguments {
u64 ttbr0;
u64 ttbr1;
u64 tcr;
@@ -32,20 +31,5 @@ namespace ams::kern::init {
u64 setup_function;
u64 exception_stack;
};
static_assert(alignof(KInitArguments) == util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE));
static_assert(sizeof(KInitArguments) == std::max(INIT_ARGUMENTS_SIZE, util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE)));
static_assert(__builtin_offsetof(KInitArguments, ttbr0) == INIT_ARGUMENTS_TTBR0);
static_assert(__builtin_offsetof(KInitArguments, ttbr1) == INIT_ARGUMENTS_TTBR1);
static_assert(__builtin_offsetof(KInitArguments, tcr) == INIT_ARGUMENTS_TCR);
static_assert(__builtin_offsetof(KInitArguments, mair) == INIT_ARGUMENTS_MAIR);
static_assert(__builtin_offsetof(KInitArguments, cpuactlr) == INIT_ARGUMENTS_CPUACTLR);
static_assert(__builtin_offsetof(KInitArguments, cpuectlr) == INIT_ARGUMENTS_CPUECTLR);
static_assert(__builtin_offsetof(KInitArguments, sctlr) == INIT_ARGUMENTS_SCTLR);
static_assert(__builtin_offsetof(KInitArguments, sp) == INIT_ARGUMENTS_SP);
static_assert(__builtin_offsetof(KInitArguments, entrypoint) == INIT_ARGUMENTS_ENTRYPOINT);
static_assert(__builtin_offsetof(KInitArguments, argument) == INIT_ARGUMENTS_ARGUMENT);
static_assert(__builtin_offsetof(KInitArguments, setup_function) == INIT_ARGUMENTS_SETUP_FUNCTION);
static_assert(__builtin_offsetof(KInitArguments, exception_stack) == INIT_ARGUMENTS_EXCEPTION_STACK);
}

View File

@@ -38,67 +38,37 @@ namespace ams::kern::arch::arm64::init {
public:
class IPageAllocator {
public:
virtual KPhysicalAddress Allocate(size_t size) = 0;
virtual void Free(KPhysicalAddress phys_addr, size_t size) = 0;
virtual KPhysicalAddress Allocate() { return Null<KPhysicalAddress>; }
virtual void Free(KPhysicalAddress phys_addr) { /* Nothing to do here. */ (void)(phys_addr); }
};
private:
KPhysicalAddress m_l1_tables[2];
u32 m_num_entries[2];
struct NoClear{};
private:
KPhysicalAddress m_l1_table;
public:
KInitialPageTable(KVirtualAddress start_address, KVirtualAddress end_address, IPageAllocator &allocator) {
/* Set tables. */
m_l1_tables[0] = AllocateNewPageTable(allocator);
m_l1_tables[1] = AllocateNewPageTable(allocator);
constexpr ALWAYS_INLINE KInitialPageTable(KPhysicalAddress l1, NoClear) : m_l1_table(l1) { /* ... */ }
/* Set counts. */
m_num_entries[0] = MaxPageTableEntries;
m_num_entries[1] = ((end_address / L1BlockSize) & (MaxPageTableEntries - 1)) - ((start_address / L1BlockSize) & (MaxPageTableEntries - 1)) + 1;
constexpr ALWAYS_INLINE KInitialPageTable(KPhysicalAddress l1) : KInitialPageTable(l1, NoClear{}) {
ClearNewPageTable(m_l1_table);
}
KInitialPageTable() {
/* Set tables. */
m_l1_tables[0] = util::AlignDown(cpu::GetTtbr0El1(), PageSize);
m_l1_tables[1] = util::AlignDown(cpu::GetTtbr1El1(), PageSize);
/* Set counts. */
cpu::TranslationControlRegisterAccessor tcr;
m_num_entries[0] = tcr.GetT0Size() / L1BlockSize;
m_num_entries[1] = tcr.GetT1Size() / L1BlockSize;
/* Check counts. */
MESOSPHERE_INIT_ABORT_UNLESS(0 < m_num_entries[0] && m_num_entries[0] <= MaxPageTableEntries);
MESOSPHERE_INIT_ABORT_UNLESS(0 < m_num_entries[1] && m_num_entries[1] <= MaxPageTableEntries);
}
constexpr ALWAYS_INLINE uintptr_t GetTtbr0L1TableAddress() const {
return GetInteger(m_l1_tables[0]);
}
constexpr ALWAYS_INLINE uintptr_t GetTtbr1L1TableAddress() const {
return GetInteger(m_l1_tables[1]);
constexpr ALWAYS_INLINE uintptr_t GetL1TableAddress() const {
return GetInteger(m_l1_table);
}
private:
constexpr ALWAYS_INLINE L1PageTableEntry *GetL1Entry(KVirtualAddress address) const {
const size_t index = (GetInteger(address) >> (BITSIZEOF(address) - 1)) & 1;
L1PageTableEntry *l1_table = reinterpret_cast<L1PageTableEntry *>(GetInteger(m_l1_tables[index]));
return l1_table + ((GetInteger(address) / L1BlockSize) & (m_num_entries[index] - 1));
static constexpr ALWAYS_INLINE L1PageTableEntry *GetL1Entry(KPhysicalAddress _l1_table, KVirtualAddress address) {
L1PageTableEntry *l1_table = reinterpret_cast<L1PageTableEntry *>(GetInteger(_l1_table));
return l1_table + ((GetInteger(address) >> 30) & (MaxPageTableEntries - 1));
}
static constexpr ALWAYS_INLINE L2PageTableEntry *GetL2Entry(const L1PageTableEntry *entry, KVirtualAddress address) {
L2PageTableEntry *l2_table = reinterpret_cast<L2PageTableEntry *>(GetInteger(entry->GetTable()));
return l2_table + ((GetInteger(address) / L2BlockSize) & (MaxPageTableEntries - 1));
return l2_table + ((GetInteger(address) >> 21) & (MaxPageTableEntries - 1));
}
static constexpr ALWAYS_INLINE L3PageTableEntry *GetL3Entry(const L2PageTableEntry *entry, KVirtualAddress address) {
L3PageTableEntry *l3_table = reinterpret_cast<L3PageTableEntry *>(GetInteger(entry->GetTable()));
return l3_table + ((GetInteger(address) / L3BlockSize) & (MaxPageTableEntries - 1));
}
static ALWAYS_INLINE KPhysicalAddress AllocateNewPageTable(IPageAllocator &allocator) {
auto address = allocator.Allocate(PageSize);
ClearNewPageTable(address);
return address;
return l3_table + ((GetInteger(address) >> 12) & (MaxPageTableEntries - 1));
}
static ALWAYS_INLINE void ClearNewPageTable(KPhysicalAddress address) {
@@ -113,7 +83,7 @@ namespace ams::kern::arch::arm64::init {
const KVirtualAddress end_virt_addr = virt_addr + size;
size_t count = 0;
while (virt_addr < end_virt_addr) {
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr);
/* If an L1 block is mapped or we're empty, advance by L1BlockSize. */
if (l1_entry->IsBlock() || l1_entry->IsEmpty()) {
@@ -167,7 +137,7 @@ namespace ams::kern::arch::arm64::init {
const KVirtualAddress end_virt_addr = virt_addr + size;
size_t count = 0;
while (virt_addr < end_virt_addr) {
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr);
/* If an L1 block is mapped or we're empty, advance by L1BlockSize. */
if (l1_entry->IsBlock() || l1_entry->IsEmpty()) {
@@ -224,7 +194,7 @@ namespace ams::kern::arch::arm64::init {
}
PageTableEntry *GetMappingEntry(KVirtualAddress virt_addr, size_t block_size) {
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr);
if (l1_entry->IsBlock()) {
MESOSPHERE_INIT_ABORT_UNLESS(block_size == L1BlockSize);
@@ -331,7 +301,7 @@ namespace ams::kern::arch::arm64::init {
/* Iteratively map pages until the requested region is mapped. */
while (size > 0) {
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr);
/* Can we make an L1 block? */
if (util::IsAligned(GetInteger(virt_addr), L1BlockSize) && util::IsAligned(GetInteger(phys_addr), L1BlockSize) && size >= L1BlockSize) {
@@ -346,7 +316,7 @@ namespace ams::kern::arch::arm64::init {
/* If we don't already have an L2 table, we need to make a new one. */
if (!l1_entry->IsTable()) {
KPhysicalAddress new_table = AllocateNewPageTable(allocator);
KPhysicalAddress new_table = allocator.Allocate();
ClearNewPageTable(new_table);
*l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever());
cpu::DataSynchronizationBarrierInnerShareable();
@@ -380,7 +350,7 @@ namespace ams::kern::arch::arm64::init {
/* If we don't already have an L3 table, we need to make a new one. */
if (!l2_entry->IsTable()) {
KPhysicalAddress new_table = AllocateNewPageTable(allocator);
KPhysicalAddress new_table = allocator.Allocate();
ClearNewPageTable(new_table);
*l2_entry = L2PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever());
cpu::DataSynchronizationBarrierInnerShareable();
@@ -412,7 +382,7 @@ namespace ams::kern::arch::arm64::init {
KPhysicalAddress GetPhysicalAddress(KVirtualAddress virt_addr) const {
/* Get the L1 entry. */
const L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
const L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr);
if (l1_entry->IsBlock()) {
return l1_entry->GetBlock() + (GetInteger(virt_addr) & (L1BlockSize - 1));
@@ -474,7 +444,7 @@ namespace ams::kern::arch::arm64::init {
};
while (virt_addr < end_virt_addr) {
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr);
/* If an L1 block is mapped, update. */
if (l1_entry->IsBlock()) {
@@ -515,7 +485,7 @@ namespace ams::kern::arch::arm64::init {
const KVirtualAddress end_virt_addr = virt_addr + size;
while (virt_addr < end_virt_addr) {
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr);
/* If an L1 block is mapped, the address isn't free. */
if (l1_entry->IsBlock()) {
@@ -564,7 +534,7 @@ namespace ams::kern::arch::arm64::init {
/* Iteratively reprotect pages until the requested region is reprotected. */
while (size > 0) {
L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr);
/* Check if an L1 block is present. */
if (l1_entry->IsBlock()) {
@@ -703,18 +673,11 @@ namespace ams::kern::arch::arm64::init {
};
class KInitialPageAllocator final : public KInitialPageTable::IPageAllocator {
private:
static constexpr inline size_t FreeUnitSize = BITSIZEOF(u64) * PageSize;
struct FreeListEntry {
FreeListEntry *next;
size_t size;
};
class KInitialPageAllocator : public KInitialPageTable::IPageAllocator {
public:
struct State {
uintptr_t start_address;
uintptr_t end_address;
FreeListEntry *free_head;
uintptr_t next_address;
uintptr_t free_bitmap;
};
private:
State m_state;
@@ -722,8 +685,8 @@ namespace ams::kern::arch::arm64::init {
constexpr ALWAYS_INLINE KInitialPageAllocator() : m_state{} { /* ... */ }
ALWAYS_INLINE void Initialize(uintptr_t address) {
m_state.start_address = address;
m_state.end_address = address;
m_state.next_address = address + BITSIZEOF(m_state.free_bitmap) * PageSize;
m_state.free_bitmap = ~uintptr_t();
}
ALWAYS_INLINE void InitializeFromState(uintptr_t state_val) {
@@ -734,134 +697,28 @@ namespace ams::kern::arch::arm64::init {
*out = m_state;
m_state = {};
}
private:
bool CanAllocate(size_t align, size_t size) const {
for (auto *cur = m_state.free_head; cur != nullptr; cur = cur->next) {
const uintptr_t cur_last = reinterpret_cast<uintptr_t>(cur) + cur->size - 1;
const uintptr_t alloc_last = util::AlignUp(reinterpret_cast<uintptr_t>(cur), align) + size - 1;
if (alloc_last <= cur_last) {
return true;
}
}
return false;
}
bool TryAllocate(uintptr_t address, size_t size) {
/* Try to allocate the region. */
auto **prev_next = std::addressof(m_state.free_head);
for (auto *cur = m_state.free_head; cur != nullptr; prev_next = std::addressof(cur->next), cur = cur->next) {
const uintptr_t cur_start = reinterpret_cast<uintptr_t>(cur);
const uintptr_t cur_last = cur_start + cur->size - 1;
if (cur_start <= address && address + size - 1 <= cur_last) {
auto *alloc = reinterpret_cast<FreeListEntry *>(address);
/* Perform fragmentation at front. */
if (cur != alloc) {
prev_next = std::addressof(cur->next);
*alloc = {
.next = cur->next,
.size = cur_start + cur->size - address,
};
*cur = {
.next = alloc,
.size = address - cur_start,
};
}
/* Perform fragmentation at tail. */
if (alloc->size != size) {
auto *next = reinterpret_cast<FreeListEntry *>(address + size);
*next = {
.next = alloc->next,
.size = alloc->size - size,
};
*alloc = {
.next = next,
.size = size,
};
}
*prev_next = alloc->next;
return true;
}
}
return false;
}
public:
KPhysicalAddress Allocate(size_t align, size_t size) {
/* Ensure that the free list is non-empty. */
while (!this->CanAllocate(align, size)) {
this->Free(m_state.end_address, FreeUnitSize);
m_state.end_address += FreeUnitSize;
}
/* Allocate a random address. */
const uintptr_t aligned_start = util::AlignUp(m_state.start_address, align);
const uintptr_t aligned_end = util::AlignDown(m_state.end_address, align);
const size_t ind_max = ((aligned_end - aligned_start) / align) - 1;
while (true) {
if (const uintptr_t random_address = aligned_start + (KSystemControl::Init::GenerateRandomRange(0, ind_max) * align); this->TryAllocate(random_address, size)) {
return random_address;
}
}
}
virtual KPhysicalAddress Allocate(size_t size) override {
return this->Allocate(size, size);
}
virtual void Free(KPhysicalAddress phys_addr, size_t size) override {
auto **prev_next = std::addressof(m_state.free_head);
auto *new_chunk = reinterpret_cast<FreeListEntry *>(GetInteger(phys_addr));
if (auto *cur = m_state.free_head; cur != nullptr) {
const uintptr_t new_start = reinterpret_cast<uintptr_t>(new_chunk);
const uintptr_t new_end = GetInteger(phys_addr) + size;
while (true) {
/* Attempt coalescing. */
const uintptr_t cur_start = reinterpret_cast<uintptr_t>(cur);
const uintptr_t cur_end = cur_start + cur->size;
if (new_start < new_end) {
if (new_end < cur_start) {
*new_chunk = {
.next = cur,
.size = size,
};
break;
} else if (new_end == cur_start) {
*new_chunk = {
.next = cur->next,
.size = cur->size + size,
};
break;
}
} else if (cur_end == new_start) {
cur->size += size;
return;
}
prev_next = std::addressof(cur->next);
if (cur->next != nullptr) {
cur = cur->next;
} else {
*new_chunk = {
.next = nullptr,
.size = size,
};
cur->next = new_chunk;
return;
}
}
virtual KPhysicalAddress Allocate() override {
MESOSPHERE_INIT_ABORT_UNLESS(m_state.next_address != Null<uintptr_t>);
uintptr_t allocated = m_state.next_address;
if (m_state.free_bitmap != 0) {
u64 index;
uintptr_t mask;
do {
index = KSystemControl::Init::GenerateRandomRange(0, BITSIZEOF(m_state.free_bitmap) - 1);
mask = (static_cast<uintptr_t>(1) << index);
} while ((m_state.free_bitmap & mask) == 0);
m_state.free_bitmap &= ~mask;
allocated = m_state.next_address - ((BITSIZEOF(m_state.free_bitmap) - index) * PageSize);
} else {
*new_chunk = {
.next = nullptr,
.size = size,
};
m_state.next_address += PageSize;
}
*prev_next = new_chunk;
ClearPhysicalMemory(allocated, PageSize);
return allocated;
}
/* No need to override free. The default does nothing, and so would we. */
};
}

View File

@@ -1,157 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/* TODO: Different header for this? */
#define AMS_KERN_NUM_SUPERVISOR_CALLS 0xC0
/* ams::kern::KThread::StackParameters, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp */
#define THREAD_STACK_PARAMETERS_SIZE 0x30
#define THREAD_STACK_PARAMETERS_SVC_PERMISSION 0x00
#define THREAD_STACK_PARAMETERS_CONTEXT 0x18
#define THREAD_STACK_PARAMETERS_CUR_THREAD 0x20
#define THREAD_STACK_PARAMETERS_DISABLE_COUNT 0x28
#define THREAD_STACK_PARAMETERS_DPC_FLAGS 0x2A
#define THREAD_STACK_PARAMETERS_CURRENT_SVC_ID 0x2B
#define THREAD_STACK_PARAMETERS_IS_CALLING_SVC 0x2C
#define THREAD_STACK_PARAMETERS_IS_IN_EXCEPTION_HANDLER 0x2D
#define THREAD_STACK_PARAMETERS_IS_PINNED 0x2E
/* ams::kern::arch::arm64::KThreadContext, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_thread_context.hpp */
#define THREAD_CONTEXT_SIZE 0x290
#define THREAD_CONTEXT_CPU_REGISTERS 0x000
#define THREAD_CONTEXT_X19 0x000
#define THREAD_CONTEXT_X20 0x008
#define THREAD_CONTEXT_X21 0x010
#define THREAD_CONTEXT_X22 0x018
#define THREAD_CONTEXT_X23 0x020
#define THREAD_CONTEXT_X24 0x028
#define THREAD_CONTEXT_X25 0x030
#define THREAD_CONTEXT_X26 0x038
#define THREAD_CONTEXT_X27 0x040
#define THREAD_CONTEXT_X28 0x048
#define THREAD_CONTEXT_X29 0x050
#define THREAD_CONTEXT_LR 0x058
#define THREAD_CONTEXT_SP 0x060
#define THREAD_CONTEXT_CPACR 0x068
#define THREAD_CONTEXT_FPCR 0x070
#define THREAD_CONTEXT_FPSR 0x078
#define THREAD_CONTEXT_FPU_REGISTERS 0x080
#define THREAD_CONTEXT_LOCKED 0x280
#define THREAD_CONTEXT_X19_X20 THREAD_CONTEXT_X19
#define THREAD_CONTEXT_X21_X22 THREAD_CONTEXT_X21
#define THREAD_CONTEXT_X23_X24 THREAD_CONTEXT_X23
#define THREAD_CONTEXT_X25_X26 THREAD_CONTEXT_X25
#define THREAD_CONTEXT_X27_X28 THREAD_CONTEXT_X27
#define THREAD_CONTEXT_X29_X30 THREAD_CONTEXT_X29
#define THREAD_CONTEXT_LR_SP THREAD_CONTEXT_LR
#define THREAD_CONTEXT_SP_CPACR THREAD_CONTEXT_SP
#define THREAD_CONTEXT_FPCR_FPSR THREAD_CONTEXT_FPCR
/* ams::kern::arch::arm64::KExceptionContext, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_exception_context.hpp */
#define EXCEPTION_CONTEXT_SIZE 0x120
#define EXCEPTION_CONTEXT_X0 0x000
#define EXCEPTION_CONTEXT_X1 0x008
#define EXCEPTION_CONTEXT_X2 0x010
#define EXCEPTION_CONTEXT_X3 0x018
#define EXCEPTION_CONTEXT_X4 0x020
#define EXCEPTION_CONTEXT_X5 0x028
#define EXCEPTION_CONTEXT_X6 0x030
#define EXCEPTION_CONTEXT_X7 0x038
#define EXCEPTION_CONTEXT_X8 0x040
#define EXCEPTION_CONTEXT_X9 0x048
#define EXCEPTION_CONTEXT_X10 0x050
#define EXCEPTION_CONTEXT_X11 0x058
#define EXCEPTION_CONTEXT_X12 0x060
#define EXCEPTION_CONTEXT_X13 0x068
#define EXCEPTION_CONTEXT_X14 0x070
#define EXCEPTION_CONTEXT_X15 0x078
#define EXCEPTION_CONTEXT_X16 0x080
#define EXCEPTION_CONTEXT_X17 0x088
#define EXCEPTION_CONTEXT_X18 0x090
#define EXCEPTION_CONTEXT_X19 0x098
#define EXCEPTION_CONTEXT_X20 0x0A0
#define EXCEPTION_CONTEXT_X21 0x0A8
#define EXCEPTION_CONTEXT_X22 0x0B0
#define EXCEPTION_CONTEXT_X23 0x0B8
#define EXCEPTION_CONTEXT_X24 0x0C0
#define EXCEPTION_CONTEXT_X25 0x0C8
#define EXCEPTION_CONTEXT_X26 0x0D0
#define EXCEPTION_CONTEXT_X27 0x0D8
#define EXCEPTION_CONTEXT_X28 0x0E0
#define EXCEPTION_CONTEXT_X29 0x0E8
#define EXCEPTION_CONTEXT_X30 0x0F0
#define EXCEPTION_CONTEXT_SP 0x0F8
#define EXCEPTION_CONTEXT_PC 0x100
#define EXCEPTION_CONTEXT_PSR 0x108
#define EXCEPTION_CONTEXT_TPIDR 0x110
#define EXCEPTION_CONTEXT_X0_X1 EXCEPTION_CONTEXT_X0
#define EXCEPTION_CONTEXT_X2_X3 EXCEPTION_CONTEXT_X2
#define EXCEPTION_CONTEXT_X4_X5 EXCEPTION_CONTEXT_X4
#define EXCEPTION_CONTEXT_X6_X7 EXCEPTION_CONTEXT_X6
#define EXCEPTION_CONTEXT_X8_X9 EXCEPTION_CONTEXT_X8
#define EXCEPTION_CONTEXT_X10_X11 EXCEPTION_CONTEXT_X10
#define EXCEPTION_CONTEXT_X12_X13 EXCEPTION_CONTEXT_X12
#define EXCEPTION_CONTEXT_X14_X15 EXCEPTION_CONTEXT_X14
#define EXCEPTION_CONTEXT_X16_X17 EXCEPTION_CONTEXT_X16
#define EXCEPTION_CONTEXT_X18_X19 EXCEPTION_CONTEXT_X18
#define EXCEPTION_CONTEXT_X20_X21 EXCEPTION_CONTEXT_X20
#define EXCEPTION_CONTEXT_X22_X23 EXCEPTION_CONTEXT_X22
#define EXCEPTION_CONTEXT_X24_X25 EXCEPTION_CONTEXT_X24
#define EXCEPTION_CONTEXT_X26_X27 EXCEPTION_CONTEXT_X26
#define EXCEPTION_CONTEXT_X28_X29 EXCEPTION_CONTEXT_X28
#define EXCEPTION_CONTEXT_X30_SP EXCEPTION_CONTEXT_X30
#define EXCEPTION_CONTEXT_PC_PSR EXCEPTION_CONTEXT_PC
#define EXCEPTION_CONTEXT_X9_X10 EXCEPTION_CONTEXT_X9
#define EXCEPTION_CONTEXT_X19_X20 EXCEPTION_CONTEXT_X19
#define EXCEPTION_CONTEXT_X21_X22 EXCEPTION_CONTEXT_X21
#define EXCEPTION_CONTEXT_X23_X24 EXCEPTION_CONTEXT_X23
#define EXCEPTION_CONTEXT_X25_X26 EXCEPTION_CONTEXT_X25
#define EXCEPTION_CONTEXT_X27_X28 EXCEPTION_CONTEXT_X27
#define EXCEPTION_CONTEXT_X29_X30 EXCEPTION_CONTEXT_X29
#define EXCEPTION_CONTEXT_SP_PC EXCEPTION_CONTEXT_SP
#define EXCEPTION_CONTEXT_PSR_TPIDR EXCEPTION_CONTEXT_PSR
/* ams::svc::arch::arm64::ThreadLocalRegion, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libvapours/include/vapours/svc/arch/arm64/svc_thread_local_region.hpp */
#define THREAD_LOCAL_REGION_MESSAGE_BUFFER 0x000
#define THREAD_LOCAL_REGION_DISABLE_COUNT 0x100
#define THREAD_LOCAL_REGION_INTERRUPT_FLAG 0x102
#define THREAD_LOCAL_REGION_SIZE 0x200
/* ams::kern::init::KInitArguments, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp */
#define INIT_ARGUMENTS_SIZE 0x60
#define INIT_ARGUMENTS_TTBR0 0x00
#define INIT_ARGUMENTS_TTBR1 0x08
#define INIT_ARGUMENTS_TCR 0x10
#define INIT_ARGUMENTS_MAIR 0x18
#define INIT_ARGUMENTS_CPUACTLR 0x20
#define INIT_ARGUMENTS_CPUECTLR 0x28
#define INIT_ARGUMENTS_SCTLR 0x30
#define INIT_ARGUMENTS_SP 0x38
#define INIT_ARGUMENTS_ENTRYPOINT 0x40
#define INIT_ARGUMENTS_ARGUMENT 0x48
#define INIT_ARGUMENTS_SETUP_FUNCTION 0x50
#define INIT_ARGUMENTS_EXCEPTION_STACK 0x58
/* ams::kern::KScheduler (::SchedulingState), https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp */
/* NOTE: Due to constraints on ldarb relative offsets, KSCHEDULER_NEEDS_SCHEDULING cannot trivially be changed, and will require assembly edits. */
#define KSCHEDULER_NEEDS_SCHEDULING 0x00
#define KSCHEDULER_INTERRUPT_TASK_THREAD_RUNNABLE 0x01
#define KSCHEDULER_HIGHEST_PRIORITY_THREAD 0x10
#define KSCHEDULER_IDLE_THREAD_STACK 0x18

View File

@@ -172,8 +172,10 @@ namespace ams::kern::arch::arm64::cpu {
/* Cache management helpers. */
void ClearPageToZeroImpl(void *);
void FlushEntireDataCacheSharedForInit();
void FlushEntireDataCacheLocalForInit();
void InvalidateEntireInstructionCacheForInit();
void StoreEntireCacheForInit();
void FlushEntireCacheForInit();
void FlushEntireDataCache();
@@ -230,7 +232,7 @@ namespace ams::kern::arch::arm64::cpu {
}
ALWAYS_INLINE void SetExceptionThreadStackTop(uintptr_t top) {
cpu::SetCntvCvalEl0(top);
SetTpidrEl1(top);
}
ALWAYS_INLINE void SwitchThreadLocalRegion(uintptr_t tlr) {

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