Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f065e3bac | ||
|
|
9296a56303 | ||
|
|
481b209ae8 | ||
|
|
17ca463c3f | ||
|
|
f175802136 | ||
|
|
fe79bc253a | ||
|
|
81bf8c577a | ||
|
|
aee89db748 | ||
|
|
f5704d25f8 | ||
|
|
73afa042f1 | ||
|
|
2da31b122f | ||
|
|
43bbfd29bb | ||
|
|
4cb4707f34 | ||
|
|
389c3b6baa | ||
|
|
0c596e682f | ||
|
|
4d430a4c61 | ||
|
|
0c41489f01 | ||
|
|
bd6155bcb4 | ||
|
|
3bedf56512 | ||
|
|
1be74ea6e2 | ||
|
|
14d458522d | ||
|
|
12bf9612cb | ||
|
|
ea7b6e14f9 | ||
|
|
5e3339e866 | ||
|
|
a7c14e03b9 | ||
|
|
9df13781c2 | ||
|
|
283736878d | ||
|
|
f863164648 | ||
|
|
3eb76fcd16 | ||
|
|
2088c5a34a | ||
|
|
846cde52e0 | ||
|
|
a3dd445b32 | ||
|
|
c362838e11 | ||
|
|
e086022b77 | ||
|
|
70c1bad08b | ||
|
|
38f9a76ba0 | ||
|
|
4892ffae15 | ||
|
|
25305257d6 | ||
|
|
e423aef033 | ||
|
|
8a6afe7909 | ||
|
|
c02f32f1bf | ||
|
|
2ab01ad33c |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -79,9 +79,8 @@ dkms.conf
|
|||||||
*.nam
|
*.nam
|
||||||
*.til
|
*.til
|
||||||
|
|
||||||
# KEYS file for sept-secondary.
|
# Compiled python files.
|
||||||
*.pyc
|
*.pyc
|
||||||
sept/sept-secondary/KEYS.py
|
|
||||||
|
|
||||||
.**/
|
.**/
|
||||||
|
|
||||||
|
|||||||
18
Makefile
18
Makefile
@@ -32,10 +32,7 @@ mesosphere: exosphere libraries
|
|||||||
troposphere: stratosphere
|
troposphere: stratosphere
|
||||||
$(MAKE) -C troposphere all
|
$(MAKE) -C troposphere all
|
||||||
|
|
||||||
sept: exosphere
|
fusee: exosphere mesosphere stratosphere
|
||||||
$(MAKE) -C sept all
|
|
||||||
|
|
||||||
fusee: exosphere mesosphere stratosphere sept
|
|
||||||
$(MAKE) -C $@ all
|
$(MAKE) -C $@ all
|
||||||
|
|
||||||
libraries:
|
libraries:
|
||||||
@@ -43,6 +40,7 @@ libraries:
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C fusee clean
|
$(MAKE) -C fusee clean
|
||||||
|
$(MAKE) -C emummc clean
|
||||||
rm -rf out
|
rm -rf out
|
||||||
|
|
||||||
dist-no-debug: all
|
dist-no-debug: all
|
||||||
@@ -60,7 +58,6 @@ dist-no-debug: all
|
|||||||
rm -rf out
|
rm -rf out
|
||||||
mkdir atmosphere-$(AMSVER)
|
mkdir atmosphere-$(AMSVER)
|
||||||
mkdir atmosphere-$(AMSVER)/atmosphere
|
mkdir atmosphere-$(AMSVER)/atmosphere
|
||||||
mkdir atmosphere-$(AMSVER)/sept
|
|
||||||
mkdir atmosphere-$(AMSVER)/switch
|
mkdir atmosphere-$(AMSVER)/switch
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/config_templates
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/config_templates
|
||||||
@@ -70,13 +67,6 @@ dist-no-debug: all
|
|||||||
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
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-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)/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/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/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/system_settings.ini atmosphere-$(AMSVER)/atmosphere/config_templates/system_settings.ini
|
||||||
@@ -108,7 +98,6 @@ dist-no-debug: all
|
|||||||
cp troposphere/daybreak/daybreak.nro atmosphere-$(AMSVER)/switch/daybreak.nro
|
cp troposphere/daybreak/daybreak.nro atmosphere-$(AMSVER)/switch/daybreak.nro
|
||||||
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
|
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)/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 ../;
|
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER)-WITHOUT_MESOSPHERE.zip ./*; cd ../;
|
||||||
rm -r atmosphere-$(AMSVER)
|
rm -r atmosphere-$(AMSVER)
|
||||||
mkdir out
|
mkdir out
|
||||||
@@ -132,9 +121,6 @@ dist: dist-no-debug
|
|||||||
cp fusee/fusee-primary/fusee-primary.elf atmosphere-$(AMSVER)-debug/fusee-primary.elf
|
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-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 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/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/program/program.elf atmosphere-$(AMSVER)-debug/exosphere-program.elf
|
||||||
cp exosphere/warmboot/warmboot.elf atmosphere-$(AMSVER)-debug/exosphere-warmboot.elf
|
cp exosphere/warmboot/warmboot.elf atmosphere-$(AMSVER)-debug/exosphere-warmboot.elf
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Building Atmosphère is a very straightforward process that relies almost exclus
|
|||||||
+ [PyCryptodome](https://pypi.org/project/pycryptodome) (optional)
|
+ [PyCryptodome](https://pypi.org/project/pycryptodome) (optional)
|
||||||
|
|
||||||
## Instructions
|
## 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:
|
2. Install the following packages via (dkp-)pacman:
|
||||||
+ `switch-dev`
|
+ `switch-dev`
|
||||||
@@ -21,12 +21,4 @@ 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):
|
3. Install the following library via python's package manager `pip`, required by [exosphere](components/exosphere.md):
|
||||||
+ `lz4`
|
+ `lz4`
|
||||||
|
|
||||||
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.
|
4. Finally, clone the Atmosphère repository and run `make` under its root directory.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|||||||
@@ -1,4 +1,43 @@
|
|||||||
# Changelog
|
# 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
|
## 0.19.4
|
||||||
+ Support was added for 12.0.3.
|
+ Support was added for 12.0.3.
|
||||||
+ A number of minor issues were fixed, including:
|
+ A number of minor issues were fixed, including:
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
# 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.
|
|
||||||
@@ -19,6 +19,8 @@ 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 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).
|
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.
|
Users may use homebrew programs to toggle cheats on and off at runtime via the cheat manager's service API.
|
||||||
@@ -40,30 +42,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.
|
Typically, instruction type is encoded in the upper nybble of the first instruction u32.
|
||||||
|
|
||||||
### Code Type 0: Store Static Value to Memory
|
### Code Type 0x0: Store Static Value to Memory
|
||||||
Code type 0 allows writing a static value to a memory address.
|
Code type 0x0 allows writing a static value to a memory address.
|
||||||
|
|
||||||
#### Encoding
|
#### Encoding
|
||||||
`0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
|
`0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
|
||||||
|
|
||||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
|
||||||
+ R: Register to use as an offset from memory region base.
|
+ R: Register to use as an offset from memory region base.
|
||||||
+ A: Immediate offset to use from memory region base.
|
+ A: Immediate offset to use from memory region base.
|
||||||
+ V: Value to write.
|
+ V: Value to write.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 1: Begin Conditional Block
|
### Code Type 0x1: Begin Conditional Block
|
||||||
Code type 1 performs a comparison of the contents of memory to a static value.
|
Code type 0x1 performs a comparison of the contents of memory to a static value.
|
||||||
|
|
||||||
If the condition is not met, all instructions until the appropriate conditional block terminator are skipped.
|
If the condition is not met, all instructions until the appropriate End or Else conditional block terminator are skipped.
|
||||||
|
|
||||||
#### Encoding
|
#### Encoding
|
||||||
`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
|
`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
|
||||||
|
|
||||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
|
||||||
+ C: Condition to use, see below.
|
+ C: Condition to use, see below.
|
||||||
+ A: Immediate offset to use from memory region base.
|
+ A: Immediate offset to use from memory region base.
|
||||||
+ V: Value to compare to.
|
+ V: Value to compare to.
|
||||||
@@ -78,16 +80,20 @@ If the condition is not met, all instructions until the appropriate conditional
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 2: End Conditional Block
|
### Code Type 0x2: End Conditional Block
|
||||||
Code type 2 marks the end of a conditional block (started by Code Type 1 or Code Type 8).
|
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.
|
||||||
|
|
||||||
#### Encoding
|
#### Encoding
|
||||||
`20000000`
|
`2X000000`
|
||||||
|
|
||||||
|
+ X: End type (0 = End, 1 = Else).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 3: Start/End Loop
|
### Code Type 0x3: Start/End Loop
|
||||||
Code type 3 allows for iterating in a loop a fixed number of times.
|
Code type 0x3 allows for iterating in a loop a fixed number of times.
|
||||||
|
|
||||||
#### Start Loop Encoding
|
#### Start Loop Encoding
|
||||||
`300R0000 VVVVVVVV`
|
`300R0000 VVVVVVVV`
|
||||||
@@ -102,8 +108,8 @@ Code type 3 allows for iterating in a loop a fixed number of times.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 4: Load Register with Static Value
|
### Code Type 0x4: Load Register with Static Value
|
||||||
Code type 4 allows setting a register to a constant value.
|
Code type 0x4 allows setting a register to a constant value.
|
||||||
|
|
||||||
#### Encoding
|
#### Encoding
|
||||||
`400R0000 VVVVVVVV VVVVVVVV`
|
`400R0000 VVVVVVVV VVVVVVVV`
|
||||||
@@ -113,29 +119,28 @@ Code type 4 allows setting a register to a constant value.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 5: Load Register with Memory Value
|
### Code Type 0x5: 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.
|
Code type 0x5 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
|
#### Load From Fixed Address Encoding
|
||||||
`5TMR00AA AAAAAAAA`
|
`5TMR00AA AAAAAAAA`
|
||||||
|
|
||||||
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
||||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
|
||||||
+ R: Register to load value into.
|
+ R: Register to load value into.
|
||||||
+ A: Immediate offset to use from memory region base.
|
+ A: Immediate offset to use from memory region base.
|
||||||
|
|
||||||
#### Load from Register Address Encoding
|
#### Load from Register Address Encoding
|
||||||
`5TMR10AA AAAAAAAA`
|
`5T0R10AA AAAAAAAA`
|
||||||
|
|
||||||
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
||||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
|
+ R: Register to load value into. (This register is also used as the base memory address).
|
||||||
+ R: Register to load value into.
|
|
||||||
+ A: Immediate offset to use from register R.
|
+ A: Immediate offset to use from register R.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 6: Store Static Value to Register Memory Address
|
### Code Type 0x6: Store Static Value to Register Memory Address
|
||||||
Code type 6 allows writing a fixed value to a memory address specified by a register.
|
Code type 0x6 allows writing a fixed value to a memory address specified by a register.
|
||||||
|
|
||||||
#### Encoding
|
#### Encoding
|
||||||
`6T0RIor0 VVVVVVVV VVVVVVVV`
|
`6T0RIor0 VVVVVVVV VVVVVVVV`
|
||||||
@@ -149,10 +154,10 @@ Code type 6 allows writing a fixed value to a memory address specified by a regi
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 7: Legacy Arithmetic
|
### Code Type 0x7: Legacy Arithmetic
|
||||||
Code type 7 allows performing arithmetic on registers.
|
Code type 0x7 allows performing arithmetic on registers.
|
||||||
|
|
||||||
However, it has been deprecated by Code type 9, and is only kept for backwards compatibility.
|
However, it has been deprecated by Code type 0x9, and is only kept for backwards compatibility.
|
||||||
|
|
||||||
#### Encoding
|
#### Encoding
|
||||||
`7T0RC000 VVVVVVVV`
|
`7T0RC000 VVVVVVVV`
|
||||||
@@ -171,8 +176,8 @@ However, it has been deprecated by Code type 9, and is only kept for backwards c
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 8: Begin Keypress Conditional Block
|
### Code Type 0x8: Begin Keypress Conditional Block
|
||||||
Code type 8 enters or skips a conditional block based on whether a key combination is pressed.
|
Code type 0x8 enters or skips a conditional block based on whether a key combination is pressed.
|
||||||
|
|
||||||
#### Encoding
|
#### Encoding
|
||||||
`8kkkkkkk`
|
`8kkkkkkk`
|
||||||
@@ -213,8 +218,8 @@ Note: This is the direct output of `hidKeysDown()`.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 9: Perform Arithmetic
|
### Code Type 0x9: Perform Arithmetic
|
||||||
Code type 9 allows performing arithmetic on registers.
|
Code type 0x9 allows performing arithmetic on registers.
|
||||||
|
|
||||||
#### Register Arithmetic Encoding
|
#### Register Arithmetic Encoding
|
||||||
`9TCRS0s0`
|
`9TCRS0s0`
|
||||||
@@ -248,8 +253,8 @@ Code type 9 allows performing arithmetic on registers.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 10: Store Register to Memory Address
|
### Code Type 0xA: Store Register to Memory Address
|
||||||
Code type 10 allows writing a register to memory.
|
Code type 0xA allows writing a register to memory.
|
||||||
|
|
||||||
#### Encoding
|
#### Encoding
|
||||||
`ATSRIOxa (aaaaaaaa)`
|
`ATSRIOxa (aaaaaaaa)`
|
||||||
@@ -272,13 +277,13 @@ Code type 10 allows writing a register to memory.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 11: Reserved
|
### Code Type 0xB: Reserved
|
||||||
Code Type 11 is currently reserved for future use.
|
Code Type 0xB is currently reserved for future use.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Code Type 12-15: Extended-Width Instruction
|
### Code Type 0xC-0xF: 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.
|
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.
|
||||||
|
|
||||||
This reserves an additional 64 opcodes for future use.
|
This reserves an additional 64 opcodes for future use.
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ Atmosphère provides six core components, mimicking to some degree the various l
|
|||||||
|
|
||||||
Additionally, Atmosphère also provides the following secondary components:
|
Additionally, Atmosphère also provides the following secondary components:
|
||||||
+ [emummc](components/emummc.md)
|
+ [emummc](components/emummc.md)
|
||||||
+ [sept](components/sept.md)
|
|
||||||
+ [libraries](components/libraries.md)
|
+ [libraries](components/libraries.md)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/m4xw/emuMMC
|
remote = https://github.com/m4xw/emuMMC
|
||||||
branch = develop
|
branch = develop
|
||||||
commit = 219c723c3001fbc33d47840ceceb83cf39a1d218
|
commit = cbc294c390ed73bb281bc1028a8899c053427112
|
||||||
parent = 7821241356c2f6b159945babf657ffd921957918
|
parent = 38f9a76ba028995ed3274da3a45b0254f09d1f59
|
||||||
method = rebase
|
method = rebase
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ CFLAGS += $(INCLUDE) -D__SWITCH__
|
|||||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||||
|
|
||||||
ASFLAGS := -g $(ARCH)
|
ASFLAGS := -g $(ARCH)
|
||||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
LDFLAGS = -specs=$(EMUMMCDIR)/emummc.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||||
|
|
||||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||||
|
|
||||||
|
|||||||
201
emummc/emummc.ld
Normal file
201
emummc/emummc.ld
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
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) }
|
||||||
|
}
|
||||||
8
emummc/emummc.specs
Normal file
8
emummc/emummc.specs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
%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
|
||||||
|
|
||||||
@@ -20,13 +20,13 @@
|
|||||||
|
|
||||||
namespace ams::secmon::loader {
|
namespace ams::secmon::loader {
|
||||||
|
|
||||||
NORETURN void UncompressAndExecute() {
|
NORETURN void UncompressAndExecute(const void *program, const void *boot_code) {
|
||||||
/* Uncompress the program image. */
|
/* Uncompress the program image. */
|
||||||
Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), program_lz4, program_lz4_size);
|
Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), program, program_lz4_size);
|
||||||
|
|
||||||
/* Copy the boot image to the end of IRAM */
|
/* Copy the boot image to the end of IRAM */
|
||||||
u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer<u8>() - boot_code_lz4_size;
|
u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer<u8>() - boot_code_lz4_size;
|
||||||
std::memcpy(relocated_boot_code, boot_code_lz4, boot_code_lz4_size);
|
std::memcpy(relocated_boot_code, boot_code, boot_code_lz4_size);
|
||||||
|
|
||||||
/* Uncompress the boot image. */
|
/* Uncompress the boot image. */
|
||||||
Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, boot_code_lz4_size);
|
Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, boot_code_lz4_size);
|
||||||
|
|||||||
@@ -98,8 +98,8 @@ _start:
|
|||||||
ldr x20, =0x7C020000
|
ldr x20, =0x7C020000
|
||||||
mov sp, x20
|
mov sp, x20
|
||||||
|
|
||||||
/* Call our init array functions. */
|
adr x0, program_lz4
|
||||||
bl __libc_init_array
|
adr x1, boot_code_lz4
|
||||||
|
|
||||||
/* Uncompress the program and iram boot code images. */
|
/* Uncompress the program and iram boot code images. */
|
||||||
b _ZN3ams6secmon6loader20UncompressAndExecuteEv
|
b _ZN3ams6secmon6loader20UncompressAndExecuteEPKvS3_
|
||||||
|
|||||||
@@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
|
|||||||
/* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */
|
/* 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. */
|
/* TODO: Update on next change of keys. */
|
||||||
/* Mariko Development Master Kek Source. */
|
/* Mariko Development Master Kek Source. */
|
||||||
.byte 0xF9, 0x37, 0xCF, 0x9A, 0xBD, 0x86, 0xBB, 0xA9, 0x9C, 0x9E, 0x03, 0xC4, 0xFC, 0xBC, 0x3B, 0xCE
|
.byte 0x75, 0x2D, 0x2E, 0xF3, 0x2F, 0x3F, 0xFE, 0x65, 0xF4, 0xA9, 0x83, 0xB4, 0xED, 0x42, 0x63, 0xBA
|
||||||
|
|
||||||
/* Mariko Production Master Kek Source. */
|
/* Mariko Production Master Kek Source. */
|
||||||
.byte 0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82
|
.byte 0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1
|
||||||
|
|
||||||
/* Development Master Key Vectors. */
|
/* 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. */
|
.byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */
|
||||||
@@ -102,6 +102,7 @@ _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 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 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 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. */
|
/* 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. */
|
.byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */
|
||||||
@@ -115,33 +116,37 @@ _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 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 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 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. */
|
/* 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 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 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 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 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 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 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 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 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. */
|
||||||
|
|
||||||
/* Development Device Master Kek Sources. */
|
/* 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 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 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 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 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 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 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 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 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. */
|
||||||
|
|
||||||
/* Production Device Master Kek Sources. */
|
/* 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 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 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 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 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 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 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 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 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. */
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ namespace ams::secmon::boot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the key generation is one that we can use. */
|
/* Check that the key generation is one that we can use. */
|
||||||
static_assert(pkg1::KeyGeneration_Count == 11);
|
static_assert(pkg1::KeyGeneration_Count == 12);
|
||||||
if (key_generation >= pkg1::KeyGeneration_Count) {
|
if (key_generation >= pkg1::KeyGeneration_Count) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -272,7 +272,19 @@ namespace ams::secmon::smc {
|
|||||||
|
|
||||||
void GetSecureDataImpl(u8 *dst, SecureData which, bool tweak) {
|
void GetSecureDataImpl(u8 *dst, SecureData which, bool tweak) {
|
||||||
/* Compute the appropriate AES-CTR. */
|
/* Compute the appropriate AES-CTR. */
|
||||||
se::ComputeAes128Ctr(dst, AesKeySize, pkg1::AesKeySlot_Device, SecureDataSource, AesKeySize, GetSecureDataCounter(which), AesKeySize);
|
{
|
||||||
|
/* 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();
|
||||||
|
}
|
||||||
|
|
||||||
/* Tweak, if we should. */
|
/* Tweak, if we should. */
|
||||||
if (tweak) {
|
if (tweak) {
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ namespace ams::secmon::smc {
|
|||||||
(static_cast<u64>(ATMOSPHERE_RELEASE_VERSION_MINOR & 0xFF) << 48) |
|
(static_cast<u64>(ATMOSPHERE_RELEASE_VERSION_MINOR & 0xFF) << 48) |
|
||||||
(static_cast<u64>(ATMOSPHERE_RELEASE_VERSION_MICRO & 0xFF) << 40) |
|
(static_cast<u64>(ATMOSPHERE_RELEASE_VERSION_MICRO & 0xFF) << 40) |
|
||||||
(static_cast<u64>(GetKeyGeneration()) << 32) |
|
(static_cast<u64>(GetKeyGeneration()) << 32) |
|
||||||
(static_cast<u64>(GetTargetFirmware()) << 00);
|
(static_cast<u64>(GetTargetFirmware()) << 0);
|
||||||
break;
|
break;
|
||||||
case ConfigItem::ExosphereNeedsReboot:
|
case ConfigItem::ExosphereNeedsReboot:
|
||||||
/* We are executing, so we aren't in the process of rebooting. */
|
/* We are executing, so we aren't in the process of rebooting. */
|
||||||
@@ -290,6 +290,12 @@ namespace ams::secmon::smc {
|
|||||||
/* Get whether usb 3.0 should be force-enabled. */
|
/* Get whether usb 3.0 should be force-enabled. */
|
||||||
args.r[1] = GetSecmonConfiguration().IsUsb30ForceEnabled();
|
args.r[1] = GetSecmonConfiguration().IsUsb30ForceEnabled();
|
||||||
break;
|
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:
|
default:
|
||||||
return SmcResult::InvalidArgument;
|
return SmcResult::InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,17 +40,18 @@ namespace ams::secmon::smc {
|
|||||||
Package2Hash = 17,
|
Package2Hash = 17,
|
||||||
|
|
||||||
/* Extension config items for exosphere. */
|
/* Extension config items for exosphere. */
|
||||||
ExosphereApiVersion = 65000,
|
ExosphereApiVersion = 65000,
|
||||||
ExosphereNeedsReboot = 65001,
|
ExosphereNeedsReboot = 65001,
|
||||||
ExosphereNeedsShutdown = 65002,
|
ExosphereNeedsShutdown = 65002,
|
||||||
ExosphereGitCommitHash = 65003,
|
ExosphereGitCommitHash = 65003,
|
||||||
ExosphereHasRcmBugPatch = 65004,
|
ExosphereHasRcmBugPatch = 65004,
|
||||||
ExosphereBlankProdInfo = 65005,
|
ExosphereBlankProdInfo = 65005,
|
||||||
ExosphereAllowCalWrites = 65006,
|
ExosphereAllowCalWrites = 65006,
|
||||||
ExosphereEmummcType = 65007,
|
ExosphereEmummcType = 65007,
|
||||||
ExospherePayloadAddress = 65008,
|
ExospherePayloadAddress = 65008,
|
||||||
ExosphereLogConfiguration = 65009,
|
ExosphereLogConfiguration = 65009,
|
||||||
ExosphereForceEnableUsb30 = 65010,
|
ExosphereForceEnableUsb30 = 65010,
|
||||||
|
ExosphereSupportedHosVersion = 65011,
|
||||||
};
|
};
|
||||||
|
|
||||||
SmcResult SmcGetConfigUser(SmcArguments &args);
|
SmcResult SmcGetConfigUser(SmcArguments &args);
|
||||||
|
|||||||
@@ -17,8 +17,6 @@
|
|||||||
#include "../../../fusee/fusee-primary/fusee-primary-main/src/fs_utils.h"
|
#include "../../../fusee/fusee-primary/fusee-primary-main/src/fs_utils.h"
|
||||||
#elif defined(FUSEE_STAGE2_SRC)
|
#elif defined(FUSEE_STAGE2_SRC)
|
||||||
#include "../../../fusee/fusee-secondary/src/device_partition.h"
|
#include "../../../fusee/fusee-secondary/src/device_partition.h"
|
||||||
#elif defined(SEPT_STAGE2_SRC)
|
|
||||||
#include "../../../sept/sept-secondary/src/fs_utils.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FUSEE_STAGE2_SRC
|
#ifdef FUSEE_STAGE2_SRC
|
||||||
|
|||||||
@@ -30,8 +30,6 @@
|
|||||||
#include "../../../fusee/fusee-primary/fusee-primary-main/src/timers.h"
|
#include "../../../fusee/fusee-primary/fusee-primary-main/src/timers.h"
|
||||||
#elif defined(FUSEE_STAGE2_SRC)
|
#elif defined(FUSEE_STAGE2_SRC)
|
||||||
#include "../../../fusee/fusee-secondary/src/timers.h"
|
#include "../../../fusee/fusee-secondary/src/timers.h"
|
||||||
#elif defined(SEPT_STAGE2_SRC)
|
|
||||||
#include "../../../sept/sept-secondary/src/timers.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UNSTUFF_BITS(resp,start,size) \
|
#define UNSTUFF_BITS(resp,start,size) \
|
||||||
@@ -102,7 +100,7 @@ static int sdmmc_device_send_r1_cmd(sdmmc_device_t *device, uint32_t opcode, uin
|
|||||||
if (resp_mask) {
|
if (resp_mask) {
|
||||||
resp &= ~(resp_mask);
|
resp &= ~(resp_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We got an error state. */
|
/* We got an error state. */
|
||||||
if (is_sdmmc_device_r1_error(resp)) {
|
if (is_sdmmc_device_r1_error(resp)) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -355,7 +353,7 @@ static int sdmmc_sd_decode_scr(sdmmc_device_t *device, uint8_t *scr) {
|
|||||||
if (device->scr.sda_spec3) {
|
if (device->scr.sda_spec3) {
|
||||||
device->scr.cmds = UNSTUFF_BITS(resp, 32, 2);
|
device->scr.cmds = UNSTUFF_BITS(resp, 32, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unknown SCR structure version. */
|
/* Unknown SCR structure version. */
|
||||||
if (UNSTUFF_BITS(resp, 60, 4)) {
|
if (UNSTUFF_BITS(resp, 60, 4)) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -465,7 +463,7 @@ static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool i
|
|||||||
if (is_uhs_en) {
|
if (is_uhs_en) {
|
||||||
arg |= SD_OCR_S18R;
|
arg |= SD_OCR_S18R;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.opcode = SD_APP_OP_COND;
|
cmd.opcode = SD_APP_OP_COND;
|
||||||
cmd.arg = arg;
|
cmd.arg = arg;
|
||||||
cmd.flags = SDMMC_RSP_R3;
|
cmd.flags = SDMMC_RSP_R3;
|
||||||
@@ -916,7 +914,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
|
|||||||
if (!sdmmc_sd_decode_csd(device, csd)) {
|
if (!sdmmc_sd_decode_csd(device, csd)) {
|
||||||
sdmmc_warn(sdmmc, "Got unknown CSD structure (0x%08x)!", device->csd.structure);
|
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 we never switched to 1.8V, change the bus speed mode. */
|
||||||
if (!device->is_180v) {
|
if (!device->is_180v) {
|
||||||
/* Reconfigure the internal clock. */
|
/* Reconfigure the internal clock. */
|
||||||
@@ -1155,7 +1153,7 @@ static int sdmmc_mmc_send_op_cond(sdmmc_device_t *device, SdmmcBusVoltage bus_vo
|
|||||||
if (resp & SD_OCR_CCS) {
|
if (resp & SD_OCR_CCS) {
|
||||||
device->is_block_sdhc = true;
|
device->is_block_sdhc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1439,7 +1437,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
|
|||||||
if (!sdmmc_mmc_decode_csd(device, csd)) {
|
if (!sdmmc_mmc_decode_csd(device, csd)) {
|
||||||
sdmmc_warn(sdmmc, "Got unknown CSD structure (0x%08x)!", device->csd.structure);
|
sdmmc_warn(sdmmc, "Got unknown CSD structure (0x%08x)!", device->csd.structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reconfigure the internal clock. */
|
/* Reconfigure the internal clock. */
|
||||||
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_LEGACY)) {
|
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_LEGACY)) {
|
||||||
sdmmc_error(sdmmc, "Failed to apply the correct bus speed!");
|
sdmmc_error(sdmmc, "Failed to apply the correct bus speed!");
|
||||||
@@ -1498,7 +1496,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
|
|||||||
} else {
|
} else {
|
||||||
sdmmc_info(sdmmc, "BKOPS is disabled!");
|
sdmmc_info(sdmmc, "BKOPS is disabled!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Switch to high speed mode. */
|
/* Switch to high speed mode. */
|
||||||
if (!sdmmc_mmc_select_timing(device, bus_speed)) {
|
if (!sdmmc_mmc_select_timing(device, bus_speed)) {
|
||||||
sdmmc_error(sdmmc, "Failed to switch to high speed mode!");
|
sdmmc_error(sdmmc, "Failed to switch to high speed mode!");
|
||||||
|
|||||||
@@ -41,15 +41,6 @@
|
|||||||
#include "../../../fusee/fusee-secondary/src/gpio.h"
|
#include "../../../fusee/fusee-secondary/src/gpio.h"
|
||||||
#include "../../../fusee/fusee-secondary/src/pmc.h"
|
#include "../../../fusee/fusee-secondary/src/pmc.h"
|
||||||
#include "../../../fusee/fusee-secondary/src/max7762x.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
|
#endif
|
||||||
#include "../log.h"
|
#include "../log.h"
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ DEFINES := -D__BPMP__ -DFUSEE_MTC_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -
|
|||||||
|
|
||||||
CFLAGS := \
|
CFLAGS := \
|
||||||
-g \
|
-g \
|
||||||
|
-gdwarf-4 \
|
||||||
-O2 \
|
-O2 \
|
||||||
-fomit-frame-pointer \
|
-fomit-frame-pointer \
|
||||||
-ffunction-sections \
|
-ffunction-sections \
|
||||||
@@ -56,8 +57,8 @@ CFLAGS += $(INCLUDE)
|
|||||||
|
|
||||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||||
|
|
||||||
ASFLAGS := -g $(ARCH)
|
ASFLAGS := -g -gdwarf-4 $(ARCH)
|
||||||
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||||
|
|
||||||
LIBS :=
|
LIBS :=
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_CAR_H
|
#ifndef FUSEE_CAR_H
|
||||||
#define FUSEE_CAR_H
|
#define FUSEE_CAR_H
|
||||||
|
|
||||||
@@ -489,7 +489,16 @@ typedef struct {
|
|||||||
uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
|
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_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_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 */
|
||||||
|
|
||||||
|
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 */
|
||||||
} tegra_car_t;
|
} tegra_car_t;
|
||||||
|
|
||||||
static inline volatile tegra_car_t *car_get_regs(void) {
|
static inline volatile tegra_car_t *car_get_regs(void) {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_EMC_H_
|
#ifndef FUSEE_EMC_H_
|
||||||
#define FUSEE_EMC_H_
|
#define FUSEE_EMC_H_
|
||||||
|
|
||||||
@@ -393,6 +393,7 @@
|
|||||||
#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
|
#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
|
||||||
#define EMC_DIG_DLL_STATUS 0x2c4
|
#define EMC_DIG_DLL_STATUS 0x2c4
|
||||||
#define EMC_DIG_DLL_STATUS_DLL_LOCK (1 << 15)
|
#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_PRIV_UPDATED (1 << 17)
|
||||||
#define EMC_DIG_DLL_STATUS_DLL_OUT_SHIFT 0
|
#define EMC_DIG_DLL_STATUS_DLL_OUT_SHIFT 0
|
||||||
#define EMC_DIG_DLL_STATUS_DLL_OUT_MASK \
|
#define EMC_DIG_DLL_STATUS_DLL_OUT_MASK \
|
||||||
@@ -1065,6 +1066,10 @@
|
|||||||
#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQSN_TX_E_DCC (1 << 16)
|
#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_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_COMMON_PAD_TX_CTRL 0xc68
|
||||||
#define EMC_PMACRO_BRICK_MAPPING_0 0xc80
|
#define EMC_PMACRO_BRICK_MAPPING_0 0xc80
|
||||||
#define EMC_PMACRO_BRICK_MAPPING_1 0xc84
|
#define EMC_PMACRO_BRICK_MAPPING_1 0xc84
|
||||||
@@ -1126,4 +1131,8 @@
|
|||||||
|
|
||||||
#define EMC_PMACRO_DSR_VTTGEN_CTRL_0 0xc6c
|
#define EMC_PMACRO_DSR_VTTGEN_CTRL_0 0xc6c
|
||||||
|
|
||||||
|
// B01
|
||||||
|
#define EMC_PMACRO_DLL_CFG_0 0x5E4
|
||||||
|
#define EMC_PMACRO_DLL_CFG_1 0x5E8
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -28,28 +28,28 @@ static stage2_mtc_args_t *g_mtc_args;
|
|||||||
|
|
||||||
int main(int argc, void **argv) {
|
int main(int argc, void **argv) {
|
||||||
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
|
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
|
||||||
|
|
||||||
/* Check argc. */
|
/* Check argc. */
|
||||||
if (argc != MTC_ARGC) {
|
if (argc != MTC_ARGC) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract arguments from argv. */
|
/* Extract arguments from argv. */
|
||||||
g_mtc_args = &g_mtc_args_store;
|
g_mtc_args = &g_mtc_args_store;
|
||||||
memcpy(g_mtc_args, (stage2_mtc_args_t *)argv[MTC_ARGV_ARGUMENT_STRUCT], sizeof(*g_mtc_args));
|
memcpy(g_mtc_args, (stage2_mtc_args_t *)argv[MTC_ARGV_ARGUMENT_STRUCT], sizeof(*g_mtc_args));
|
||||||
log_level = g_mtc_args->log_level;
|
log_level = g_mtc_args->log_level;
|
||||||
|
|
||||||
/* Override the global logging level. */
|
/* Override the global logging level. */
|
||||||
log_set_log_level(log_level);
|
log_set_log_level(log_level);
|
||||||
|
|
||||||
if (log_level != SCREEN_LOG_LEVEL_NONE) {
|
if (log_level != SCREEN_LOG_LEVEL_NONE) {
|
||||||
/* Set framebuffer address. */
|
/* Set framebuffer address. */
|
||||||
g_framebuffer = (void *)0xC0000000;
|
g_framebuffer = (void *)0xC0000000;
|
||||||
|
|
||||||
/* Zero-fill the framebuffer and register it as printk provider. */
|
/* Zero-fill the framebuffer and register it as printk provider. */
|
||||||
video_init(g_framebuffer);
|
video_init(g_framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Train DRAM. */
|
/* Train DRAM. */
|
||||||
train_dram();
|
train_dram();
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -35,7 +35,7 @@
|
|||||||
#define TEGRA21_MAX_TABLE_ID_LEN 50
|
#define TEGRA21_MAX_TABLE_ID_LEN 50
|
||||||
#define TEGRA_EMC_ISO_USE_FREQ_MAX_NUM 12
|
#define TEGRA_EMC_ISO_USE_FREQ_MAX_NUM 12
|
||||||
#define PLL_C_DIRECT_FLOOR 333500000
|
#define PLL_C_DIRECT_FLOOR 333500000
|
||||||
#define EMC_STATUS_UPDATE_TIMEOUT 1000
|
#define EMC_STATUS_UPDATE_TIMEOUT 2000
|
||||||
#define TEGRA_EMC_DEFAULT_CLK_LATENCY_US 2000
|
#define TEGRA_EMC_DEFAULT_CLK_LATENCY_US 2000
|
||||||
|
|
||||||
#define TEGRA_EMC_MODE_REG_17 0x00110000
|
#define TEGRA_EMC_MODE_REG_17 0x00110000
|
||||||
|
|||||||
4180
fusee/fusee-mtc/src/mtc_b01.c
Normal file
4180
fusee/fusee-mtc/src/mtc_b01.c
Normal file
File diff suppressed because it is too large
Load Diff
689
fusee/fusee-mtc/src/mtc_b01.h
Normal file
689
fusee/fusee-mtc/src/mtc_b01.h
Normal file
@@ -0,0 +1,689 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
10551
fusee/fusee-mtc/src/mtc_tables_b01.h
Normal file
10551
fusee/fusee-mtc/src/mtc_tables_b01.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "utils.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) {
|
if (log_get_log_level() == SCREEN_LOG_LEVEL_NONE) {
|
||||||
/* Zero-fill the framebuffer and register it as printk provider. */
|
/* Zero-fill the framebuffer and register it as printk provider. */
|
||||||
video_init((void *)0xC0000000);
|
video_init((void *)0xC0000000);
|
||||||
|
|
||||||
/* Override the global logging level. */
|
/* Override the global logging level. */
|
||||||
log_set_log_level(SCREEN_LOG_LEVEL_ERROR);
|
log_set_log_level(SCREEN_LOG_LEVEL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display fatal error. */
|
/* Display fatal error. */
|
||||||
va_list args;
|
va_list args;
|
||||||
print(SCREEN_LOG_LEVEL_ERROR, "Fatal error: ");
|
print(SCREEN_LOG_LEVEL_ERROR, "Fatal error: ");
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vprint(SCREEN_LOG_LEVEL_ERROR, fmt, args);
|
vprint(SCREEN_LOG_LEVEL_ERROR, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Lock. */
|
/* Lock. */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
|
|||||||
|
|
||||||
CFLAGS := \
|
CFLAGS := \
|
||||||
-g \
|
-g \
|
||||||
|
-gdwarf-4 \
|
||||||
-O2 \
|
-O2 \
|
||||||
-fomit-frame-pointer \
|
-fomit-frame-pointer \
|
||||||
-ffunction-sections \
|
-ffunction-sections \
|
||||||
@@ -63,8 +64,8 @@ CFLAGS += $(INCLUDE)
|
|||||||
|
|
||||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||||
|
|
||||||
ASFLAGS := -g $(ARCH)
|
ASFLAGS := -g -gdwarf-4 $(ARCH)
|
||||||
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||||
|
|
||||||
LIBS :=
|
LIBS :=
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
|
|||||||
|
|
||||||
CFLAGS := \
|
CFLAGS := \
|
||||||
-g \
|
-g \
|
||||||
|
-gdwarf-4 \
|
||||||
-O2 \
|
-O2 \
|
||||||
-fomit-frame-pointer \
|
-fomit-frame-pointer \
|
||||||
-ffunction-sections \
|
-ffunction-sections \
|
||||||
@@ -56,8 +57,8 @@ CFLAGS += $(INCLUDE)
|
|||||||
|
|
||||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||||
|
|
||||||
ASFLAGS := -g $(ARCH)
|
ASFLAGS := -g -gdwarf-4 $(ARCH)
|
||||||
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||||
|
|
||||||
LIBS :=
|
LIBS :=
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,12 @@ static void config_se_brom(void) {
|
|||||||
|
|
||||||
/* Bootrom part we skipped. */
|
/* 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]};
|
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]};
|
||||||
set_aes_keyslot(0xE, sbk, 0x10);
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
if (sbk[i] != 0xFFFFFFFF) {
|
||||||
|
set_aes_keyslot(0xE, sbk, 0x10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Lock SBK from being read. */
|
/* Lock SBK from being read. */
|
||||||
se->SE_CRYPTO_KEYTABLE_ACCESS[0xE] = 0x7E;
|
se->SE_CRYPTO_KEYTABLE_ACCESS[0xE] = 0x7E;
|
||||||
@@ -247,7 +252,7 @@ void nx_hwinit(bool enable_log) {
|
|||||||
} else {
|
} else {
|
||||||
uint8_t val = 0x40;
|
uint8_t val = 0x40;
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
|
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
|
||||||
val = 0x60;
|
val = 0x58;
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
|
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
|
||||||
val = 0x38;
|
val = 0x38;
|
||||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1);
|
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE2_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
|
|||||||
|
|
||||||
CFLAGS := \
|
CFLAGS := \
|
||||||
-g \
|
-g \
|
||||||
|
-gdwarf-4 \
|
||||||
-O2 \
|
-O2 \
|
||||||
-fomit-frame-pointer \
|
-fomit-frame-pointer \
|
||||||
-ffunction-sections \
|
-ffunction-sections \
|
||||||
@@ -65,8 +66,8 @@ CFLAGS += $(INCLUDE)
|
|||||||
|
|
||||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||||
|
|
||||||
ASFLAGS := -g $(ARCH) $(INCLUDE) $(DEFINES)
|
ASFLAGS := -g -gdwarf-4 $(ARCH) $(INCLUDE) $(DEFINES)
|
||||||
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||||
|
|
||||||
LIBS :=
|
LIBS :=
|
||||||
|
|
||||||
@@ -91,8 +92,8 @@ export KIPDIRS := $(AMS)/stratosphere/loader $(AMS)/stratosphere/ncm $(AMS)/stra
|
|||||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
||||||
$(AMS)/exosphere $(AMS)/exosphere/warmboot $(AMS)/exosphere/program/rebootstub \
|
$(AMS)/exosphere $(AMS)/exosphere/warmboot $(AMS)/exosphere/program/rebootstub \
|
||||||
$(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/sept/sept-primary \
|
$(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/emummc $(AMS)/mesosphere \
|
||||||
$(AMS)/sept/sept-secondary $(AMS)/emummc $(AMS)/mesosphere $(AMS)/mesosphere/kernel_ldr $(KIPDIRS)
|
$(KIPDIRS)
|
||||||
|
|
||||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
@@ -102,9 +103,7 @@ SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
|||||||
KIPFILES := loader.kip ncm.kip pm.kip sm.kip ams_mitm.kip spl.kip boot.kip
|
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 \
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin \
|
||||||
exosphere.bin warmboot.bin rebootstub.bin thermosphere.bin splash_screen.bin \
|
exosphere.bin warmboot.bin rebootstub.bin thermosphere.bin splash_screen.bin \
|
||||||
sept-primary.bin sept-secondary_00.enc sept-secondary_01.enc emummc.kip \
|
emummc.kip mesosphere.bin mariko_fatal.bin $(KIPFILES)
|
||||||
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
|
# use CXX for linking C++ projects, CC for standard C
|
||||||
@@ -132,7 +131,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
|||||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||||
|
|
||||||
.PHONY: $(BUILD) clean all
|
.PHONY: $(BUILD) clean all
|
||||||
.PHONY: check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_stratosphere check_libraries
|
.PHONY: check_fusee_primary check_exosphere check_emummc check_thermosphere check_stratosphere check_libraries
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
all: $(BUILD)
|
all: $(BUILD)
|
||||||
@@ -143,9 +142,6 @@ check_fusee_primary:
|
|||||||
check_exosphere:
|
check_exosphere:
|
||||||
@$(MAKE) -C $(AMS)/exosphere all
|
@$(MAKE) -C $(AMS)/exosphere all
|
||||||
|
|
||||||
check_sept:
|
|
||||||
@$(MAKE) -C $(AMS)/sept all
|
|
||||||
|
|
||||||
check_emummc:
|
check_emummc:
|
||||||
@$(MAKE) -C $(AMS)/emummc EMUMMCDIR=$(AMS)/emummc all
|
@$(MAKE) -C $(AMS)/emummc EMUMMCDIR=$(AMS)/emummc all
|
||||||
|
|
||||||
@@ -162,7 +158,7 @@ check_libraries:
|
|||||||
@$(MAKE) -C $(AMS)/libraries all
|
@$(MAKE) -C $(AMS)/libraries all
|
||||||
|
|
||||||
|
|
||||||
$(BUILD): check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_libraries check_stratosphere check_mesosphere
|
$(BUILD): check_fusee_primary check_exosphere check_emummc check_thermosphere check_libraries check_stratosphere check_mesosphere
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
@@ -175,7 +171,6 @@ clean:
|
|||||||
@$(MAKE) -C $(AMS)/libraries clean
|
@$(MAKE) -C $(AMS)/libraries clean
|
||||||
@$(MAKE) -C $(AMS)/mesosphere clean
|
@$(MAKE) -C $(AMS)/mesosphere clean
|
||||||
@$(MAKE) -C $(AMS)/stratosphere clean
|
@$(MAKE) -C $(AMS)/stratosphere clean
|
||||||
@$(MAKE) -C $(AMS)/sept clean
|
|
||||||
@$(MAKE) -C $(AMS)/emummc clean
|
@$(MAKE) -C $(AMS)/emummc clean
|
||||||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
|
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
|
||||||
|
|
||||||
@@ -215,31 +210,6 @@ fusee_primary.bin.o fusee_primary_bin.h: fusee-primary.bin
|
|||||||
@echo $(notdir $<)
|
@echo $(notdir $<)
|
||||||
@$(_bin2o)
|
@$(_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
|
%.bin.o %_bin.h: %.bin
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
@echo $(notdir $<)
|
@echo $(notdir $<)
|
||||||
|
|||||||
BIN
fusee/fusee-secondary/data/tsec_keygen.bin
Normal file
BIN
fusee/fusee-secondary/data/tsec_keygen.bin
Normal file
Binary file not shown.
@@ -244,12 +244,6 @@ SECTIONS
|
|||||||
PROVIDE(__pm_kip_size__ = pm_kip_end - pm_kip);
|
PROVIDE(__pm_kip_size__ = pm_kip_end - pm_kip);
|
||||||
PROVIDE(__rebootstub_bin_start__ = rebootstub_bin - __start__);
|
PROVIDE(__rebootstub_bin_start__ = rebootstub_bin - __start__);
|
||||||
PROVIDE(__rebootstub_bin_size__ = rebootstub_bin_end - rebootstub_bin);
|
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_start__ = sm_kip - __start__);
|
||||||
PROVIDE(__sm_kip_size__ = sm_kip_end - sm_kip);
|
PROVIDE(__sm_kip_size__ = sm_kip_end - sm_kip);
|
||||||
PROVIDE(__spl_kip_start__ = spl_kip - __start__);
|
PROVIDE(__spl_kip_start__ = spl_kip - __start__);
|
||||||
@@ -266,4 +260,6 @@ SECTIONS
|
|||||||
PROVIDE(__mesosphere_bin_size__ = mesosphere_bin_end - mesosphere_bin);
|
PROVIDE(__mesosphere_bin_size__ = mesosphere_bin_end - mesosphere_bin);
|
||||||
PROVIDE(__mariko_fatal_bin_start__ = mariko_fatal_bin - __start__);
|
PROVIDE(__mariko_fatal_bin_start__ = mariko_fatal_bin - __start__);
|
||||||
PROVIDE(__mariko_fatal_bin_size__ = mariko_fatal_bin_end - mariko_fatal_bin);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_CAR_H
|
#ifndef FUSEE_CAR_H
|
||||||
#define FUSEE_CAR_H
|
#define FUSEE_CAR_H
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ typedef enum {
|
|||||||
CARDEVICE_USB2 = ((1 << 5) | 0x1A),
|
CARDEVICE_USB2 = ((1 << 5) | 0x1A),
|
||||||
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
|
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
|
||||||
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
||||||
CARDEVICE_MSELECT = ((3 << 5) | 0x8),
|
CARDEVICE_MSELECT = ((3 << 5) | 0x3),
|
||||||
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
|
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
|
||||||
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
|
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
|
||||||
CARDEVICE_SE = ((3 << 5) | 0x1F),
|
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_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_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_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;
|
} tegra_car_t;
|
||||||
|
|
||||||
static inline volatile tegra_car_t *car_get_regs(void) {
|
static inline volatile tegra_car_t *car_get_regs(void) {
|
||||||
|
|||||||
@@ -21,12 +21,6 @@
|
|||||||
#include "kernel_patches.h"
|
#include "kernel_patches.h"
|
||||||
#include "ips.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_BRANCH(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
|
||||||
#define MAKE_NOP 0xD503201F
|
#define MAKE_NOP 0xD503201F
|
||||||
|
|
||||||
|
|||||||
@@ -26,19 +26,6 @@
|
|||||||
|
|
||||||
#define AL16 ALIGN(16)
|
#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] = {
|
static const uint8_t AL16 masterkey_seed[0x10] = {
|
||||||
0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C
|
0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C
|
||||||
};
|
};
|
||||||
@@ -55,164 +42,51 @@ 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
|
0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TODO: Bother adding 8.1.0 here? We'll never call into here... */
|
static const uint8_t AL16 keyblob_seed_00[0x10] = {
|
||||||
static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_800 - MASTERKEY_REVISION_600_610][0x10] = {
|
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3
|
||||||
{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_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
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t AL16 master_kek_seed_mariko[0x10] = { /* TODO: Update on next change of keys. */
|
static const uint8_t AL16 master_kek_seed_mariko[0x10] = { /* TODO: Update on next change of keys. */
|
||||||
0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82, /* Mariko MasterKek seed 0A. */
|
0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1, /* Mariko MasterKek seed 0B. */
|
||||||
};
|
};
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (get_keyblob(&keyblob, revision, keyblobs, available_revision) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int load_package1_key(uint32_t revision) {
|
|
||||||
if (revision > MASTERKEY_REVISION_600_610) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_aes_keyslot(0xB, g_dec_keyblobs[revision].package1_key, 0x10);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive all Switch keys. */
|
/* 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) {
|
int derive_nx_keydata_erista(uint32_t target_firmware) {
|
||||||
uint8_t AL16 work_buffer[0x10];
|
uint8_t AL16 work_buffer[0x10];
|
||||||
uint8_t AL16 zeroes[0x10] = {0};
|
|
||||||
|
|
||||||
/* Initialize keygen type. */
|
/* Get whether we're using dev keys. */
|
||||||
*out_keygen_type = 0;
|
const bool is_retail = fuse_get_hardware_state() != 0;
|
||||||
|
|
||||||
/* TODO: Set keyslot flags properly in preparation of derivation. */
|
/* Derive Keyblob Key 00. */
|
||||||
set_aes_keyslot_flags(0xE, 0x15);
|
se_aes_ecb_decrypt_block(0xC, work_buffer, 0x10, keyblob_seed_00, 0x10);
|
||||||
set_aes_keyslot_flags(0xD, 0x15);
|
decrypt_data_into_keyslot(0xF, 0xE, work_buffer, 0x10);
|
||||||
|
|
||||||
/* Set the TSEC key. */
|
/* Derive master kek. */
|
||||||
set_aes_keyslot(0xD, tsec_key, 0x10);
|
decrypt_data_into_keyslot(0xE, is_retail ? 0xD : 0xB, master_kek_seed_erista, 0x10);
|
||||||
|
|
||||||
/* Decrypt all keyblobs, setting keyslot 0xF correctly. */
|
/* Derive master key, device master key. */
|
||||||
for (unsigned int rev = 0; rev <= MASTERKEY_REVISION_600_610; rev++) {
|
decrypt_data_into_keyslot(0xD, 0xE, masterkey_seed, 0x10);
|
||||||
int ret = decrypt_keyblob(keyblobs, rev, available_revision);
|
decrypt_data_into_keyslot(0xE, 0xE, masterkey_4x_seed, 0x10);
|
||||||
if (ret) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do 6.2.0+ keygen. */
|
/* Derive device keys. */
|
||||||
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(0xA, 0xF, devicekey_4x_seed, 0x10);
|
||||||
decrypt_data_into_keyslot(0xF, 0xF, devicekey_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);
|
/* 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);
|
||||||
|
|
||||||
|
/* Clear keyslots 0xB/0xE. */
|
||||||
|
clear_aes_keyslot(0xB);
|
||||||
|
clear_aes_keyslot(0xE);
|
||||||
|
|
||||||
/* Setup master key revision, derive older master keys for use. */
|
/* Setup master key revision, derive older master keys for use. */
|
||||||
return mkey_detect_revision(fuse_get_hardware_state() != 0);
|
return mkey_detect_revision(fuse_get_hardware_state() != 0);
|
||||||
|
|||||||
@@ -27,29 +27,8 @@ typedef enum BisPartition {
|
|||||||
BisPartition_UserSystem = 2,
|
BisPartition_UserSystem = 2,
|
||||||
} BisPartition;
|
} BisPartition;
|
||||||
|
|
||||||
typedef struct {
|
int derive_nx_keydata_erista(uint32_t target_firmware);
|
||||||
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 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);
|
void derive_bis_key(void *dst, BisPartition partition_id, uint32_t target_firmware);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ 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. */
|
{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. */
|
{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. */
|
{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. */
|
/* Retail unit keys. */
|
||||||
@@ -59,17 +60,19 @@ 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. */
|
{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. */
|
{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. */
|
{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] = {
|
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. */
|
{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. */
|
{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. */
|
{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. */
|
{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. */
|
{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. */
|
{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. */
|
{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. */
|
{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. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
|
static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
|
||||||
@@ -80,7 +83,8 @@ 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. */
|
{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. */
|
{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. */
|
{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 to be added on next change-of-keys. */
|
{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. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
|
static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
|
||||||
@@ -91,7 +95,8 @@ 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. */
|
{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. */
|
{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. */
|
{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 to be added on next change-of-keys. */
|
{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. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Determine the current SoC for Mariko specific code. */
|
/* Determine the current SoC for Mariko specific code. */
|
||||||
@@ -180,8 +185,8 @@ void derive_new_device_keys(bool is_retail, unsigned int keygen_keyslot, unsigne
|
|||||||
if (relative_revision > mkey_get_revision()) {
|
if (relative_revision > mkey_get_revision()) {
|
||||||
break;
|
break;
|
||||||
} else if (relative_revision == mkey_get_revision()) {
|
} else if (relative_revision == mkey_get_revision()) {
|
||||||
/* On 7.0.0 erista, sept will have derived this key for us already. */
|
/* On Erista, this will already be derived. */
|
||||||
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0 || is_mariko) {
|
if (is_mariko) {
|
||||||
decrypt_data_into_keyslot(is_mariko ? KEYSLOT_SWITCH_DEVICEKEY_MARIKO : KEYSLOT_SWITCH_DEVICEKEY, KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10);
|
decrypt_data_into_keyslot(is_mariko ? KEYSLOT_SWITCH_DEVICEKEY_MARIKO : KEYSLOT_SWITCH_DEVICEKEY, KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
|
|
||||||
/* This is glue code to enable master key support across versions. */
|
/* This is glue code to enable master key support across versions. */
|
||||||
|
|
||||||
/* TODO: Update to 0xC on release of new master key. */
|
/* TODO: Update to 0xD on release of new master key. */
|
||||||
#define MASTERKEY_REVISION_MAX 0xB
|
#define MASTERKEY_REVISION_MAX 0xC
|
||||||
|
|
||||||
#define MASTERKEY_REVISION_100_230 0x00
|
#define MASTERKEY_REVISION_100_230 0x00
|
||||||
#define MASTERKEY_REVISION_300 0x01
|
#define MASTERKEY_REVISION_300 0x01
|
||||||
@@ -32,7 +32,8 @@
|
|||||||
#define MASTERKEY_REVISION_700_800 0x07
|
#define MASTERKEY_REVISION_700_800 0x07
|
||||||
#define MASTERKEY_REVISION_810 0x08
|
#define MASTERKEY_REVISION_810 0x08
|
||||||
#define MASTERKEY_REVISION_900 0x09
|
#define MASTERKEY_REVISION_900 0x09
|
||||||
#define MASTERKEY_REVISION_910_CURRENT 0x0A
|
#define MASTERKEY_REVISION_910_1203 0x0A
|
||||||
|
#define MASTERKEY_REVISION_C10_CURRENT 0x0B
|
||||||
|
|
||||||
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)
|
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,6 @@
|
|||||||
#include "masterkey.h"
|
#include "masterkey.h"
|
||||||
#include "package1.h"
|
#include "package1.h"
|
||||||
#include "package2.h"
|
#include "package2.h"
|
||||||
#include "smmu.h"
|
|
||||||
#include "tsec.h"
|
#include "tsec.h"
|
||||||
#include "lp0.h"
|
#include "lp0.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
@@ -59,11 +58,8 @@
|
|||||||
#include "exosphere_bin.h"
|
#include "exosphere_bin.h"
|
||||||
#include "mariko_fatal_bin.h"
|
#include "mariko_fatal_bin.h"
|
||||||
#include "mesosphere_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 "warmboot_bin.h"
|
||||||
|
#include "tsec_keygen_bin.h"
|
||||||
#include "emummc_kip.h"
|
#include "emummc_kip.h"
|
||||||
#undef u8
|
#undef u8
|
||||||
#undef u32
|
#undef u32
|
||||||
@@ -285,7 +281,9 @@ static bool is_nca_present(const char *nca_name) {
|
|||||||
static uint32_t nxboot_get_specific_target_firmware(uint32_t target_firmware){
|
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)
|
#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_0_2) {
|
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("a1863a5c0e1cedd442f5e60b0422dc15", 12_0_3);
|
||||||
CHECK_NCA("63d928b5a3016fe8cc0e76d2f06f4e98", 12_0_2);
|
CHECK_NCA("63d928b5a3016fe8cc0e76d2f06f4e98", 12_0_2);
|
||||||
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_0) {
|
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_0) {
|
||||||
@@ -398,6 +396,8 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
|
|||||||
return ATMOSPHERE_TARGET_FIRMWARE_12_0_0;
|
return ATMOSPHERE_TARGET_FIRMWARE_12_0_0;
|
||||||
} else if (memcmp(package1loader_header->build_timestamp, "20210422", 8) == 0) {
|
} else if (memcmp(package1loader_header->build_timestamp, "20210422", 8) == 0) {
|
||||||
return ATMOSPHERE_TARGET_FIRMWARE_12_0_2;
|
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 {
|
} else {
|
||||||
fatal_error("[NXBOOT] Unable to identify package1!\n");
|
fatal_error("[NXBOOT] Unable to identify package1!\n");
|
||||||
}
|
}
|
||||||
@@ -720,18 +720,11 @@ static void nxboot_move_bootconfig() {
|
|||||||
free(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) {
|
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);
|
snprintf(dst, dst_size, "warmboot_mariko/wb_%02" PRIx32 ".bin", version);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the main function responsible for booting Horizon. */
|
/* This is the main function responsible for booting Horizon. */
|
||||||
static nx_keyblob_t __attribute__((aligned(16))) g_keyblobs[32];
|
|
||||||
uint32_t nxboot_main(void) {
|
uint32_t nxboot_main(void) {
|
||||||
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||||
loader_ctx_t *loader_ctx = get_loader_ctx();
|
loader_ctx_t *loader_ctx = get_loader_ctx();
|
||||||
@@ -741,8 +734,6 @@ uint32_t nxboot_main(void) {
|
|||||||
size_t package2_size;
|
size_t package2_size;
|
||||||
void *tsec_fw;
|
void *tsec_fw;
|
||||||
size_t tsec_fw_size;
|
size_t tsec_fw_size;
|
||||||
const void *sept_secondary_enc = NULL;
|
|
||||||
size_t sept_secondary_enc_size = 0;
|
|
||||||
void *warmboot_fw;
|
void *warmboot_fw;
|
||||||
size_t warmboot_fw_size;
|
size_t warmboot_fw_size;
|
||||||
void *warmboot_memaddr;
|
void *warmboot_memaddr;
|
||||||
@@ -752,7 +743,6 @@ uint32_t nxboot_main(void) {
|
|||||||
size_t mesosphere_size;
|
size_t mesosphere_size;
|
||||||
void *emummc;
|
void *emummc;
|
||||||
size_t emummc_size;
|
size_t emummc_size;
|
||||||
uint32_t available_revision;
|
|
||||||
FILE *boot0, *pk2file;
|
FILE *boot0, *pk2file;
|
||||||
void *exosphere_memaddr;
|
void *exosphere_memaddr;
|
||||||
exo_emummc_config_t exo_emummc_cfg;
|
exo_emummc_config_t exo_emummc_cfg;
|
||||||
@@ -840,7 +830,7 @@ uint32_t nxboot_main(void) {
|
|||||||
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
|
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (package1_read_and_parse_boot0_erista(&package1loader, &package1loader_size, g_keyblobs, &available_revision, boot0) == -1) {
|
if (package1_read_and_parse_boot0_erista(&package1loader, &package1loader_size, boot0) == -1) {
|
||||||
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
|
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -856,103 +846,26 @@ uint32_t nxboot_main(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle TSEC and Sept (Erista only). */
|
/* Handle TSEC and Sept (Erista only). */
|
||||||
uint8_t tsec_key[0x10] = {0};
|
|
||||||
uint8_t tsec_root_keys[0x20][0x10] = {0};
|
|
||||||
if (!is_mariko) {
|
if (!is_mariko) {
|
||||||
/* Read the TSEC firmware from a file, otherwise from PK1L. */
|
/* Use Atmosphere's tsec_keygen implementation. */
|
||||||
if (loader_ctx->tsecfw_path[0] != '\0') {
|
tsec_fw_size = tsec_keygen_bin_size;
|
||||||
tsec_fw_size = get_file_size(loader_ctx->tsecfw_path);
|
tsec_fw = memalign(0x100, tsec_fw_size);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for the TSEC firmware. */
|
if (tsec_fw == NULL) {
|
||||||
tsec_fw = memalign(0x100, tsec_fw_size);
|
fatal_error("[NXBOOT] Out of memory!\n");
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Loaded firmware from eMMC...\n");
|
memcpy(tsec_fw, tsec_keygen_bin, tsec_fw_size);
|
||||||
|
|
||||||
/* Get the TSEC keys. */
|
if (tsec_fw_size == 0) {
|
||||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
|
fatal_error("[NXBOOT] Could not read the warmboot firmware from Package1!\n");
|
||||||
/* 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};
|
|
||||||
|
|
||||||
/* Emulate the TSEC payload on 6.2.0+. */
|
/* Get the TSEC keys into the security engine. */
|
||||||
smmu_emulate_tsec((void *)tsec_keys, package1loader, package1loader_size, package1loader);
|
int tsec_res = tsec_run_fw(tsec_fw, tsec_fw_size);
|
||||||
|
if (tsec_res != 0) {
|
||||||
/* Copy back the keys. */
|
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
||||||
memcpy((void *)tsec_key, (void *)tsec_keys, 0x10);
|
fatal_error("[NXBOOT] Failed to run TSEC firmware %d %08x %08x!\n", tsec_res, tsec->TSEC_FALCON_MAILBOX0, tsec->TSEC_FALCON_MAILBOX1);
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -965,8 +878,8 @@ uint32_t nxboot_main(void) {
|
|||||||
if (derive_nx_keydata_mariko(target_firmware) != 0) {
|
if (derive_nx_keydata_mariko(target_firmware) != 0) {
|
||||||
fatal_error("[NXBOOT] Mariko key derivation failed!\n");
|
fatal_error("[NXBOOT] Mariko key derivation failed!\n");
|
||||||
}
|
}
|
||||||
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) { /* If on 7.0.0+, sept has already derived keys for us (Erista only). */
|
} else {
|
||||||
if (derive_nx_keydata_erista(target_firmware, g_keyblobs, available_revision, tsec_key, tsec_root_keys, &keygen_type) != 0) {
|
if (derive_nx_keydata_erista(target_firmware) != 0) {
|
||||||
fatal_error("[NXBOOT] Erista key derivation failed!\n");
|
fatal_error("[NXBOOT] Erista key derivation failed!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1226,9 +1139,6 @@ uint32_t nxboot_main(void) {
|
|||||||
|
|
||||||
/* Clean up. */
|
/* Clean up. */
|
||||||
free(package1loader);
|
free(package1loader);
|
||||||
if (loader_ctx->tsecfw_path[0] != '\0') {
|
|
||||||
free(tsec_fw);
|
|
||||||
}
|
|
||||||
if (loader_ctx->warmboot_path[0] != '\0') {
|
if (loader_ctx->warmboot_path[0] != '\0') {
|
||||||
free(warmboot_fw);
|
free(warmboot_fw);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,18 +24,10 @@
|
|||||||
#include "mc.h"
|
#include "mc.h"
|
||||||
#include "nxboot.h"
|
#include "nxboot.h"
|
||||||
#include "se.h"
|
#include "se.h"
|
||||||
#include "smmu.h"
|
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "sysreg.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) {
|
void nxboot_finish(uint32_t boot_memaddr) {
|
||||||
bool is_mariko = is_soc_mariko();
|
|
||||||
|
|
||||||
/* Boot up Exosphère. */
|
/* Boot up Exosphère. */
|
||||||
MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 0;
|
MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 0;
|
||||||
MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X;
|
MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X;
|
||||||
@@ -43,26 +35,8 @@ void nxboot_finish(uint32_t boot_memaddr) {
|
|||||||
/* Terminate the display. */
|
/* Terminate the display. */
|
||||||
display_end();
|
display_end();
|
||||||
|
|
||||||
if (is_mariko) {
|
/* Boot CPU0. */
|
||||||
/* Boot CPU0. */
|
cluster_boot_cpu0(boot_memaddr);
|
||||||
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. */
|
/* Wait for Exosphère to wake up. */
|
||||||
while (MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE == 0) {
|
while (MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE == 0) {
|
||||||
|
|||||||
@@ -58,16 +58,12 @@ bool package1_is_custom_public_key(const void *bct, bool mariko) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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_erista(void **package1loader, size_t *package1loader_size, FILE *boot0) {
|
||||||
nvboot_config_table *bct; /* Normal firmware BCT, primary. TODO: check? */
|
nvboot_config_table *bct; /* Normal firmware BCT, primary. TODO: check? */
|
||||||
nv_bootloader_info *pk1l_info; /* TODO: check? */
|
nv_bootloader_info *pk1l_info; /* TODO: check? */
|
||||||
size_t fpos, pk1l_offset;
|
size_t fpos, pk1l_offset;
|
||||||
union {
|
|
||||||
nx_keyblob_t keyblob;
|
|
||||||
uint8_t sector[0x200];
|
|
||||||
} d;
|
|
||||||
|
|
||||||
if (package1loader == NULL || package1loader_size == NULL || keyblobs == NULL || revision == NULL || boot0 == NULL) {
|
if (package1loader == NULL || package1loader_size == NULL || boot0 == NULL) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -105,7 +101,6 @@ int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*revision = pk1l_info->version - 1;
|
|
||||||
*package1loader_size = pk1l_info->length;
|
*package1loader_size = pk1l_info->length;
|
||||||
|
|
||||||
pk1l_offset = 0x4000 * pk1l_info->start_blk + 0x200 * pk1l_info->start_page;
|
pk1l_offset = 0x4000 * pk1l_info->start_blk + 0x200 * pk1l_info->start_page;
|
||||||
@@ -128,14 +123,6 @@ int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1
|
|||||||
return -1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,24 +198,6 @@ bool package1_get_tsec_fw(void **tsec_fw, const void *package1loader, size_t pac
|
|||||||
return false;
|
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) {
|
void *package1_get_warmboot_fw(const package1_header_t *package1) {
|
||||||
/*
|
/*
|
||||||
The layout of pk1 changes between versions.
|
The layout of pk1 changes between versions.
|
||||||
|
|||||||
@@ -59,14 +59,10 @@ typedef struct {
|
|||||||
|
|
||||||
bool package1_is_custom_public_key(const void *bct, bool mariko);
|
bool package1_is_custom_public_key(const void *bct, bool mariko);
|
||||||
|
|
||||||
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_erista(void **package1loader, size_t *package1loader_size, FILE *boot0);
|
||||||
int package1_read_and_parse_boot0_mariko(void **package1loader, size_t *package1loader_size, 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. */
|
/* 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);
|
void *package1_get_warmboot_fw(const package1_header_t *package1);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,284 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
@@ -1,63 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -108,6 +108,7 @@ _metadata:
|
|||||||
#define CONTENT_TYPE_KLD 9
|
#define CONTENT_TYPE_KLD 9
|
||||||
#define CONTENT_TYPE_KRN 10
|
#define CONTENT_TYPE_KRN 10
|
||||||
#define CONTENT_TYPE_EXF 11
|
#define CONTENT_TYPE_EXF 11
|
||||||
|
#define CONTENT_TYPE_TKG 12
|
||||||
|
|
||||||
#define CONTENT_FLAG_NONE (0 << 0)
|
#define CONTENT_FLAG_NONE (0 << 0)
|
||||||
|
|
||||||
@@ -213,39 +214,6 @@ _content_headers:
|
|||||||
.asciz "rebootstub"
|
.asciz "rebootstub"
|
||||||
.align 5
|
.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 */
|
/* sm content header */
|
||||||
.word __sm_kip_start__
|
.word __sm_kip_start__
|
||||||
.word __sm_kip_size__
|
.word __sm_kip_size__
|
||||||
@@ -301,6 +269,17 @@ _content_headers:
|
|||||||
.asciz "exosphere_fatal"
|
.asciz "exosphere_fatal"
|
||||||
.align 5
|
.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:
|
_content_headers_end:
|
||||||
|
|
||||||
/* No need to include this in normal programs: */
|
/* No need to include this in normal programs: */
|
||||||
|
|||||||
@@ -14,15 +14,16 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tsec.h"
|
#include "tsec.h"
|
||||||
#include "di.h"
|
#include "di.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
|
#include "mc.h"
|
||||||
|
|
||||||
static int tsec_dma_wait_idle()
|
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);
|
uint32_t timeout = (get_time_ms() + 10000);
|
||||||
|
|
||||||
while (!(tsec->TSEC_FALCON_DMATRFCMD & 2))
|
while (!(tsec->TSEC_FALCON_DMATRFCMD & 2))
|
||||||
@@ -30,13 +31,13 @@ static int tsec_dma_wait_idle()
|
|||||||
if (get_time_ms() > timeout)
|
if (get_time_ms() > timeout)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsec_dma_phys_to_flcn(bool is_imem, uint32_t flcn_offset, uint32_t phys_offset)
|
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;
|
uint32_t cmd = 0;
|
||||||
|
|
||||||
if (!is_imem)
|
if (!is_imem)
|
||||||
@@ -52,16 +53,16 @@ static int tsec_dma_phys_to_flcn(bool is_imem, uint32_t flcn_offset, uint32_t ph
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int tsec_kfuse_wait_ready()
|
static int tsec_kfuse_wait_ready()
|
||||||
{
|
{
|
||||||
uint32_t timeout = (get_time_ms() + 10000);
|
uint32_t timeout = (get_time_ms() + 10000);
|
||||||
|
|
||||||
/* Wait for STATE_DONE. */
|
/* Wait for STATE_DONE. */
|
||||||
while (!(KFUSE_STATE & 0x10000))
|
while (!(KFUSE_STATE & 0x10000))
|
||||||
{
|
{
|
||||||
if (get_time_ms() > timeout)
|
if (get_time_ms() > timeout)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for STATE_CRCPASS. */
|
/* Check for STATE_CRCPASS. */
|
||||||
if (!(KFUSE_STATE & 0x20000))
|
if (!(KFUSE_STATE & 0x20000))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -91,19 +92,19 @@ void tsec_disable_clkrst()
|
|||||||
clkrst_disable(CARDEVICE_HOST1X);
|
clkrst_disable(CARDEVICE_HOST1X);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tsec_get_key(uint8_t *key, uint32_t rev, const void *tsec_fw, size_t tsec_fw_size)
|
static int tsec_run_fw_impl(const void *tsec_fw, size_t tsec_fw_size)
|
||||||
{
|
{
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
||||||
|
|
||||||
/* Enable clocks. */
|
/* Enable clocks. */
|
||||||
tsec_enable_clkrst();
|
tsec_enable_clkrst();
|
||||||
|
|
||||||
/* Make sure KFUSE is ready. */
|
/* Make sure KFUSE is ready. */
|
||||||
if (!tsec_kfuse_wait_ready())
|
if (!tsec_kfuse_wait_ready())
|
||||||
{
|
{
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,16 +113,16 @@ int tsec_get_key(uint8_t *key, uint32_t rev, const void *tsec_fw, size_t tsec_fw
|
|||||||
tsec->TSEC_FALCON_IRQMSET = 0xFFF2;
|
tsec->TSEC_FALCON_IRQMSET = 0xFFF2;
|
||||||
tsec->TSEC_FALCON_IRQDEST = 0xFFF0;
|
tsec->TSEC_FALCON_IRQDEST = 0xFFF0;
|
||||||
tsec->TSEC_FALCON_ITFEN = 3;
|
tsec->TSEC_FALCON_ITFEN = 3;
|
||||||
|
|
||||||
/* Make sure the DMA block is idle. */
|
/* Make sure the DMA block is idle. */
|
||||||
if (!tsec_dma_wait_idle())
|
if (!tsec_dma_wait_idle())
|
||||||
{
|
{
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load firmware. */
|
/* Load firmware. */
|
||||||
tsec->TSEC_FALCON_DMATRFBASE = (uint32_t)tsec_fw >> 8;
|
tsec->TSEC_FALCON_DMATRFBASE = (uint32_t)tsec_fw >> 8;
|
||||||
for (uint32_t addr = 0; addr < tsec_fw_size; addr += 0x100)
|
for (uint32_t addr = 0; addr < tsec_fw_size; addr += 0x100)
|
||||||
@@ -130,128 +131,71 @@ int tsec_get_key(uint8_t *key, uint32_t rev, const void *tsec_fw, size_t tsec_fw
|
|||||||
{
|
{
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write magic value to HOST1X scratch register. */
|
/* Write magic value to HOST1X scratch register. */
|
||||||
MAKE_HOST1X_REG(0x3300) = 0x34C2E1DA;
|
MAKE_HOST1X_REG(0x3300) = 0x34C2E1DA;
|
||||||
|
|
||||||
/* Execute firmware. */
|
/* Execute firmware. */
|
||||||
tsec->TSEC_FALCON_MAILBOX1 = 0;
|
tsec->TSEC_FALCON_MAILBOX1 = 0;
|
||||||
tsec->TSEC_FALCON_MAILBOX0 = rev;
|
tsec->TSEC_FALCON_MAILBOX0 = 1;
|
||||||
tsec->TSEC_FALCON_BOOTVEC = 0;
|
tsec->TSEC_FALCON_BOOTVEC = 0;
|
||||||
tsec->TSEC_FALCON_CPUCTL = 2;
|
tsec->TSEC_FALCON_CPUCTL = 2;
|
||||||
|
|
||||||
/* Make sure the DMA block is idle. */
|
/* Make sure the DMA block is idle. */
|
||||||
if (!tsec_dma_wait_idle())
|
if (!tsec_dma_wait_idle())
|
||||||
{
|
{
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t timeout = (get_time_ms() + 2000);
|
uint32_t timeout = (get_time_ms() + 4000);
|
||||||
while (!tsec->TSEC_FALCON_MAILBOX1)
|
while (!(tsec->TSEC_FALCON_CPUCTL & 0x10)) {
|
||||||
{
|
if (get_time_ms() > timeout) {
|
||||||
if (get_time_ms() > timeout)
|
|
||||||
{
|
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsec->TSEC_FALCON_MAILBOX1 != 0xB0B0B0B0)
|
if (tsec->TSEC_FALCON_MAILBOX1 != 0xB0B0B0B0)
|
||||||
{
|
{
|
||||||
/* Disable clocks. */
|
/* Disable clocks. */
|
||||||
tsec_disable_clkrst();
|
tsec_disable_clkrst();
|
||||||
|
|
||||||
return -6;
|
return -6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear magic value from HOST1X scratch register. */
|
/* Clear magic value from HOST1X scratch register. */
|
||||||
MAKE_HOST1X_REG(0x3300) = 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tsec_load_fw(const void *tsec_fw, size_t tsec_fw_size)
|
int tsec_run_fw(const void *tsec_fw, size_t tsec_fw_size) {
|
||||||
{
|
/* Ensure that the ahb redirect is enabled. */
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
mc_enable_ahb_redirect();
|
||||||
|
|
||||||
/* Enable clocks. */
|
/* Get bom/tom */
|
||||||
tsec_enable_clkrst();
|
uint32_t bom = MAKE_MC_REG(MC_IRAM_BOM);
|
||||||
|
uint32_t tom = MAKE_MC_REG(MC_IRAM_TOM);
|
||||||
/* Make sure KFUSE is ready. */
|
|
||||||
if (!tsec_kfuse_wait_ready())
|
|
||||||
{
|
|
||||||
/* Disable clocks. */
|
|
||||||
tsec_disable_clkrst();
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure Falcon. */
|
/* Override the ahb redirect extents. */
|
||||||
tsec->TSEC_FALCON_DMACTL = 0;
|
MAKE_MC_REG(MC_IRAM_BOM) = 0x40000000;
|
||||||
tsec->TSEC_FALCON_IRQMSET = 0xFFF2;
|
MAKE_MC_REG(MC_IRAM_TOM) = 0x80000000;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
/* Run the fw. */
|
||||||
}
|
int res = tsec_run_fw_impl(tsec_fw, tsec_fw_size);
|
||||||
|
|
||||||
void tsec_run_fw()
|
/* Reset the ahb redirect extents. */
|
||||||
{
|
MAKE_MC_REG(MC_IRAM_BOM) = bom;
|
||||||
volatile tegra_tsec_t *tsec = tsec_get_regs();
|
MAKE_MC_REG(MC_IRAM_TOM) = tom;
|
||||||
|
|
||||||
/* Write magic value to HOST1X scratch register. */
|
return res;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_TSEC_H_
|
#ifndef FUSEE_TSEC_H_
|
||||||
#define FUSEE_TSEC_H_
|
#define FUSEE_TSEC_H_
|
||||||
|
|
||||||
@@ -306,8 +306,7 @@ static inline volatile tegra_tsec_t *tsec_get_regs(void)
|
|||||||
|
|
||||||
void tsec_enable_clkrst();
|
void tsec_enable_clkrst();
|
||||||
void tsec_disable_clkrst();
|
void tsec_disable_clkrst();
|
||||||
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);
|
int tsec_run_fw(const void *tsec_fw, size_t tsec_fw_size);
|
||||||
void tsec_run_fw();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -34,7 +34,6 @@
|
|||||||
#define u8 uint8_t
|
#define u8 uint8_t
|
||||||
#define u32 uint32_t
|
#define u32 uint32_t
|
||||||
#include "fusee_primary_bin.h"
|
#include "fusee_primary_bin.h"
|
||||||
#include "sept_primary_bin.h"
|
|
||||||
#include "rebootstub_bin.h"
|
#include "rebootstub_bin.h"
|
||||||
#undef u8
|
#undef u8
|
||||||
#undef u32
|
#undef u32
|
||||||
@@ -131,42 +130,8 @@ __attribute__((noreturn)) void reboot_to_fusee_primary(void) {
|
|||||||
reboot_to_payload();
|
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) {
|
__attribute__((noreturn)) void reboot_to_iram_payload(void *payload, size_t payload_size) {
|
||||||
/* Copy sept into IRAM low. */
|
/* Copy payload into IRAM low. */
|
||||||
for (size_t i = 0; i < payload_size; i += sizeof(uint32_t)) {
|
for (size_t i = 0; i < payload_size; i += sizeof(uint32_t)) {
|
||||||
write32le((void *)0x40010000, i, read32le(payload, i));
|
write32le((void *)0x40010000, i, read32le(payload, i));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_UTILS_H
|
#ifndef FUSEE_UTILS_H
|
||||||
#define FUSEE_UTILS_H
|
#define FUSEE_UTILS_H
|
||||||
|
|
||||||
@@ -121,7 +121,6 @@ static inline bool check_32bit_address_range_in_program(uintptr_t addr, size_t s
|
|||||||
__attribute__((noreturn)) void watchdog_reboot(void);
|
__attribute__((noreturn)) void watchdog_reboot(void);
|
||||||
__attribute__((noreturn)) void pmc_reboot(uint32_t scratch0);
|
__attribute__((noreturn)) void pmc_reboot(uint32_t scratch0);
|
||||||
__attribute__((noreturn)) void reboot_to_fusee_primary(void);
|
__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 reboot_to_iram_payload(void *payload, size_t payload_size);
|
||||||
__attribute__((noreturn)) void wait_for_button_and_reboot(void);
|
__attribute__((noreturn)) void wait_for_button_and_reboot(void);
|
||||||
void wait_for_button(void);
|
void wait_for_button(void);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||||
branch = master
|
branch = master
|
||||||
commit = b5b55f60d8567ea4608163abc299e5e238381d44
|
commit = 87a1de0b1d489c25a85e187a5bf059f6872465d1
|
||||||
parent = 7e05e12b833e19333ffac02e4fec72250c8b17fa
|
parent = 9296a563036ef20664a2752c03a9695597d4c2b4
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ endif
|
|||||||
ATMOSPHERE_BUILD_SETTINGS ?=
|
ATMOSPHERE_BUILD_SETTINGS ?=
|
||||||
|
|
||||||
export ATMOSPHERE_DEFINES := -DATMOSPHERE
|
export ATMOSPHERE_DEFINES := -DATMOSPHERE
|
||||||
export ATMOSPHERE_SETTINGS := -fPIE -g $(ATMOSPHERE_BUILD_SETTINGS)
|
export ATMOSPHERE_SETTINGS := -fPIE -g -gdwarf-4 $(ATMOSPHERE_BUILD_SETTINGS)
|
||||||
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
|
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
|
||||||
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
|
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
|
||||||
-Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation
|
-Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
|
|||||||
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
|
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
|
||||||
endif
|
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 $(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 -gdwarf-4 $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
|
||||||
|
|
||||||
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
||||||
-Wl,--wrap,__cxa_throw \
|
-Wl,--wrap,__cxa_throw \
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
|||||||
export CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
|
export CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
|
||||||
export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
||||||
|
|
||||||
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 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 CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
||||||
-Wl,--wrap,__cxa_throw \
|
-Wl,--wrap,__cxa_throw \
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ clean-$(strip $1):
|
|||||||
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(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
|
@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
|
endef
|
||||||
|
|
||||||
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
|
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
|
||||||
@@ -117,7 +119,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_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)))
|
ALL_GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(foreach id,$(ALL_GCH_IDENTIFIERS),$(hdr)/$(id)))
|
||||||
|
|
||||||
.PHONY: clean all $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
|
.PHONY: clean all
|
||||||
|
|
||||||
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
|
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ clean-$(strip $1):
|
|||||||
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(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
|
@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
|
endef
|
||||||
|
|
||||||
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
|
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
|
||||||
@@ -117,7 +119,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_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)))
|
ALL_GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(foreach id,$(ALL_GCH_IDENTIFIERS),$(hdr)/$(id)))
|
||||||
|
|
||||||
.PHONY: clean all $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
|
.PHONY: clean all
|
||||||
|
|
||||||
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
|
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
|||||||
@@ -20,17 +20,18 @@ namespace ams::pkg1 {
|
|||||||
|
|
||||||
enum KeyGeneration : int {
|
enum KeyGeneration : int {
|
||||||
|
|
||||||
KeyGeneration_1_0_0 = 0x00,
|
KeyGeneration_1_0_0 = 0x00,
|
||||||
KeyGeneration_3_0_0 = 0x01,
|
KeyGeneration_3_0_0 = 0x01,
|
||||||
KeyGeneration_3_0_1 = 0x02,
|
KeyGeneration_3_0_1 = 0x02,
|
||||||
KeyGeneration_4_0_0 = 0x03,
|
KeyGeneration_4_0_0 = 0x03,
|
||||||
KeyGeneration_5_0_0 = 0x04,
|
KeyGeneration_5_0_0 = 0x04,
|
||||||
KeyGeneration_6_0_0 = 0x05,
|
KeyGeneration_6_0_0 = 0x05,
|
||||||
KeyGeneration_6_2_0 = 0x06,
|
KeyGeneration_6_2_0 = 0x06,
|
||||||
KeyGeneration_7_0_0 = 0x07,
|
KeyGeneration_7_0_0 = 0x07,
|
||||||
KeyGeneration_8_1_0 = 0x08,
|
KeyGeneration_8_1_0 = 0x08,
|
||||||
KeyGeneration_9_0_0 = 0x09,
|
KeyGeneration_9_0_0 = 0x09,
|
||||||
KeyGeneration_9_1_0 = 0x0A,
|
KeyGeneration_9_1_0 = 0x0A,
|
||||||
|
KeyGeneration_12_1_0 = 0x0B,
|
||||||
|
|
||||||
KeyGeneration_Count,
|
KeyGeneration_Count,
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace ams::pkg2 {
|
|||||||
|
|
||||||
constexpr inline int PayloadCount = 3;
|
constexpr inline int PayloadCount = 3;
|
||||||
|
|
||||||
constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x11 in Nintendo's code. */
|
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 CurrentBootloaderVersion = 0xF;
|
||||||
|
|
||||||
struct Package2Meta {
|
struct Package2Meta {
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ clean-$(strip $1):
|
|||||||
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(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
|
@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
|
endef
|
||||||
|
|
||||||
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
|
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
|
||||||
@@ -109,7 +111,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_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)))
|
ALL_GCH_FILES := $(foreach hdr,$(PRECOMPILED_HEADERS:.hpp=.hpp.gch),$(foreach id,$(ALL_GCH_IDENTIFIERS),$(hdr)/$(id)))
|
||||||
|
|
||||||
.PHONY: clean all $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),$(config) clean-$(config))
|
.PHONY: clean all
|
||||||
|
|
||||||
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
|
$(ATMOSPHERE_LIBRARY_DIR) $(GCH_DIRS):
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::kern::init {
|
namespace ams::kern::init {
|
||||||
|
|
||||||
struct KInitArguments {
|
struct alignas(util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE)) KInitArguments {
|
||||||
u64 ttbr0;
|
u64 ttbr0;
|
||||||
u64 ttbr1;
|
u64 ttbr1;
|
||||||
u64 tcr;
|
u64 tcr;
|
||||||
@@ -32,7 +32,8 @@ namespace ams::kern::init {
|
|||||||
u64 setup_function;
|
u64 setup_function;
|
||||||
u64 exception_stack;
|
u64 exception_stack;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(KInitArguments) == INIT_ARGUMENTS_SIZE);
|
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, ttbr0) == INIT_ARGUMENTS_TTBR0);
|
||||||
static_assert(__builtin_offsetof(KInitArguments, ttbr1) == INIT_ARGUMENTS_TTBR1);
|
static_assert(__builtin_offsetof(KInitArguments, ttbr1) == INIT_ARGUMENTS_TTBR1);
|
||||||
|
|||||||
@@ -172,10 +172,8 @@ namespace ams::kern::arch::arm64::cpu {
|
|||||||
|
|
||||||
/* Cache management helpers. */
|
/* Cache management helpers. */
|
||||||
void ClearPageToZeroImpl(void *);
|
void ClearPageToZeroImpl(void *);
|
||||||
void FlushEntireDataCacheSharedForInit();
|
|
||||||
void FlushEntireDataCacheLocalForInit();
|
|
||||||
void InvalidateEntireInstructionCacheForInit();
|
|
||||||
void StoreEntireCacheForInit();
|
void StoreEntireCacheForInit();
|
||||||
|
void FlushEntireCacheForInit();
|
||||||
|
|
||||||
void FlushEntireDataCache();
|
void FlushEntireDataCache();
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
Result Attach(ams::svc::DeviceName device_name, u64 space_address, u64 space_size);
|
Result Attach(ams::svc::DeviceName device_name, u64 space_address, u64 space_size);
|
||||||
Result Detach(ams::svc::DeviceName device_name);
|
Result Detach(ams::svc::DeviceName device_name);
|
||||||
|
|
||||||
Result Map(size_t *out_mapped_size, KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool refresh_mappings);
|
Result Map(size_t *out_mapped_size, KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool is_aligned, bool refresh_mappings);
|
||||||
Result Unmap(KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address);
|
Result Unmap(KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address);
|
||||||
|
|
||||||
void Unmap(KDeviceVirtualAddress device_address, size_t size) {
|
void Unmap(KDeviceVirtualAddress device_address, size_t size) {
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
namespace ams::kern::init {
|
namespace ams::kern::init {
|
||||||
|
|
||||||
|
static_assert(util::IsPowerOfTwo(alignof(KInitArguments)) && util::IsPowerOfTwo(sizeof(KInitArguments)));
|
||||||
|
|
||||||
KPhysicalAddress GetInitArgumentsAddress(s32 core_id);
|
KPhysicalAddress GetInitArgumentsAddress(s32 core_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,8 +64,11 @@ namespace ams::kern {
|
|||||||
m_page_bitmap.Initialize(management_ptr, m_count);
|
m_page_bitmap.Initialize(management_ptr, m_count);
|
||||||
|
|
||||||
/* Free the pages to the bitmap. */
|
/* Free the pages to the bitmap. */
|
||||||
std::memset(GetPointer<PageBuffer>(m_address), 0, m_count * sizeof(PageBuffer));
|
|
||||||
for (size_t i = 0; i < m_count; i++) {
|
for (size_t i = 0; i < m_count; i++) {
|
||||||
|
/* Ensure the freed page is all-zero. */
|
||||||
|
cpu::ClearPageToZero(GetPointer<PageBuffer>(m_address) + i);
|
||||||
|
|
||||||
|
/* Set the bit for the free page. */
|
||||||
m_page_bitmap.SetBit(i);
|
m_page_bitmap.SetBit(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,6 +102,9 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Free(PageBuffer *pb) {
|
void Free(PageBuffer *pb) {
|
||||||
|
/* Ensure all pages in the heap are zero. */
|
||||||
|
cpu::ClearPageToZero(pb);
|
||||||
|
|
||||||
/* Take the lock. */
|
/* Take the lock. */
|
||||||
KScopedInterruptDisable di;
|
KScopedInterruptDisable di;
|
||||||
KScopedSpinLock lk(m_lock);
|
KScopedSpinLock lk(m_lock);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
namespace ams::kern {
|
namespace ams::kern {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, bool ClearNode = false>
|
||||||
class KDynamicSlabHeap {
|
class KDynamicSlabHeap {
|
||||||
NON_COPYABLE(KDynamicSlabHeap);
|
NON_COPYABLE(KDynamicSlabHeap);
|
||||||
NON_MOVEABLE(KDynamicSlabHeap);
|
NON_MOVEABLE(KDynamicSlabHeap);
|
||||||
@@ -97,6 +97,13 @@ namespace ams::kern {
|
|||||||
T *Allocate() {
|
T *Allocate() {
|
||||||
T *allocated = reinterpret_cast<T *>(this->GetImpl()->Allocate());
|
T *allocated = reinterpret_cast<T *>(this->GetImpl()->Allocate());
|
||||||
|
|
||||||
|
/* If we successfully allocated and we should clear the node, do so. */
|
||||||
|
if constexpr (ClearNode) {
|
||||||
|
if (AMS_LIKELY(allocated != nullptr)) {
|
||||||
|
reinterpret_cast<Impl::Node *>(allocated)->next = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If we fail to allocate, try to get a new page from our next allocator. */
|
/* If we fail to allocate, try to get a new page from our next allocator. */
|
||||||
if (AMS_UNLIKELY(allocated == nullptr)) {
|
if (AMS_UNLIKELY(allocated == nullptr)) {
|
||||||
if (m_page_allocator != nullptr) {
|
if (m_page_allocator != nullptr) {
|
||||||
|
|||||||
@@ -107,8 +107,11 @@ namespace ams::kern {
|
|||||||
Node *Peek() const { return m_root; }
|
Node *Peek() const { return m_root; }
|
||||||
|
|
||||||
Node *Pop() {
|
Node *Pop() {
|
||||||
Node *r = m_root;
|
Node * const r = m_root;
|
||||||
m_root = m_root->m_next;
|
|
||||||
|
m_root = r->m_next;
|
||||||
|
r->m_next = nullptr;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,18 +25,20 @@ namespace ams::kern {
|
|||||||
class PageTablePage {
|
class PageTablePage {
|
||||||
private:
|
private:
|
||||||
u8 m_buffer[PageSize];
|
u8 m_buffer[PageSize];
|
||||||
|
public:
|
||||||
|
ALWAYS_INLINE PageTablePage() { /* Do not initialize anything. */ }
|
||||||
};
|
};
|
||||||
static_assert(sizeof(PageTablePage) == PageSize);
|
static_assert(sizeof(PageTablePage) == PageSize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class KPageTableManager : public KDynamicSlabHeap<impl::PageTablePage> {
|
class KPageTableManager : public KDynamicSlabHeap<impl::PageTablePage, true> {
|
||||||
public:
|
public:
|
||||||
using RefCount = u16;
|
using RefCount = u16;
|
||||||
static constexpr size_t PageTableSize = sizeof(impl::PageTablePage);
|
static constexpr size_t PageTableSize = sizeof(impl::PageTablePage);
|
||||||
static_assert(PageTableSize == PageSize);
|
static_assert(PageTableSize == PageSize);
|
||||||
private:
|
private:
|
||||||
using BaseHeap = KDynamicSlabHeap<impl::PageTablePage>;
|
using BaseHeap = KDynamicSlabHeap<impl::PageTablePage, true>;
|
||||||
private:
|
private:
|
||||||
RefCount *m_ref_counts;
|
RefCount *m_ref_counts;
|
||||||
public:
|
public:
|
||||||
@@ -72,9 +74,6 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Free(KVirtualAddress addr) {
|
void Free(KVirtualAddress addr) {
|
||||||
/* Ensure all pages in the heap are zero. */
|
|
||||||
cpu::ClearPageToZero(GetVoidPointer(addr));
|
|
||||||
|
|
||||||
/* Free the page. */
|
/* Free the page. */
|
||||||
BaseHeap::Free(GetPointer<impl::PageTablePage>(addr));
|
BaseHeap::Free(GetPointer<impl::PageTablePage>(addr));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,27 +262,6 @@ namespace ams::kern::arch::arm64::cpu {
|
|||||||
__asm__ __volatile__("dc csw, %[v]" :: [v]"r"(sw_value) : "memory");
|
__asm__ __volatile__("dc csw, %[v]" :: [v]"r"(sw_value) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool Init, typename F>
|
|
||||||
ALWAYS_INLINE void PerformCacheOperationBySetWayShared(F f) {
|
|
||||||
CacheLineIdRegisterAccessor clidr_el1;
|
|
||||||
const int levels_of_coherency = clidr_el1.GetLevelsOfCoherency();
|
|
||||||
const int levels_of_unification = clidr_el1.GetLevelsOfUnification();
|
|
||||||
|
|
||||||
for (int level = levels_of_coherency; level >= levels_of_unification; level--) {
|
|
||||||
PerformCacheOperationBySetWayImpl<Init>(level, f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool Init, typename F>
|
|
||||||
ALWAYS_INLINE void PerformCacheOperationBySetWayLocal(F f) {
|
|
||||||
CacheLineIdRegisterAccessor clidr_el1;
|
|
||||||
const int levels_of_unification = clidr_el1.GetLevelsOfUnification();
|
|
||||||
|
|
||||||
for (int level = levels_of_unification - 1; level >= 0; level--) {
|
|
||||||
PerformCacheOperationBySetWayImpl<Init>(level, f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StoreDataCacheBySetWay(int level) {
|
void StoreDataCacheBySetWay(int level) {
|
||||||
PerformCacheOperationBySetWayImpl<false>(level, StoreDataCacheLineBySetWayImpl);
|
PerformCacheOperationBySetWayImpl<false>(level, StoreDataCacheLineBySetWayImpl);
|
||||||
cpu::DataSynchronizationBarrier();
|
cpu::DataSynchronizationBarrier();
|
||||||
@@ -361,24 +340,63 @@ namespace ams::kern::arch::arm64::cpu {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlushEntireDataCacheSharedForInit() {
|
void StoreEntireCacheForInit() {
|
||||||
return PerformCacheOperationBySetWayShared<true>(FlushDataCacheLineBySetWayImpl);
|
/* Store local. */
|
||||||
|
{
|
||||||
|
CacheLineIdRegisterAccessor clidr_el1;
|
||||||
|
const int levels_of_unification = clidr_el1.GetLevelsOfUnification();
|
||||||
|
|
||||||
|
for (int level = 0; level != levels_of_unification; ++level) {
|
||||||
|
PerformCacheOperationBySetWayImpl<true>(level, StoreDataCacheLineBySetWayImpl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store shared. */
|
||||||
|
{
|
||||||
|
CacheLineIdRegisterAccessor clidr_el1;
|
||||||
|
const int levels_of_coherency = clidr_el1.GetLevelsOfCoherency();
|
||||||
|
const int levels_of_unification = clidr_el1.GetLevelsOfUnification();
|
||||||
|
|
||||||
|
for (int level = levels_of_unification; level <= levels_of_coherency; ++level) {
|
||||||
|
PerformCacheOperationBySetWayImpl<true>(level, StoreDataCacheLineBySetWayImpl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Data synchronization barrier. */
|
||||||
|
DataSynchronizationBarrierInnerShareable();
|
||||||
|
|
||||||
|
/* Invalidate instruction cache. */
|
||||||
|
InvalidateEntireInstructionCacheLocalImpl();
|
||||||
|
|
||||||
|
/* Ensure local instruction consistency. */
|
||||||
|
DataSynchronizationBarrierInnerShareable();
|
||||||
|
InstructionMemoryBarrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlushEntireDataCacheLocalForInit() {
|
void FlushEntireCacheForInit() {
|
||||||
return PerformCacheOperationBySetWayLocal<true>(FlushDataCacheLineBySetWayImpl);
|
/* Flush data cache. */
|
||||||
}
|
{
|
||||||
|
/* Get levels of coherence/unificaiton. */
|
||||||
|
CacheLineIdRegisterAccessor clidr_el1;
|
||||||
|
const int levels_of_coherency = clidr_el1.GetLevelsOfCoherency();
|
||||||
|
|
||||||
void InvalidateEntireInstructionCacheForInit() {
|
/* Store cache from L1 up to (level of coherence - 1). */
|
||||||
|
for (int level = 0; level < levels_of_coherency - 1; ++level) {
|
||||||
|
PerformCacheOperationBySetWayImpl<true>(level, StoreDataCacheLineBySetWayImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flush cache from (level of coherence - 1) down to L0. */
|
||||||
|
for (int level = levels_of_coherency; level > 0; --level) {
|
||||||
|
PerformCacheOperationBySetWayImpl<true>(level - 1, FlushDataCacheLineBySetWayImpl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Invalidate instruction cache. */
|
||||||
InvalidateEntireInstructionCacheLocalImpl();
|
InvalidateEntireInstructionCacheLocalImpl();
|
||||||
EnsureInstructionConsistency();
|
EnsureInstructionConsistency();
|
||||||
}
|
|
||||||
|
|
||||||
void StoreEntireCacheForInit() {
|
/* Invalidate entire TLB. */
|
||||||
PerformCacheOperationBySetWayLocal<true>(StoreDataCacheLineBySetWayImpl);
|
InvalidateEntireTlb();
|
||||||
PerformCacheOperationBySetWayShared<true>(StoreDataCacheLineBySetWayImpl);
|
|
||||||
DataSynchronizationBarrierInnerShareable();
|
|
||||||
InvalidateEntireInstructionCacheForInit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlushEntireDataCache() {
|
void FlushEntireDataCache() {
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
{
|
{
|
||||||
exception = ams::svc::DebugException_BreakPoint;
|
exception = ams::svc::DebugException_BreakPoint;
|
||||||
param2 = far;
|
param2 = far;
|
||||||
param3 = ams::svc::BreakPointType_HardwareInstruction;
|
param3 = ams::svc::BreakPointType_HardwareData;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EsrEc_SErrorInterrupt:
|
case EsrEc_SErrorInterrupt:
|
||||||
@@ -293,6 +293,13 @@ namespace ams::kern::arch::arm64 {
|
|||||||
/* Print that an exception occurred. */
|
/* Print that an exception occurred. */
|
||||||
MESOSPHERE_RELEASE_LOG("Exception occurred. %016lx\n", GetCurrentProcess().GetProgramId());
|
MESOSPHERE_RELEASE_LOG("Exception occurred. %016lx\n", GetCurrentProcess().GetProgramId());
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Print the current thread's registers. */
|
||||||
|
KDebug::PrintRegister();
|
||||||
|
|
||||||
|
/* Print a backtrace. */
|
||||||
|
KDebug::PrintBacktrace();
|
||||||
|
}
|
||||||
|
|
||||||
/* If the SVC is handled, handle it. */
|
/* If the SVC is handled, handle it. */
|
||||||
if (!svc::ResultNotHandled::Includes(result)) {
|
if (!svc::ResultNotHandled::Includes(result)) {
|
||||||
|
|||||||
@@ -74,26 +74,32 @@ namespace ams::kern::arch::arm64 {
|
|||||||
/* Get the exception context. */
|
/* Get the exception context. */
|
||||||
const KExceptionContext *e_ctx = GetExceptionContext(thread);
|
const KExceptionContext *e_ctx = GetExceptionContext(thread);
|
||||||
|
|
||||||
|
/* Get whether we're 64-bit. */
|
||||||
|
const bool is_64_bit = this->Is64Bit();
|
||||||
|
|
||||||
/* If general registers are requested, get them. */
|
/* If general registers are requested, get them. */
|
||||||
if ((context_flags & ams::svc::ThreadContextFlag_General) != 0) {
|
if ((context_flags & ams::svc::ThreadContextFlag_General) != 0) {
|
||||||
|
/* We can always get X0-X7/R0-R7. */
|
||||||
|
auto register_count = 8;
|
||||||
if (!thread->IsCallingSvc() || thread->GetSvcId() == svc::SvcId_ReturnFromException) {
|
if (!thread->IsCallingSvc() || thread->GetSvcId() == svc::SvcId_ReturnFromException) {
|
||||||
if (this->Is64Bit()) {
|
if (is_64_bit) {
|
||||||
/* Get X0-X28. */
|
/* We're not in an SVC, so we can get X0-X29. */
|
||||||
for (auto i = 0; i <= 28; ++i) {
|
register_count = 29;
|
||||||
out->r[i] = e_ctx->x[i];
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* Get R0-R12. */
|
/* We're 32-bit, so we should get R0-R12. */
|
||||||
for (auto i = 0; i <= 12; ++i) {
|
register_count = 13;
|
||||||
out->r[i] = static_cast<u32>(e_ctx->x[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the registers. */
|
||||||
|
for (auto i = 0; i < register_count; ++i) {
|
||||||
|
out->r[i] = is_64_bit ? e_ctx->x[i] : static_cast<u32>(e_ctx->x[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If control flags are requested, get them. */
|
/* If control flags are requested, get them. */
|
||||||
if ((context_flags & ams::svc::ThreadContextFlag_Control) != 0) {
|
if ((context_flags & ams::svc::ThreadContextFlag_Control) != 0) {
|
||||||
if (this->Is64Bit()) {
|
if (is_64_bit) {
|
||||||
out->fp = e_ctx->x[29];
|
out->fp = e_ctx->x[29];
|
||||||
out->lr = e_ctx->x[30];
|
out->lr = e_ctx->x[30];
|
||||||
out->sp = e_ctx->sp;
|
out->sp = e_ctx->sp;
|
||||||
@@ -291,7 +297,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
/* If the breakpoint matches context id, we need to get the context id. */
|
/* If the breakpoint matches context id, we need to get the context id. */
|
||||||
if ((flags & (1ul << 21)) != 0) {
|
if ((flags & (1ul << 21)) != 0) {
|
||||||
/* Ensure that the breakpoint is context-aware. */
|
/* Ensure that the breakpoint is context-aware. */
|
||||||
R_UNLESS((name - ams::svc::HardwareBreakPointRegisterName_I0) <= (num_bp - num_ctx), svc::ResultNotSupported());
|
R_UNLESS((name - ams::svc::HardwareBreakPointRegisterName_I0) >= (num_bp - num_ctx), svc::ResultNotSupported());
|
||||||
|
|
||||||
/* Check that the breakpoint does not have the mismatch bit. */
|
/* Check that the breakpoint does not have the mismatch bit. */
|
||||||
R_UNLESS((flags & (1ul << 22)) == 0, svc::ResultInvalidCombination());
|
R_UNLESS((flags & (1ul << 22)) == 0, svc::ResultInvalidCombination());
|
||||||
|
|||||||
@@ -279,9 +279,10 @@ namespace ams::kern::arch::arm64 {
|
|||||||
if (l1_entry->IsTable()) {
|
if (l1_entry->IsTable()) {
|
||||||
L2PageTableEntry *l2_entry = impl.GetL2Entry(l1_entry, cur_address);
|
L2PageTableEntry *l2_entry = impl.GetL2Entry(l1_entry, cur_address);
|
||||||
if (l2_entry->IsTable()) {
|
if (l2_entry->IsTable()) {
|
||||||
KVirtualAddress l3_table = GetPageTableVirtualAddress(l2_entry->GetTable());
|
const KVirtualAddress l3_table = GetPageTableVirtualAddress(l2_entry->GetTable());
|
||||||
if (this->GetPageTableManager().IsInPageTableHeap(l3_table)) {
|
if (this->GetPageTableManager().IsInPageTableHeap(l3_table)) {
|
||||||
while (!this->GetPageTableManager().Close(l3_table, 1)) { /* ... */ }
|
while (!this->GetPageTableManager().Close(l3_table, 1)) { /* ... */ }
|
||||||
|
ClearPageTable(l3_table);
|
||||||
this->GetPageTableManager().Free(l3_table);
|
this->GetPageTableManager().Free(l3_table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,16 +293,21 @@ namespace ams::kern::arch::arm64 {
|
|||||||
for (KProcessAddress cur_address = as_start; cur_address <= as_last; cur_address += L1BlockSize) {
|
for (KProcessAddress cur_address = as_start; cur_address <= as_last; cur_address += L1BlockSize) {
|
||||||
L1PageTableEntry *l1_entry = impl.GetL1Entry(cur_address);
|
L1PageTableEntry *l1_entry = impl.GetL1Entry(cur_address);
|
||||||
if (l1_entry->IsTable()) {
|
if (l1_entry->IsTable()) {
|
||||||
KVirtualAddress l2_table = GetPageTableVirtualAddress(l1_entry->GetTable());
|
const KVirtualAddress l2_table = GetPageTableVirtualAddress(l1_entry->GetTable());
|
||||||
if (this->GetPageTableManager().IsInPageTableHeap(l2_table)) {
|
if (this->GetPageTableManager().IsInPageTableHeap(l2_table)) {
|
||||||
while (!this->GetPageTableManager().Close(l2_table, 1)) { /* ... */ }
|
while (!this->GetPageTableManager().Close(l2_table, 1)) { /* ... */ }
|
||||||
|
ClearPageTable(l2_table);
|
||||||
this->GetPageTableManager().Free(l2_table);
|
this->GetPageTableManager().Free(l2_table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the L1 table. */
|
/* Free the L1 table. */
|
||||||
this->GetPageTableManager().Free(reinterpret_cast<uintptr_t>(impl.Finalize()));
|
{
|
||||||
|
const KVirtualAddress l1_table = reinterpret_cast<uintptr_t>(impl.Finalize());
|
||||||
|
ClearPageTable(l1_table);
|
||||||
|
this->GetPageTableManager().Free(l1_table);
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform inherited finalization. */
|
/* Perform inherited finalization. */
|
||||||
KPageTableBase::Finalize();
|
KPageTableBase::Finalize();
|
||||||
|
|||||||
@@ -1437,13 +1437,13 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KDevicePageTable::Map(size_t *out_mapped_size, KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool refresh_mappings) {
|
Result KDevicePageTable::Map(size_t *out_mapped_size, KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool is_aligned, bool refresh_mappings) {
|
||||||
/* Clear the output size. */
|
/* Clear the output size. */
|
||||||
*out_mapped_size = 0;
|
*out_mapped_size = 0;
|
||||||
|
|
||||||
/* Map the pages. */
|
/* Map the pages. */
|
||||||
s32 num_pt = 0;
|
s32 num_pt = 0;
|
||||||
return this->MapImpl(out_mapped_size, num_pt, refresh_mappings ? 1 : std::numeric_limits<s32>::max(), page_table, process_address, size, device_address, device_perm, refresh_mappings);
|
return this->MapImpl(out_mapped_size, num_pt, refresh_mappings ? 1 : std::numeric_limits<s32>::max(), page_table, process_address, size, device_address, device_perm, is_aligned);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KDevicePageTable::Unmap(KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address) {
|
Result KDevicePageTable::Unmap(KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address) {
|
||||||
|
|||||||
@@ -55,16 +55,18 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
Package2Hash = 17,
|
Package2Hash = 17,
|
||||||
|
|
||||||
/* Extension config items for exosphere. */
|
/* Extension config items for exosphere. */
|
||||||
ExosphereApiVersion = 65000,
|
ExosphereApiVersion = 65000,
|
||||||
ExosphereNeedsReboot = 65001,
|
ExosphereNeedsReboot = 65001,
|
||||||
ExosphereNeedsShutdown = 65002,
|
ExosphereNeedsShutdown = 65002,
|
||||||
ExosphereGitCommitHash = 65003,
|
ExosphereGitCommitHash = 65003,
|
||||||
ExosphereHasRcmBugPatch = 65004,
|
ExosphereHasRcmBugPatch = 65004,
|
||||||
ExosphereBlankProdInfo = 65005,
|
ExosphereBlankProdInfo = 65005,
|
||||||
ExosphereAllowCalWrites = 65006,
|
ExosphereAllowCalWrites = 65006,
|
||||||
ExosphereEmummcType = 65007,
|
ExosphereEmummcType = 65007,
|
||||||
ExospherePayloadAddress = 65008,
|
ExospherePayloadAddress = 65008,
|
||||||
ExosphereLogConfiguration = 65009,
|
ExosphereLogConfiguration = 65009,
|
||||||
|
ExosphereForceEnableUsb30 = 65010,
|
||||||
|
ExosphereSupportedHosVersion = 65011,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SmcResult {
|
enum class SmcResult {
|
||||||
|
|||||||
@@ -103,54 +103,29 @@ namespace ams::kern {
|
|||||||
auto it = m_tree.nfind_key({ addr, -1 });
|
auto it = m_tree.nfind_key({ addr, -1 });
|
||||||
/* Determine the updated value. */
|
/* Determine the updated value. */
|
||||||
s32 new_value;
|
s32 new_value;
|
||||||
if (GetTargetFirmware() >= TargetFirmware_7_0_0) {
|
if (count <= 0) {
|
||||||
if (count <= 0) {
|
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
||||||
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
new_value = value - 2;
|
||||||
new_value = value - 2;
|
|
||||||
} else {
|
|
||||||
new_value = value + 1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
new_value = value + 1;
|
||||||
auto tmp_it = it;
|
|
||||||
s32 tmp_num_waiters = 0;
|
|
||||||
while ((++tmp_it != m_tree.end()) && (tmp_it->GetAddressArbiterKey() == addr)) {
|
|
||||||
if ((tmp_num_waiters++) >= count) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tmp_num_waiters < count) {
|
|
||||||
new_value = value - 1;
|
|
||||||
} else {
|
|
||||||
new_value = value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
new_value = value + 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (count <= 0) {
|
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
||||||
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
|
|
||||||
new_value = value - 1;
|
|
||||||
} else {
|
|
||||||
new_value = value + 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auto tmp_it = it;
|
auto tmp_it = it;
|
||||||
s32 tmp_num_waiters = 0;
|
s32 tmp_num_waiters = 0;
|
||||||
while ((tmp_it != m_tree.end()) && (tmp_it->GetAddressArbiterKey() == addr) && (tmp_num_waiters < count + 1)) {
|
while ((++tmp_it != m_tree.end()) && (tmp_it->GetAddressArbiterKey() == addr)) {
|
||||||
++tmp_num_waiters;
|
if ((tmp_num_waiters++) >= count) {
|
||||||
++tmp_it;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp_num_waiters == 0) {
|
if (tmp_num_waiters < count) {
|
||||||
new_value = value + 1;
|
|
||||||
} else if (tmp_num_waiters <= count) {
|
|
||||||
new_value = value - 1;
|
new_value = value - 1;
|
||||||
} else {
|
} else {
|
||||||
new_value = value;
|
new_value = value;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
new_value = value + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
can_access = cpu::CanAccessAtomic(address);
|
can_access = cpu::CanAccessAtomic(address);
|
||||||
if (AMS_LIKELY(can_access)) {
|
if (AMS_LIKELY(can_access)) {
|
||||||
UpdateLockAtomic(std::addressof(prev_tag), address, own_tag, ams::svc::HandleWaitMask);
|
can_access = UpdateLockAtomic(std::addressof(prev_tag), address, own_tag, ams::svc::HandleWaitMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -422,8 +422,8 @@ namespace ams::kern {
|
|||||||
for (auto i = 0; i < static_cast<s32>(cpu::NumCores); ++i) {
|
for (auto i = 0; i < static_cast<s32>(cpu::NumCores); ++i) {
|
||||||
if (thread == Kernel::GetScheduler(i).GetSchedulerCurrentThread()) {
|
if (thread == Kernel::GetScheduler(i).GetSchedulerCurrentThread()) {
|
||||||
current = true;
|
current = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the thread is current, retry until it isn't. */
|
/* If the thread is current, retry until it isn't. */
|
||||||
@@ -469,8 +469,8 @@ namespace ams::kern {
|
|||||||
for (auto i = 0; i < static_cast<s32>(cpu::NumCores); ++i) {
|
for (auto i = 0; i < static_cast<s32>(cpu::NumCores); ++i) {
|
||||||
if (thread == Kernel::GetScheduler(i).GetSchedulerCurrentThread()) {
|
if (thread == Kernel::GetScheduler(i).GetSchedulerCurrentThread()) {
|
||||||
current = true;
|
current = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the thread is current, retry until it isn't. */
|
/* If the thread is current, retry until it isn't. */
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ namespace ams::kern {
|
|||||||
auto mapped_size_guard = SCOPE_GUARD { *out_mapped_size = 0; };
|
auto mapped_size_guard = SCOPE_GUARD { *out_mapped_size = 0; };
|
||||||
|
|
||||||
/* Perform the mapping. */
|
/* Perform the mapping. */
|
||||||
R_TRY(m_table.Map(out_mapped_size, page_table, process_address, size, device_address, device_perm, refresh_mappings));
|
R_TRY(m_table.Map(out_mapped_size, page_table, process_address, size, device_address, device_perm, is_aligned, refresh_mappings));
|
||||||
|
|
||||||
/* Ensure that we unmap the pages if we fail to update the protections. */
|
/* Ensure that we unmap the pages if we fail to update the protections. */
|
||||||
/* NOTE: Nintendo does not check the result of this unmap call. */
|
/* NOTE: Nintendo does not check the result of this unmap call. */
|
||||||
@@ -120,7 +120,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* If we fail to unmap, we want to do a partial unlock. */
|
/* If we fail to unmap, we want to do a partial unlock. */
|
||||||
{
|
{
|
||||||
auto unlock_guard = SCOPE_GUARD { page_table->UnlockForDeviceAddressSpacePartialMap(process_address, size, size); };
|
auto unlock_guard = SCOPE_GUARD { MESOSPHERE_R_ABORT_UNLESS(page_table->UnlockForDeviceAddressSpacePartialMap(process_address, size, size)); };
|
||||||
|
|
||||||
/* Unmap. */
|
/* Unmap. */
|
||||||
R_TRY(m_table.Unmap(page_table, process_address, size, device_address));
|
R_TRY(m_table.Unmap(page_table, process_address, size, device_address));
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace ams::kern::KDumpObject {
|
|||||||
|
|
||||||
const auto end = accessor.end();
|
const auto end = accessor.end();
|
||||||
const auto &handle_table = process->GetHandleTable();
|
const auto &handle_table = process->GetHandleTable();
|
||||||
const size_t max_handles = handle_table.GetMaxCount();
|
const size_t max_handles = handle_table.GetTableSize();
|
||||||
for (size_t i = 0; i < max_handles; ++i) {
|
for (size_t i = 0; i < max_handles; ++i) {
|
||||||
/* Get the object + handle. */
|
/* Get the object + handle. */
|
||||||
ams::svc::Handle handle = ams::svc::InvalidHandle;
|
ams::svc::Handle handle = ams::svc::InvalidHandle;
|
||||||
@@ -181,7 +181,7 @@ namespace ams::kern::KDumpObject {
|
|||||||
|
|
||||||
const auto end = accessor.end();
|
const auto end = accessor.end();
|
||||||
const auto &handle_table = process->GetHandleTable();
|
const auto &handle_table = process->GetHandleTable();
|
||||||
const size_t max_handles = handle_table.GetMaxCount();
|
const size_t max_handles = handle_table.GetTableSize();
|
||||||
for (size_t i = 0; i < max_handles; ++i) {
|
for (size_t i = 0; i < max_handles; ++i) {
|
||||||
/* Get the object + handle. */
|
/* Get the object + handle. */
|
||||||
ams::svc::Handle handle = ams::svc::InvalidHandle;
|
ams::svc::Handle handle = ams::svc::InvalidHandle;
|
||||||
@@ -203,7 +203,7 @@ namespace ams::kern::KDumpObject {
|
|||||||
{
|
{
|
||||||
for (auto it = accessor.begin(); it != end && client_port_process.IsNull(); ++it) {
|
for (auto it = accessor.begin(); it != end && client_port_process.IsNull(); ++it) {
|
||||||
KProcess *cur = static_cast<KProcess *>(std::addressof(*it));
|
KProcess *cur = static_cast<KProcess *>(std::addressof(*it));
|
||||||
for (size_t j = 0; j < cur->GetHandleTable().GetMaxCount(); ++j) {
|
for (size_t j = 0; j < cur->GetHandleTable().GetTableSize(); ++j) {
|
||||||
ams::svc::Handle cur_h = ams::svc::InvalidHandle;
|
ams::svc::Handle cur_h = ams::svc::InvalidHandle;
|
||||||
KScopedAutoObject cur_o = cur->GetHandleTable().GetObjectByIndex(std::addressof(cur_h), j);
|
KScopedAutoObject cur_o = cur->GetHandleTable().GetObjectByIndex(std::addressof(cur_h), j);
|
||||||
if (cur_o.IsNotNull()) {
|
if (cur_o.IsNotNull()) {
|
||||||
@@ -236,7 +236,7 @@ namespace ams::kern::KDumpObject {
|
|||||||
{
|
{
|
||||||
for (auto it = accessor.begin(); it != end; ++it) {
|
for (auto it = accessor.begin(); it != end; ++it) {
|
||||||
KProcess *cur = static_cast<KProcess *>(std::addressof(*it));
|
KProcess *cur = static_cast<KProcess *>(std::addressof(*it));
|
||||||
for (size_t j = 0; j < cur->GetHandleTable().GetMaxCount(); ++j) {
|
for (size_t j = 0; j < cur->GetHandleTable().GetTableSize(); ++j) {
|
||||||
ams::svc::Handle cur_h = ams::svc::InvalidHandle;
|
ams::svc::Handle cur_h = ams::svc::InvalidHandle;
|
||||||
KScopedAutoObject cur_o = cur->GetHandleTable().GetObjectByIndex(std::addressof(cur_h), j);
|
KScopedAutoObject cur_o = cur->GetHandleTable().GetObjectByIndex(std::addressof(cur_h), j);
|
||||||
if (cur_o.IsNull()) {
|
if (cur_o.IsNull()) {
|
||||||
|
|||||||
@@ -804,7 +804,7 @@ namespace ams::kern {
|
|||||||
|
|
||||||
/* Remove waiter thread. */
|
/* Remove waiter thread. */
|
||||||
s32 num_waiters;
|
s32 num_waiters;
|
||||||
if (KThread *next = thread->RemoveWaiterByKey(std::addressof(num_waiters), reinterpret_cast<uintptr_t>(std::addressof(m_exception_thread))); next != nullptr) {
|
if (KThread *next = thread->RemoveWaiterByKey(std::addressof(num_waiters), reinterpret_cast<uintptr_t>(std::addressof(m_exception_thread)) | 1); next != nullptr) {
|
||||||
next->SetState(KThread::ThreadState_Runnable);
|
next->SetState(KThread::ThreadState_Runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ namespace ams::kern {
|
|||||||
R_UNLESS(m_current_values[which] <= value, svc::ResultInvalidState());
|
R_UNLESS(m_current_values[which] <= value, svc::ResultInvalidState());
|
||||||
|
|
||||||
m_limit_values[which] = value;
|
m_limit_values[which] = value;
|
||||||
|
m_peak_values[which] = m_current_values[which];
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
|||||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||||
-I.
|
-I.
|
||||||
|
|
||||||
.PHONY: clean all
|
.PHONY: clean all lib/$(TARGET).a
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
all: lib/$(TARGET).a
|
all: lib/$(TARGET).a
|
||||||
|
|||||||
@@ -164,6 +164,6 @@ namespace ams::fs {
|
|||||||
static_assert(util::is_pod<HashSalt>::value);
|
static_assert(util::is_pod<HashSalt>::value);
|
||||||
static_assert(sizeof(HashSalt) == HashSalt::Size);
|
static_assert(sizeof(HashSalt) == HashSalt::Size);
|
||||||
|
|
||||||
using SaveDataHashSalt = std::optional<HashSalt>;
|
using SaveDataHashSalt = util::optional<HashSalt>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <stratosphere/fssrv/sf/fssrv_sf_path.hpp>
|
#include <stratosphere/fssrv/sf/fssrv_sf_path.hpp>
|
||||||
#include <stratosphere/fssrv/sf/fssrv_sf_ifile.hpp>
|
#include <stratosphere/fssrv/sf/fssrv_sf_ifile.hpp>
|
||||||
#include <stratosphere/fssrv/sf/fssrv_sf_i_event_notifier.hpp>
|
#include <stratosphere/fssrv/sf/fssrv_sf_i_event_notifier.hpp>
|
||||||
|
#include <stratosphere/fssrv/impl/fssrv_impl_program_index_map_info_manager.hpp>
|
||||||
#include <stratosphere/fssrv/fssrv_path_normalizer.hpp>
|
#include <stratosphere/fssrv/fssrv_path_normalizer.hpp>
|
||||||
#include <stratosphere/fssrv/fssrv_nca_crypto_configuration.hpp>
|
#include <stratosphere/fssrv/fssrv_nca_crypto_configuration.hpp>
|
||||||
#include <stratosphere/fssrv/fssrv_memory_resource_from_standard_allocator.hpp>
|
#include <stratosphere/fssrv/fssrv_memory_resource_from_standard_allocator.hpp>
|
||||||
|
|||||||
@@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||||
|
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||||
|
#include <stratosphere/fs/fs_program_index_map_info.hpp>
|
||||||
|
|
||||||
|
namespace ams::fssrv::impl {
|
||||||
|
|
||||||
|
struct ProgramIndexMapInfoEntry : public ::ams::util::IntrusiveListBaseNode<ProgramIndexMapInfoEntry>, public ::ams::fs::impl::Newable {
|
||||||
|
ncm::ProgramId program_id;
|
||||||
|
ncm::ProgramId base_program_id;
|
||||||
|
u8 program_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ProgramIndexMapInfoManager {
|
||||||
|
NON_COPYABLE(ProgramIndexMapInfoManager);
|
||||||
|
NON_MOVEABLE(ProgramIndexMapInfoManager);
|
||||||
|
private:
|
||||||
|
using ProgramIndexMapInfoList = util::IntrusiveListBaseTraits<ProgramIndexMapInfoEntry>::ListType;
|
||||||
|
private:
|
||||||
|
ProgramIndexMapInfoList m_list;
|
||||||
|
mutable os::SdkMutex m_mutex;
|
||||||
|
public:
|
||||||
|
constexpr ProgramIndexMapInfoManager() : m_list(), m_mutex() { /* ... */ }
|
||||||
|
|
||||||
|
void Clear() {
|
||||||
|
/* Acquire exclusive access to the map. */
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
/* Actually clear. */
|
||||||
|
this->ClearImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetProgramCount() const {
|
||||||
|
/* Acquire exclusive access to the map. */
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
/* Get the size. */
|
||||||
|
return m_list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
util::optional<fs::ProgramIndexMapInfo> Get(const ncm::ProgramId &program_id) const {
|
||||||
|
/* Acquire exclusive access to the map. */
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
/* Get the entry from the map. */
|
||||||
|
return this->GetImpl([&] (const ProgramIndexMapInfoEntry &entry) {
|
||||||
|
return entry.program_id == program_id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ncm::ProgramId GetProgramId(const ncm::ProgramId &program_id, u8 program_index) const {
|
||||||
|
/* Acquire exclusive access to the map. */
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
/* Get the program info for the desired program id. */
|
||||||
|
const auto base_info = this->GetImpl([&] (const ProgramIndexMapInfoEntry &entry) {
|
||||||
|
return entry.program_id == program_id;
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Check that an entry exists for the program id. */
|
||||||
|
if (!base_info.has_value()) {
|
||||||
|
return ncm::InvalidProgramId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a program info which matches the same base program with the desired index. */
|
||||||
|
const auto target_info = this->GetImpl([&] (const ProgramIndexMapInfoEntry &entry) {
|
||||||
|
return entry.base_program_id == base_info->base_program_id && entry.program_index == program_index;
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Return the desired program id. */
|
||||||
|
if (target_info.has_value()) {
|
||||||
|
return target_info->program_id;
|
||||||
|
} else {
|
||||||
|
return ncm::InvalidProgramId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Reset(const fs::ProgramIndexMapInfo *infos, int count) {
|
||||||
|
/* Acquire exclusive access to the map. */
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
/* Clear the map, and ensure we remain clear if we fail after this point. */
|
||||||
|
this->ClearImpl();
|
||||||
|
auto clear_guard = SCOPE_GUARD { this->ClearImpl(); };
|
||||||
|
|
||||||
|
/* Add each info to the list. */
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
/* Allocate new entry. */
|
||||||
|
auto *entry = new ProgramIndexMapInfoEntry;
|
||||||
|
R_UNLESS(entry != nullptr, fs::ResultAllocationFailureInNew());
|
||||||
|
|
||||||
|
/* Copy over the info. */
|
||||||
|
entry->program_id = infos[i].program_id;
|
||||||
|
entry->base_program_id = infos[i].base_program_id;
|
||||||
|
entry->program_index = infos[i].program_index;
|
||||||
|
|
||||||
|
/* Add to the list. */
|
||||||
|
m_list.push_back(*entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We successfully imported the map. */
|
||||||
|
clear_guard.Cancel();
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void ClearImpl() {
|
||||||
|
/* Delete all entries. */
|
||||||
|
while (!m_list.empty()) {
|
||||||
|
/* Get the first entry. */
|
||||||
|
ProgramIndexMapInfoEntry *front = std::addressof(*m_list.begin());
|
||||||
|
|
||||||
|
/* Erase it from the list. */
|
||||||
|
m_list.erase(m_list.iterator_to(*front));
|
||||||
|
|
||||||
|
/* Delete the entry. */
|
||||||
|
delete front;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
util::optional<fs::ProgramIndexMapInfo> GetImpl(F f) const {
|
||||||
|
/* Try to find an entry matching the predicate. */
|
||||||
|
util::optional<fs::ProgramIndexMapInfo> match = util::nullopt;
|
||||||
|
|
||||||
|
for (const auto &entry : m_list) {
|
||||||
|
/* If the predicate matches, we want to return the relevant info. */
|
||||||
|
if (f(entry)) {
|
||||||
|
match.emplace();
|
||||||
|
|
||||||
|
match->program_id = entry.program_id;
|
||||||
|
match->base_program_id = entry.base_program_id;
|
||||||
|
match->program_index = entry.program_index;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -92,7 +92,7 @@ namespace ams::fssrv::impl {
|
|||||||
public:
|
public:
|
||||||
bool IsDeepRetryEnabled() const;
|
bool IsDeepRetryEnabled() const;
|
||||||
bool IsAccessFailureDetectionObserved() const;
|
bool IsAccessFailureDetectionObserved() const;
|
||||||
std::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
|
util::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
|
||||||
os::ReadWriteLock &GetReadWriteLockForCacheInvalidation();
|
os::ReadWriteLock &GetReadWriteLockForCacheInvalidation();
|
||||||
public:
|
public:
|
||||||
/* Command API. */
|
/* Command API. */
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace ams::fssrv::impl {
|
|||||||
|
|
||||||
~StorageInterfaceAdapter();
|
~StorageInterfaceAdapter();
|
||||||
private:
|
private:
|
||||||
std::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
|
util::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
|
||||||
public:
|
public:
|
||||||
/* Command API. */
|
/* Command API. */
|
||||||
Result Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size);
|
Result Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size);
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ namespace ams::fssystem {
|
|||||||
|
|
||||||
virtual ~DirectoryRedirectionFileSystem();
|
virtual ~DirectoryRedirectionFileSystem();
|
||||||
protected:
|
protected:
|
||||||
inline std::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() const {
|
inline util::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() const {
|
||||||
/* No accessor lock is needed. */
|
/* No accessor lock is needed. */
|
||||||
return std::nullopt;
|
return util::nullopt;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Result GetNormalizedDirectoryPath(char **out, size_t *out_size, const char *dir);
|
Result GetNormalizedDirectoryPath(char **out, size_t *out_size, const char *dir);
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ namespace ams::fssystem {
|
|||||||
|
|
||||||
virtual ~DirectorySaveDataFileSystem();
|
virtual ~DirectorySaveDataFileSystem();
|
||||||
protected:
|
protected:
|
||||||
inline std::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() {
|
inline util::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() {
|
||||||
/* We have a real accessor lock that we want to use. */
|
/* We have a real accessor lock that we want to use. */
|
||||||
return std::make_optional<std::scoped_lock<os::Mutex>>(this->accessor_mutex);
|
return util::make_optional<std::scoped_lock<os::Mutex>>(this->accessor_mutex);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Result AllocateWorkBuffer(std::unique_ptr<u8[]> *out, size_t *out_size, size_t ideal_size);
|
Result AllocateWorkBuffer(std::unique_ptr<u8[]> *out, size_t *out_size, size_t ideal_size);
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ namespace ams::fssystem {
|
|||||||
class Sha256PartitionFileSystemMeta : public PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat> {
|
class Sha256PartitionFileSystemMeta : public PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat> {
|
||||||
public:
|
public:
|
||||||
using PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat>::Initialize;
|
using PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat>::Initialize;
|
||||||
Result Initialize(fs::IStorage *base_storage, MemoryResource *allocator, const void *hash, size_t hash_size, std::optional<u8> suffix = std::nullopt);
|
Result Initialize(fs::IStorage *base_storage, MemoryResource *allocator, const void *hash, size_t hash_size, util::optional<u8> suffix = util::nullopt);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ namespace ams::fssystem {
|
|||||||
|
|
||||||
virtual ~SubDirectoryFileSystem();
|
virtual ~SubDirectoryFileSystem();
|
||||||
protected:
|
protected:
|
||||||
inline std::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() const {
|
inline util::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() const {
|
||||||
/* No accessor lock is needed. */
|
/* No accessor lock is needed. */
|
||||||
return std::nullopt;
|
return util::nullopt;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Result Initialize(const char *bp);
|
Result Initialize(const char *bp);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->CreateFile(full_path, size, option);
|
return this->base_fs->CreateFile(full_path, size, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->DeleteFile(full_path);
|
return this->base_fs->DeleteFile(full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->CreateDirectory(full_path);
|
return this->base_fs->CreateDirectory(full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->DeleteDirectory(full_path);
|
return this->base_fs->DeleteDirectory(full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->DeleteDirectoryRecursively(full_path);
|
return this->base_fs->DeleteDirectoryRecursively(full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ namespace ams::fssystem::impl {
|
|||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(old_full_path, sizeof(old_full_path), old_path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(old_full_path, sizeof(old_full_path), old_path));
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(new_full_path, sizeof(new_full_path), new_path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(new_full_path, sizeof(new_full_path), new_path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->RenameFile(old_full_path, new_full_path);
|
return this->base_fs->RenameFile(old_full_path, new_full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ namespace ams::fssystem::impl {
|
|||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(old_full_path, sizeof(old_full_path), old_path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(old_full_path, sizeof(old_full_path), old_path));
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(new_full_path, sizeof(new_full_path), new_path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(new_full_path, sizeof(new_full_path), new_path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->RenameDirectory(old_full_path, new_full_path);
|
return this->base_fs->RenameDirectory(old_full_path, new_full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->GetEntryType(out, full_path);
|
return this->base_fs->GetEntryType(out, full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->OpenFile(out_file, full_path, mode);
|
return this->base_fs->OpenFile(out_file, full_path, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,12 +126,12 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->OpenDirectory(out_dir, full_path, mode);
|
return this->base_fs->OpenDirectory(out_dir, full_path, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoCommit() override {
|
virtual Result DoCommit() override {
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->Commit();
|
return this->base_fs->Commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->GetFreeSpaceSize(out, full_path);
|
return this->base_fs->GetFreeSpaceSize(out, full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->GetTotalSpaceSize(out, full_path);
|
return this->base_fs->GetTotalSpaceSize(out, full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->CleanDirectoryRecursively(full_path);
|
return this->base_fs->CleanDirectoryRecursively(full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->GetFileTimeStampRaw(out, full_path);
|
return this->base_fs->GetFileTimeStampRaw(out, full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,23 +171,23 @@ namespace ams::fssystem::impl {
|
|||||||
char full_path[fs::EntryNameLengthMax + 1];
|
char full_path[fs::EntryNameLengthMax + 1];
|
||||||
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
R_TRY(static_cast<Impl*>(this)->ResolveFullPath(full_path, sizeof(full_path), path));
|
||||||
|
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->QueryEntry(dst, dst_size, src, src_size, query, full_path);
|
return this->base_fs->QueryEntry(dst, dst_size, src, src_size, query, full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These aren't accessible as commands. */
|
/* These aren't accessible as commands. */
|
||||||
virtual Result DoCommitProvisionally(s64 counter) override {
|
virtual Result DoCommitProvisionally(s64 counter) override {
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->CommitProvisionally(counter);
|
return this->base_fs->CommitProvisionally(counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoRollback() override {
|
virtual Result DoRollback() override {
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->Rollback();
|
return this->base_fs->Rollback();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoFlush() override {
|
virtual Result DoFlush() override {
|
||||||
std::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
util::optional optional_lock = static_cast<Impl*>(this)->GetAccessorLock();
|
||||||
return this->base_fs->Flush();
|
return this->base_fs->Flush();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ namespace ams::hos {
|
|||||||
Version_12_0_1 = ::ams::TargetFirmware_12_0_1,
|
Version_12_0_1 = ::ams::TargetFirmware_12_0_1,
|
||||||
Version_12_0_2 = ::ams::TargetFirmware_12_0_2,
|
Version_12_0_2 = ::ams::TargetFirmware_12_0_2,
|
||||||
Version_12_0_3 = ::ams::TargetFirmware_12_0_3,
|
Version_12_0_3 = ::ams::TargetFirmware_12_0_3,
|
||||||
|
Version_12_1_0 = ::ams::TargetFirmware_12_1_0,
|
||||||
|
|
||||||
Version_Current = ::ams::TargetFirmware_Current,
|
Version_Current = ::ams::TargetFirmware_Current,
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ namespace ams::kvdb {
|
|||||||
public:
|
public:
|
||||||
Result Initialize(void *buffer, size_t buffer_size, size_t capacity);
|
Result Initialize(void *buffer, size_t buffer_size, size_t capacity);
|
||||||
void Invalidate();
|
void Invalidate();
|
||||||
std::optional<size_t> TryGet(void *out_value, size_t max_out_size, const void *key, size_t key_size);
|
util::optional<size_t> TryGet(void *out_value, size_t max_out_size, const void *key, size_t key_size);
|
||||||
std::optional<size_t> TryGetSize(const void *key, size_t key_size);
|
util::optional<size_t> TryGetSize(const void *key, size_t key_size);
|
||||||
void Set(const void *key, size_t key_size, const void *value, size_t value_size);
|
void Set(const void *key, size_t key_size, const void *value, size_t value_size);
|
||||||
bool Contains(const void *key, size_t key_size);
|
bool Contains(const void *key, size_t key_size);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,6 +37,6 @@ namespace ams::ncm {
|
|||||||
void GetTicketFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id);
|
void GetTicketFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id);
|
||||||
void GetCertificateFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id);
|
void GetCertificateFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id);
|
||||||
|
|
||||||
std::optional<ContentId> GetContentIdFromString(const char *str, size_t len);
|
util::optional<ContentId> GetContentIdFromString(const char *str, size_t len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ namespace ams::ncm {
|
|||||||
StorageId storage_id;
|
StorageId storage_id;
|
||||||
SystemSaveDataInfo info;
|
SystemSaveDataInfo info;
|
||||||
sf::SharedPointer<IContentMetaDatabase> content_meta_database;
|
sf::SharedPointer<IContentMetaDatabase> content_meta_database;
|
||||||
std::optional<kvdb::MemoryKeyValueStore<ContentMetaKey>> kvs;
|
util::optional<kvdb::MemoryKeyValueStore<ContentMetaKey>> kvs;
|
||||||
ContentMetaMemoryResource *memory_resource;
|
ContentMetaMemoryResource *memory_resource;
|
||||||
u32 max_content_metas;
|
u32 max_content_metas;
|
||||||
|
|
||||||
|
|||||||
@@ -303,17 +303,17 @@ namespace ams::ncm {
|
|||||||
return static_cast<StorageId>(this->GetHeader()->storage_id);
|
return static_cast<StorageId>(this->GetHeader()->storage_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ApplicationId> GetApplicationId(const ContentMetaKey &key) const {
|
util::optional<ApplicationId> GetApplicationId(const ContentMetaKey &key) const {
|
||||||
switch (key.type) {
|
switch (key.type) {
|
||||||
case ContentMetaType::Application: return ApplicationId{ key.id };
|
case ContentMetaType::Application: return ApplicationId{ key.id };
|
||||||
case ContentMetaType::Patch: return this->GetExtendedHeader<PatchMetaExtendedHeader>()->application_id;
|
case ContentMetaType::Patch: return this->GetExtendedHeader<PatchMetaExtendedHeader>()->application_id;
|
||||||
case ContentMetaType::AddOnContent: return this->GetExtendedHeader<AddOnContentMetaExtendedHeader>()->application_id;
|
case ContentMetaType::AddOnContent: return this->GetExtendedHeader<AddOnContentMetaExtendedHeader>()->application_id;
|
||||||
case ContentMetaType::Delta: return this->GetExtendedHeader<DeltaMetaExtendedHeader>()->application_id;
|
case ContentMetaType::Delta: return this->GetExtendedHeader<DeltaMetaExtendedHeader>()->application_id;
|
||||||
default: return std::nullopt;
|
default: return util::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ApplicationId> GetApplicationId() const {
|
util::optional<ApplicationId> GetApplicationId() const {
|
||||||
return this->GetApplicationId(this->GetKey());
|
return this->GetApplicationId(this->GetKey());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user