Compare commits

..

25 Commits

Author SHA1 Message Date
Michael Scire
1f065e3bac git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "87a1de0b"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "87a1de0b"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-08-20 13:34:30 -07:00
Michael Scire
9296a56303 ams: bump to 0.2.0
NOTE: Release will not occur until hekate is ready to handle new sept-less release format.
2021-08-20 13:31:59 -07:00
Michael Scire
481b209ae8 docs: wipe sept from the docs 2021-08-20 13:17:11 -07:00
SciresM
17ca463c3f ams: replace sept with tsec firmware (#1594)
* ams: replace sept with tsec firmware

This replaces sept with a custom tsec key derivation firmware.

NOTE: This does not use any TSEC exploits whatsoever; it is a well-signed
TSEC binary assembled with envyas and signed with the real cauth key.

For more details, contact SciresM#0524.

* fusee: only set SBK if it's readable
2021-08-20 13:13:29 -07:00
Michael Scire
f175802136 kern: improve some debug output 2021-08-20 00:06:43 -07:00
Michael Scire
fe79bc253a kern: fix same is_current check in GetThreadContext 2021-08-19 07:38:25 -07:00
Michael Scire
81bf8c577a kern: fix check for thread-is-current in KDebugBase::SetThreadContext 2021-08-19 07:34:08 -07:00
SciresM
aee89db748 mtc: implement memory training for mariko (#1593)
* mtc: implement memory training for mariko

* mtc: fix apply_periodic_compensation_trimmer, train_wr_vref results

* mtc: fix clktree calculations
2021-08-17 17:27:12 -07:00
Michael Scire
f5704d25f8 kern: remove firmare-specific SignalAndModify impl
Nintendo made this breaking change because there was zero official software relying on it,
so it's safe for us to make the same change.
2021-07-22 15:56:45 -07:00
Michael Scire
73afa042f1 dmnt: fix opcode decoding (closes #1575) 2021-07-22 06:06:48 -07:00
Michael Scire
2da31b122f kern: fix hardware watchpoint detection 2021-07-22 00:35:40 -07:00
Michael Scire
43bbfd29bb kern: fix inverted condition in context breakpoint validation 2021-07-21 23:56:28 -07:00
Michael Scire
4cb4707f34 dmnt: add theoretical 'else' support to cheat engine vm conditionals 2021-07-21 19:36:46 -07:00
Michael Scire
389c3b6baa dmnt: various cheat changes/suggestions that have been cooking a while 2021-07-21 19:21:58 -07:00
Michael Scire
0c596e682f exo/daybreak: advertise (and check against) supported hos version 2021-07-21 18:21:38 -07:00
tslater2006
4d430a4c61 Updates to Cheats documentation (#1568)
* docs: update cheats doc to clarify Code Type 5 encoding

This change removes references to the "M" nibble for the "Register Address" encoding of Code Type 5 whis is not used in this mode.

In the dword block the "M" has been replaced with a "0"

* docs: update cheats doc to clarify register usage on Code Type 5

This adds additional clarification for "Register Address Encoding" mode of Code Type 5 that the "R" nibble reflects both the destination as well as the base memory address.

* docs: update cheats doc to make Code Types consistent

Code Types are now consistently written in hex notation.
2021-07-16 11:17:03 -07:00
Michael Scire
0c41489f01 exo: fix SE aes-ctr usage in GetSecureData 2021-07-16 10:55:49 -07:00
Michael Scire
bd6155bcb4 kern: since 10.0.0, KDebug::GetThreadContext always returns X0-X7 2021-07-13 13:00:16 -07:00
Michael Scire
3bedf56512 kern: fix incorrect waiter management in KProcess::ReleaseUserException 2021-07-13 05:27:19 -07:00
Michael Scire
1be74ea6e2 kern: fix bug in KConditionVariable::SignalImpl 2021-07-13 01:40:16 -07:00
Michael Scire
14d458522d kern: update initial cache management to match latest kernel 2021-07-12 18:30:01 -07:00
Michael Scire
12bf9612cb git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "e96b24f8"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "e96b24f8"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-07-12 02:00:12 -07:00
Michael Scire
ea7b6e14f9 ams-libs: fix change detection for library building 2021-07-12 01:59:37 -07:00
Michael Scire
5e3339e866 kern: add missing abort on unmap failure 2021-07-11 21:59:06 -07:00
Michael Scire
a7c14e03b9 ams: std::optional -> util::optional 2021-07-08 02:37:26 -07:00
243 changed files with 17176 additions and 29029 deletions

3
.gitignore vendored
View File

@@ -79,9 +79,8 @@ dkms.conf
*.nam
*.til
# KEYS file for sept-secondary.
# Compiled python files.
*.pyc
sept/sept-secondary/KEYS.py
.**/

View File

@@ -32,10 +32,7 @@ mesosphere: exosphere libraries
troposphere: stratosphere
$(MAKE) -C troposphere all
sept: exosphere
$(MAKE) -C sept all
fusee: exosphere mesosphere stratosphere sept
fusee: exosphere mesosphere stratosphere
$(MAKE) -C $@ all
libraries:
@@ -61,7 +58,6 @@ dist-no-debug: all
rm -rf out
mkdir atmosphere-$(AMSVER)
mkdir atmosphere-$(AMSVER)/atmosphere
mkdir atmosphere-$(AMSVER)/sept
mkdir atmosphere-$(AMSVER)/switch
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
mkdir -p atmosphere-$(AMSVER)/atmosphere/config_templates
@@ -71,13 +67,6 @@ dist-no-debug: all
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin
cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/sept/payload.bin
cp sept/sept-primary/sept-primary.bin atmosphere-$(AMSVER)/sept/sept-primary.bin
cp sept/sept-secondary/sept-secondary.bin atmosphere-$(AMSVER)/sept/sept-secondary.bin
cp sept/sept-secondary/sept-secondary_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_00.enc
cp sept/sept-secondary/sept-secondary_01.enc atmosphere-$(AMSVER)/sept/sept-secondary_01.enc
cp sept/sept-secondary/sept-secondary_dev_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_dev_00.enc
cp sept/sept-secondary/sept-secondary_dev_01.enc atmosphere-$(AMSVER)/sept/sept-secondary_dev_01.enc
cp config_templates/BCT.ini atmosphere-$(AMSVER)/atmosphere/config_templates/BCT.ini
cp config_templates/override_config.ini atmosphere-$(AMSVER)/atmosphere/config_templates/override_config.ini
cp config_templates/system_settings.ini atmosphere-$(AMSVER)/atmosphere/config_templates/system_settings.ini
@@ -109,7 +98,6 @@ dist-no-debug: all
cp troposphere/daybreak/daybreak.nro atmosphere-$(AMSVER)/switch/daybreak.nro
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/sept/payload.bin
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER)-WITHOUT_MESOSPHERE.zip ./*; cd ../;
rm -r atmosphere-$(AMSVER)
mkdir out
@@ -133,9 +121,6 @@ dist: dist-no-debug
cp fusee/fusee-primary/fusee-primary.elf atmosphere-$(AMSVER)-debug/fusee-primary.elf
cp fusee/fusee-mtc/fusee-mtc.elf atmosphere-$(AMSVER)-debug/fusee-mtc.elf
cp fusee/fusee-secondary/fusee-secondary-experimental.elf atmosphere-$(AMSVER)-debug/fusee-secondary.elf
cp sept/sept-primary/sept-primary.elf atmosphere-$(AMSVER)-debug/sept-primary.elf
cp sept/sept-secondary/sept-secondary.elf atmosphere-$(AMSVER)-debug/sept-secondary.elf
cp sept/sept-secondary/key_derivation/key_derivation.elf atmosphere-$(AMSVER)-debug/sept-secondary-key-derivation.elf
cp exosphere/loader_stub/loader_stub.elf atmosphere-$(AMSVER)-debug/exosphere-loader-stub.elf
cp exosphere/program/program.elf atmosphere-$(AMSVER)-debug/exosphere-program.elf
cp exosphere/warmboot/warmboot.elf atmosphere-$(AMSVER)-debug/exosphere-warmboot.elf

View File

@@ -9,7 +9,7 @@ Building Atmosphère is a very straightforward process that relies almost exclus
+ [PyCryptodome](https://pypi.org/project/pycryptodome) (optional)
## Instructions
1. Follow the guide located [here](https://devkitpro.org/wiki/Getting_Started) to install and configure all the tools necessary for the build process.
1. Follow the guide located [here](https://devkitpro.org/wiki/Getting_Started) to install and configure all the tools necessary for the build process.
2. Install the following packages via (dkp-)pacman:
+ `switch-dev`
@@ -21,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):
+ `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.
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.
4. Finally, clone the Atmosphère repository and run `make` under its root directory.

View File

@@ -1,4 +1,31 @@
# 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.

View File

@@ -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.

View File

@@ -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 activated the cheat manager, but the user wants to use an alternate debugger, the cheat manager's service API provides a `ForceCloseCheatProcess` command that homebrew can use. This command will cause the cheat manager to detach itself from the process.
By default, all cheat codes listed in the loaded .txt file will be toggled on. This is configurable by the user by editing the `atmosphere!dmnt_cheats_enabled_by_default` [system setting](configurations.md).
Users may use homebrew programs to toggle cheats on and off at runtime via the cheat manager's service API.
@@ -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.
### Code Type 0: Store Static Value to Memory
Code type 0 allows writing a static value to a memory address.
### Code Type 0x0: Store Static Value to Memory
Code type 0x0 allows writing a static value to a memory address.
#### Encoding
`0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
+ T: Width of memory write (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
+ 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.
+ A: Immediate offset to use from memory region base.
+ V: Value to write.
---
### Code Type 1: Begin Conditional Block
Code type 1 performs a comparison of the contents of memory to a static value.
### Code Type 0x1: Begin Conditional Block
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
`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
+ T: Width of memory write (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
+ C: Condition to use, see below.
+ A: Immediate offset to use from memory region base.
+ 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 2 marks the end of a conditional block (started by Code Type 1 or Code Type 8).
### Code Type 0x2: End Conditional Block
Code type 0x2 marks the end of a conditional block (started by Code Type 0x1 or Code Type 0x8).
When an Else is executed, all instructions until the appropriate End conditional block terminator are skipped.
#### Encoding
`20000000`
`2X000000`
+ X: End type (0 = End, 1 = Else).
---
### Code Type 3: Start/End Loop
Code type 3 allows for iterating in a loop a fixed number of times.
### Code Type 0x3: Start/End Loop
Code type 0x3 allows for iterating in a loop a fixed number of times.
#### Start Loop Encoding
`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 4 allows setting a register to a constant value.
### Code Type 0x4: Load Register with Static Value
Code type 0x4 allows setting a register to a constant value.
#### Encoding
`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 5 allows loading a value from memory into a register, either using a fixed address or by dereferencing the destination register.
### Code Type 0x5: Load Register with Memory Value
Code type 0x5 allows loading a value from memory into a register, either using a fixed address or by dereferencing the destination register.
#### Load From Fixed Address Encoding
`5TMR00AA AAAAAAAA`
+ T: Width of memory read (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
+ R: Register to load value into.
+ A: Immediate offset to use from memory region base.
#### Load from Register Address Encoding
`5TMR10AA AAAAAAAA`
`5T0R10AA AAAAAAAA`
+ 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.
+ R: Register to load value into. (This register is also used as the base memory address).
+ A: Immediate offset to use from register R.
---
### Code Type 6: Store Static Value to Register Memory Address
Code type 6 allows writing a fixed value to a memory address specified by a register.
### Code Type 0x6: Store Static Value to Register Memory Address
Code type 0x6 allows writing a fixed value to a memory address specified by a register.
#### Encoding
`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 7 allows performing arithmetic on registers.
### Code Type 0x7: Legacy Arithmetic
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
`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 8 enters or skips a conditional block based on whether a key combination is pressed.
### Code Type 0x8: Begin Keypress Conditional Block
Code type 0x8 enters or skips a conditional block based on whether a key combination is pressed.
#### Encoding
`8kkkkkkk`
@@ -213,8 +218,8 @@ Note: This is the direct output of `hidKeysDown()`.
---
### Code Type 9: Perform Arithmetic
Code type 9 allows performing arithmetic on registers.
### Code Type 0x9: Perform Arithmetic
Code type 0x9 allows performing arithmetic on registers.
#### Register Arithmetic Encoding
`9TCRS0s0`
@@ -248,8 +253,8 @@ Code type 9 allows performing arithmetic on registers.
---
### Code Type 10: Store Register to Memory Address
Code type 10 allows writing a register to memory.
### Code Type 0xA: Store Register to Memory Address
Code type 0xA allows writing a register to memory.
#### Encoding
`ATSRIOxa (aaaaaaaa)`
@@ -272,13 +277,13 @@ Code type 10 allows writing a register to memory.
---
### Code Type 11: Reserved
Code Type 11 is currently reserved for future use.
### Code Type 0xB: Reserved
Code Type 0xB is currently reserved for future use.
---
### Code Type 12-15: Extended-Width Instruction
Code Types 12-15 signal to the VM to treat the upper two nybbles of the first dword as instruction type, instead of just the upper nybble.
### Code Type 0xC-0xF: Extended-Width Instruction
Code Types 0xC-0xF signal to the VM to treat the upper two nybbles of the first dword as instruction type, instead of just the upper nybble.
This reserves an additional 64 opcodes for future use.

View File

@@ -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:
+ [emummc](components/emummc.md)
+ [sept](components/sept.md)
+ [libraries](components/libraries.md)
## Features

View File

@@ -20,13 +20,13 @@
namespace ams::secmon::loader {
NORETURN void UncompressAndExecute() {
NORETURN void UncompressAndExecute(const void *program, const void *boot_code) {
/* 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 */
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(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, boot_code_lz4_size);

View File

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

View File

@@ -272,7 +272,19 @@ namespace ams::secmon::smc {
void GetSecureDataImpl(u8 *dst, SecureData which, bool tweak) {
/* 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. */
if (tweak) {

View File

@@ -243,7 +243,7 @@ namespace ams::secmon::smc {
(static_cast<u64>(ATMOSPHERE_RELEASE_VERSION_MINOR & 0xFF) << 48) |
(static_cast<u64>(ATMOSPHERE_RELEASE_VERSION_MICRO & 0xFF) << 40) |
(static_cast<u64>(GetKeyGeneration()) << 32) |
(static_cast<u64>(GetTargetFirmware()) << 00);
(static_cast<u64>(GetTargetFirmware()) << 0);
break;
case ConfigItem::ExosphereNeedsReboot:
/* 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. */
args.r[1] = GetSecmonConfiguration().IsUsb30ForceEnabled();
break;
case ConfigItem::ExosphereSupportedHosVersion:
/* Get information about the supported hos version. */
args.r[1] = (static_cast<u64>(ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR & 0xFF) << 24) |
(static_cast<u64>(ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR & 0xFF) << 16) |
(static_cast<u64>(ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO & 0xFF) << 8);
break;
default:
return SmcResult::InvalidArgument;
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FUSEE_CAR_H
#define FUSEE_CAR_H
@@ -489,7 +489,16 @@ typedef struct {
uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
uint32_t sdmmc4_pllc4_out1_shaper_ctrl; /* _SDMMC4_PLLC4_OUT1_SHAPER_CTRL_0, 0x73c */
uint32_t sdmmc4_pllc4_out2_shaper_ctrl; /* _SDMMC4_PLLC4_OUT2_SHAPER_CTRL_0, 0x740 */
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
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;
static inline volatile tegra_car_t *car_get_regs(void) {

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -158,7 +158,12 @@ static void config_se_brom(void) {
/* Bootrom part we skipped. */
uint32_t sbk[4] = {fuse_chip->FUSE_PRIVATE_KEY[0], fuse_chip->FUSE_PRIVATE_KEY[1], fuse_chip->FUSE_PRIVATE_KEY[2], fuse_chip->FUSE_PRIVATE_KEY[3]};
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. */
se->SE_CRYPTO_KEYTABLE_ACCESS[0xE] = 0x7E;
@@ -247,7 +252,7 @@ void nx_hwinit(bool enable_log) {
} else {
uint8_t val = 0x40;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
val = 0x60;
val = 0x58;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
val = 0x38;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1);

View File

@@ -92,8 +92,8 @@ export KIPDIRS := $(AMS)/stratosphere/loader $(AMS)/stratosphere/ncm $(AMS)/stra
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
$(AMS)/exosphere $(AMS)/exosphere/warmboot $(AMS)/exosphere/program/rebootstub \
$(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/sept/sept-primary \
$(AMS)/sept/sept-secondary $(AMS)/emummc $(AMS)/mesosphere $(AMS)/mesosphere/kernel_ldr $(KIPDIRS)
$(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/emummc $(AMS)/mesosphere \
$(KIPDIRS)
export DEPSDIR := $(CURDIR)/$(BUILD)
@@ -103,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
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.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 \
sept-secondary_dev_00.enc sept-secondary_dev_01.enc mesosphere.bin kernel_ldr.bin \
mariko_fatal.bin $(KIPFILES)
emummc.kip mesosphere.bin mariko_fatal.bin $(KIPFILES)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
@@ -133,7 +131,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
.PHONY: $(BUILD) clean all
.PHONY: check_fusee_primary check_exosphere check_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)
@@ -144,9 +142,6 @@ check_fusee_primary:
check_exosphere:
@$(MAKE) -C $(AMS)/exosphere all
check_sept:
@$(MAKE) -C $(AMS)/sept all
check_emummc:
@$(MAKE) -C $(AMS)/emummc EMUMMCDIR=$(AMS)/emummc all
@@ -163,7 +158,7 @@ check_libraries:
@$(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 $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
@@ -176,7 +171,6 @@ clean:
@$(MAKE) -C $(AMS)/libraries clean
@$(MAKE) -C $(AMS)/mesosphere clean
@$(MAKE) -C $(AMS)/stratosphere clean
@$(MAKE) -C $(AMS)/sept clean
@$(MAKE) -C $(AMS)/emummc clean
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
@@ -216,31 +210,6 @@ fusee_primary.bin.o fusee_primary_bin.h: fusee-primary.bin
@echo $(notdir $<)
@$(_bin2o)
sept_primary.bin.o sept_primary_bin.h: sept-primary.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
sept_secondary_00.enc.o sept_secondary_00_enc.h: sept-secondary_00.enc
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
sept_secondary_01.enc.o sept_secondary_01_enc.h: sept-secondary_01.enc
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
sept_secondary_dev_00.enc.o sept_secondary_dev_00_enc.h: sept-secondary_dev_00.enc
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
sept_secondary_dev_01.enc.o sept_secondary_dev_01_enc.h: sept-secondary_dev_01.enc
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(_bin2o)
%.bin.o %_bin.h: %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)

Binary file not shown.

View File

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

View File

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

View File

@@ -21,12 +21,6 @@
#include "kernel_patches.h"
#include "ips.h"
#define u8 uint8_t
#define u32 uint32_t
#include "kernel_ldr_bin.h"
#undef u8
#undef u32
#define MAKE_BRANCH(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
#define MAKE_NOP 0xD503201F

View File

@@ -26,19 +26,6 @@
#define AL16 ALIGN(16)
static const uint8_t AL16 keyblob_seeds[MASTERKEY_REVISION_MAX][0x10] = {
{0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3}, /* Keyblob seed 00. */
{0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC}, /* Keyblob seed 01. */
{0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B}, /* Keyblob seed 02. */
{0x2D, 0x1F, 0x48, 0x80, 0xED, 0xEC, 0xED, 0x3E, 0x3C, 0xF2, 0x48, 0xB5, 0x65, 0x7D, 0xF7, 0xBE}, /* Keyblob seed 03. */
{0xBB, 0x5A, 0x01, 0xF9, 0x88, 0xAF, 0xF5, 0xFC, 0x6C, 0xFF, 0x07, 0x9E, 0x13, 0x3C, 0x39, 0x80}, /* Keyblob seed 04. */
{0xD8, 0xCC, 0xE1, 0x26, 0x6A, 0x35, 0x3F, 0xCC, 0x20, 0xF3, 0x2D, 0x3B, 0x51, 0x7D, 0xE9, 0xC0} /* Keyblob seed 05. */
};
static const uint8_t AL16 keyblob_mac_seed[0x10] = {
0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5
};
static const uint8_t AL16 masterkey_seed[0x10] = {
0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C
};
@@ -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
};
/* TODO: Bother adding 8.1.0 here? We'll never call into here... */
static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_800 - MASTERKEY_REVISION_600_610][0x10] = {
{0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, /* MasterKek seed 06. */
{0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, /* MasterKek seed 07. */
static const uint8_t AL16 keyblob_seed_00[0x10] = {
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3
};
static const uint8_t AL16 master_kek_seed_erista[0x10] = { /* TODO: Update on next change of keys. */
0x84, 0x67, 0xB6, 0x7F, 0x13, 0x11, 0xAE, 0xE6, 0x58, 0x9B, 0x19, 0xAF, 0x13, 0x6C, 0x80, 0x7A /* Erista MasterKek seed 0B. */
};
static const uint8_t AL16 master_devkey_seed_erista[0x10] = {
0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6
};
static const uint8_t AL16 master_kek_seed_mariko[0x10] = { /* TODO: Update on next change of keys. */
0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1, /* Mariko MasterKek seed 0B. */
};
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. */
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 zeroes[0x10] = {0};
/* Initialize keygen type. */
*out_keygen_type = 0;
/* Get whether we're using dev keys. */
const bool is_retail = fuse_get_hardware_state() != 0;
/* TODO: Set keyslot flags properly in preparation of derivation. */
set_aes_keyslot_flags(0xE, 0x15);
set_aes_keyslot_flags(0xD, 0x15);
/* Derive Keyblob Key 00. */
se_aes_ecb_decrypt_block(0xC, work_buffer, 0x10, keyblob_seed_00, 0x10);
decrypt_data_into_keyslot(0xF, 0xE, work_buffer, 0x10);
/* Set the TSEC key. */
set_aes_keyslot(0xD, tsec_key, 0x10);
/* Derive master kek. */
decrypt_data_into_keyslot(0xE, is_retail ? 0xD : 0xB, master_kek_seed_erista, 0x10);
/* Decrypt all keyblobs, setting keyslot 0xF correctly. */
for (unsigned int rev = 0; rev <= MASTERKEY_REVISION_600_610; rev++) {
int ret = decrypt_keyblob(keyblobs, rev, available_revision);
if (ret) {
return ret;
}
}
/* Derive master key, device master key. */
decrypt_data_into_keyslot(0xD, 0xE, masterkey_seed, 0x10);
decrypt_data_into_keyslot(0xE, 0xE, masterkey_4x_seed, 0x10);
/* Do 6.2.0+ keygen. */
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
uint32_t desired_keyblob;
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) {
/* NOTE: We load in the current key for all >= 8.1.0 firmwares to reduce sept binaries. */
desired_keyblob = MASTERKEY_REVISION_C10_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. */
/* Derive device keys. */
decrypt_data_into_keyslot(0xA, 0xF, devicekey_4x_seed, 0x10);
decrypt_data_into_keyslot(0xF, 0xF, devicekey_seed, 0x10);
decrypt_data_into_keyslot(0xC, 0xD, masterkey_4x_seed, 0x10);
decrypt_data_into_keyslot(0xD, 0xD, masterkey_seed, 0x10);
decrypt_data_into_keyslot(0xF, 0xF, devicekey_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. */
return mkey_detect_revision(fuse_get_hardware_state() != 0);

View File

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

View File

@@ -185,8 +185,8 @@ void derive_new_device_keys(bool is_retail, unsigned int keygen_keyslot, unsigne
if (relative_revision > mkey_get_revision()) {
break;
} else if (relative_revision == mkey_get_revision()) {
/* On 7.0.0 erista, sept will have derived this key for us already. */
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0 || is_mariko) {
/* On Erista, this will already be derived. */
if (is_mariko) {
decrypt_data_into_keyslot(is_mariko ? KEYSLOT_SWITCH_DEVICEKEY_MARIKO : KEYSLOT_SWITCH_DEVICEKEY, KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10);
}
} else {

View File

@@ -44,7 +44,6 @@
#include "masterkey.h"
#include "package1.h"
#include "package2.h"
#include "smmu.h"
#include "tsec.h"
#include "lp0.h"
#include "loader.h"
@@ -59,11 +58,8 @@
#include "exosphere_bin.h"
#include "mariko_fatal_bin.h"
#include "mesosphere_bin.h"
#include "sept_secondary_00_enc.h"
#include "sept_secondary_01_enc.h"
#include "sept_secondary_dev_00_enc.h"
#include "sept_secondary_dev_01_enc.h"
#include "warmboot_bin.h"
#include "tsec_keygen_bin.h"
#include "emummc_kip.h"
#undef u8
#undef u32
@@ -724,18 +720,11 @@ static void nxboot_move_bootconfig() {
free(bootconfig);
}
static bool get_and_clear_has_run_sept(void) {
bool has_run_sept = (MAKE_EMC_REG(EMC_SCRATCH0) & 0x80000000) != 0;
MAKE_EMC_REG(EMC_SCRATCH0) &= ~0x80000000;
return has_run_sept;
}
static void get_mariko_warmboot_path(char *dst, size_t dst_size, uint32_t version) {
snprintf(dst, dst_size, "warmboot_mariko/wb_%02" PRIx32 ".bin", version);
}
/* This is the main function responsible for booting Horizon. */
static nx_keyblob_t __attribute__((aligned(16))) g_keyblobs[32];
uint32_t nxboot_main(void) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
loader_ctx_t *loader_ctx = get_loader_ctx();
@@ -745,8 +734,6 @@ uint32_t nxboot_main(void) {
size_t package2_size;
void *tsec_fw;
size_t tsec_fw_size;
const void *sept_secondary_enc = NULL;
size_t sept_secondary_enc_size = 0;
void *warmboot_fw;
size_t warmboot_fw_size;
void *warmboot_memaddr;
@@ -756,7 +743,6 @@ uint32_t nxboot_main(void) {
size_t mesosphere_size;
void *emummc;
size_t emummc_size;
uint32_t available_revision;
FILE *boot0, *pk2file;
void *exosphere_memaddr;
exo_emummc_config_t exo_emummc_cfg;
@@ -844,7 +830,7 @@ uint32_t nxboot_main(void) {
fatal_error("[NXBOOT] Couldn't parse boot0: %s!\n", strerror(errno));
}
} else {
if (package1_read_and_parse_boot0_erista(&package1loader, &package1loader_size, 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));
}
}
@@ -860,103 +846,26 @@ uint32_t nxboot_main(void) {
}
/* Handle TSEC and Sept (Erista only). */
uint8_t tsec_key[0x10] = {0};
uint8_t tsec_root_keys[0x20][0x10] = {0};
if (!is_mariko) {
/* Read the TSEC firmware from a file, otherwise from PK1L. */
if (loader_ctx->tsecfw_path[0] != '\0') {
tsec_fw_size = get_file_size(loader_ctx->tsecfw_path);
if ((tsec_fw_size != 0) && (tsec_fw_size != 0xF00 && tsec_fw_size != 0x2900 && tsec_fw_size != 0x3000 && tsec_fw_size != 0x3300)) {
fatal_error("[NXBOOT] TSEC firmware from %s has a wrong size!\n", loader_ctx->tsecfw_path);
} else if (tsec_fw_size == 0) {
fatal_error("[NXBOOT] Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path);
}
/* Use Atmosphere's tsec_keygen implementation. */
tsec_fw_size = tsec_keygen_bin_size;
tsec_fw = memalign(0x100, tsec_fw_size);
/* Allocate memory for the TSEC firmware. */
tsec_fw = memalign(0x100, tsec_fw_size);
if (tsec_fw == NULL) {
fatal_error("[NXBOOT] Out of memory!\n");
}
if (read_from_file(tsec_fw, tsec_fw_size, loader_ctx->tsecfw_path) != tsec_fw_size) {
fatal_error("[NXBOOT] Could not read the TSEC firmware from %s!\n", loader_ctx->tsecfw_path);
}
if (tsec_fw_size == 0x3000) {
if (fuse_get_hardware_state() != 0) {
sept_secondary_enc = sept_secondary_00_enc;
sept_secondary_enc_size = sept_secondary_00_enc_size;
} else {
sept_secondary_enc = sept_secondary_dev_00_enc;
sept_secondary_enc_size = sept_secondary_dev_00_enc_size;
}
} else if (tsec_fw_size == 0x3300) {
if (fuse_get_hardware_state() != 0) {
sept_secondary_enc = sept_secondary_01_enc;
sept_secondary_enc_size = sept_secondary_01_enc_size;
} else {
sept_secondary_enc = sept_secondary_dev_01_enc;
sept_secondary_enc_size = sept_secondary_dev_01_enc_size;
}
} else {
fatal_error("[NXBOOT] Unable to identify sept revision to run.");
}
} else {
if (!package1_get_tsec_fw(&tsec_fw, package1loader, package1loader_size)) {
fatal_error("[NXBOOT] Failed to read the TSEC firmware from Package1loader!\n");
}
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) {
if (fuse_get_hardware_state() != 0) {
sept_secondary_enc = sept_secondary_01_enc;
sept_secondary_enc_size = sept_secondary_01_enc_size;
} else {
sept_secondary_enc = sept_secondary_dev_01_enc;
sept_secondary_enc_size = sept_secondary_dev_01_enc_size;
}
tsec_fw_size = 0x3300;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
if (fuse_get_hardware_state() != 0) {
sept_secondary_enc = sept_secondary_00_enc;
sept_secondary_enc_size = sept_secondary_00_enc_size;
} else {
sept_secondary_enc = sept_secondary_dev_00_enc;
sept_secondary_enc_size = sept_secondary_dev_00_enc_size;
}
tsec_fw_size = 0x3000;
} else if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
tsec_fw_size = 0x2900;
} else {
tsec_fw_size = 0xF00;
}
if (tsec_fw == NULL) {
fatal_error("[NXBOOT] Out of memory!\n");
}
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 (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
/* Detect whether we need to run sept-secondary in order to derive keys. */
if (!get_and_clear_has_run_sept()) {
reboot_to_sept(tsec_fw, tsec_fw_size, sept_secondary_enc, sept_secondary_enc_size);
} else {
if (mkey_detect_revision(fuse_get_hardware_state() != 0) != 0) {
fatal_error("[NXBOOT] Sept derived incorrect keys!\n");
}
}
get_and_clear_has_run_sept();
} else if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_6_2_0) {
uint8_t tsec_keys[0x20] = {0};
if (tsec_fw_size == 0) {
fatal_error("[NXBOOT] Could not read the warmboot firmware from Package1!\n");
}
/* Emulate the TSEC payload on 6.2.0+. */
smmu_emulate_tsec((void *)tsec_keys, package1loader, package1loader_size, package1loader);
/* Copy back the keys. */
memcpy((void *)tsec_key, (void *)tsec_keys, 0x10);
memcpy((void *)tsec_root_keys, (void *)tsec_keys + 0x10, 0x10);
} else {
/* Run the TSEC payload and get the key. */
if (tsec_get_key(tsec_key, 1, tsec_fw, tsec_fw_size) != 0) {
fatal_error("[NXBOOT] Failed to get TSEC key!\n");
}
/* Get the TSEC keys into the security engine. */
int tsec_res = tsec_run_fw(tsec_fw, tsec_fw_size);
if (tsec_res != 0) {
volatile tegra_tsec_t *tsec = tsec_get_regs();
fatal_error("[NXBOOT] Failed to run TSEC firmware %d %08x %08x!\n", tsec_res, tsec->TSEC_FALCON_MAILBOX0, tsec->TSEC_FALCON_MAILBOX1);
}
}
@@ -969,8 +878,8 @@ uint32_t nxboot_main(void) {
if (derive_nx_keydata_mariko(target_firmware) != 0) {
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). */
if (derive_nx_keydata_erista(target_firmware, g_keyblobs, available_revision, tsec_key, tsec_root_keys, &keygen_type) != 0) {
} else {
if (derive_nx_keydata_erista(target_firmware) != 0) {
fatal_error("[NXBOOT] Erista key derivation failed!\n");
}
}
@@ -1230,9 +1139,6 @@ uint32_t nxboot_main(void) {
/* Clean up. */
free(package1loader);
if (loader_ctx->tsecfw_path[0] != '\0') {
free(tsec_fw);
}
if (loader_ctx->warmboot_path[0] != '\0') {
free(warmboot_fw);
}

View File

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

View File

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

View File

@@ -59,14 +59,10 @@ typedef struct {
bool package1_is_custom_public_key(const void *bct, bool mariko);
int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, 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);
bool package1_get_tsec_fw(void **tsec_fw, const void *package1loader, size_t package1loader_size);
size_t package1_get_encrypted_package1(package1_header_t **package1, uint8_t *ctr, const void *package1loader, size_t package1loader_size);
/* Must be aligned to 16 bytes. */
bool package1_decrypt(package1_header_t *package1, size_t package1_size, const uint8_t *ctr);
void *package1_get_warmboot_fw(const package1_header_t *package1);
#endif

View File

@@ -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);
}

View File

@@ -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

View File

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

View File

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

View File

@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef FUSEE_TSEC_H_
#define FUSEE_TSEC_H_
@@ -306,8 +306,7 @@ static inline volatile tegra_tsec_t *tsec_get_regs(void)
void tsec_enable_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);
void tsec_run_fw();
int tsec_run_fw(const void *tsec_fw, size_t tsec_fw_size);
#endif

View File

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

View File

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

View File

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

View File

@@ -96,6 +96,8 @@ clean-$(strip $1):
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1))
@for i in $$(GCH_DIRS) $$(ATMOSPHERE_BUILD_DIR) $$(ATMOSPHERE_LIBRARY_DIR); do [ -d $$$$i ] && rmdir --ignore-fail-on-non-empty $$$$i || true; done
.PHONY: $(strip $1) clean-$(strip $1) $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
endef
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
@@ -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_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):
@[ -d $@ ] || mkdir -p $@

View File

@@ -96,6 +96,8 @@ clean-$(strip $1):
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1))
@for i in $$(GCH_DIRS) $$(ATMOSPHERE_BUILD_DIR) $$(ATMOSPHERE_LIBRARY_DIR); do [ -d $$$$i ] && rmdir --ignore-fail-on-non-empty $$$$i || true; done
.PHONY: $(strip $1) clean-$(strip $1) $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
endef
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
@@ -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_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):
@[ -d $@ ] || mkdir -p $@

View File

@@ -88,6 +88,8 @@ clean-$(strip $1):
@rm -fr $$(foreach hdr,$$(GCH_DIRS),$$(hdr)/$$(ATMOSPHERE_BOARD_NAME)_$$(ATMOSPHERE_ARCH_NAME)_$(strip $1))
@for i in $$(GCH_DIRS) $$(ATMOSPHERE_BUILD_DIR) $$(ATMOSPHERE_LIBRARY_DIR); do [ -d $$$$i ] && rmdir --ignore-fail-on-non-empty $$$$i || true; done
.PHONY: $(strip $1) clean-$(strip $1) $$(ATMOSPHERE_LIBRARY_DIR)/$(strip $2)
endef
$(eval $(call ATMOSPHERE_ADD_TARGET, release, $(TARGET).a, \
@@ -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_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):
@[ -d $@ ] || mkdir -p $@

View File

@@ -172,10 +172,8 @@ namespace ams::kern::arch::arm64::cpu {
/* Cache management helpers. */
void ClearPageToZeroImpl(void *);
void FlushEntireDataCacheSharedForInit();
void FlushEntireDataCacheLocalForInit();
void InvalidateEntireInstructionCacheForInit();
void StoreEntireCacheForInit();
void FlushEntireCacheForInit();
void FlushEntireDataCache();

View File

@@ -262,27 +262,6 @@ namespace ams::kern::arch::arm64::cpu {
__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) {
PerformCacheOperationBySetWayImpl<false>(level, StoreDataCacheLineBySetWayImpl);
cpu::DataSynchronizationBarrier();
@@ -361,24 +340,63 @@ namespace ams::kern::arch::arm64::cpu {
}
void FlushEntireDataCacheSharedForInit() {
return PerformCacheOperationBySetWayShared<true>(FlushDataCacheLineBySetWayImpl);
void StoreEntireCacheForInit() {
/* 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() {
return PerformCacheOperationBySetWayLocal<true>(FlushDataCacheLineBySetWayImpl);
}
void FlushEntireCacheForInit() {
/* 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();
EnsureInstructionConsistency();
}
void StoreEntireCacheForInit() {
PerformCacheOperationBySetWayLocal<true>(StoreDataCacheLineBySetWayImpl);
PerformCacheOperationBySetWayShared<true>(StoreDataCacheLineBySetWayImpl);
DataSynchronizationBarrierInnerShareable();
InvalidateEntireInstructionCacheForInit();
/* Invalidate entire TLB. */
InvalidateEntireTlb();
}
void FlushEntireDataCache() {

View File

@@ -258,7 +258,7 @@ namespace ams::kern::arch::arm64 {
{
exception = ams::svc::DebugException_BreakPoint;
param2 = far;
param3 = ams::svc::BreakPointType_HardwareInstruction;
param3 = ams::svc::BreakPointType_HardwareData;
}
break;
case EsrEc_SErrorInterrupt:
@@ -293,6 +293,13 @@ namespace ams::kern::arch::arm64 {
/* Print that an exception occurred. */
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 (!svc::ResultNotHandled::Includes(result)) {

View File

@@ -74,26 +74,32 @@ namespace ams::kern::arch::arm64 {
/* Get the exception context. */
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 ((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 (this->Is64Bit()) {
/* Get X0-X28. */
for (auto i = 0; i <= 28; ++i) {
out->r[i] = e_ctx->x[i];
}
if (is_64_bit) {
/* We're not in an SVC, so we can get X0-X29. */
register_count = 29;
} else {
/* Get R0-R12. */
for (auto i = 0; i <= 12; ++i) {
out->r[i] = static_cast<u32>(e_ctx->x[i]);
}
/* We're 32-bit, so we should get R0-R12. */
register_count = 13;
}
}
/* 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 ((context_flags & ams::svc::ThreadContextFlag_Control) != 0) {
if (this->Is64Bit()) {
if (is_64_bit) {
out->fp = e_ctx->x[29];
out->lr = e_ctx->x[30];
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 ((flags & (1ul << 21)) != 0) {
/* 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. */
R_UNLESS((flags & (1ul << 22)) == 0, svc::ResultInvalidCombination());

View File

@@ -55,16 +55,18 @@ namespace ams::kern::board::nintendo::nx::smc {
Package2Hash = 17,
/* Extension config items for exosphere. */
ExosphereApiVersion = 65000,
ExosphereNeedsReboot = 65001,
ExosphereNeedsShutdown = 65002,
ExosphereGitCommitHash = 65003,
ExosphereHasRcmBugPatch = 65004,
ExosphereBlankProdInfo = 65005,
ExosphereAllowCalWrites = 65006,
ExosphereEmummcType = 65007,
ExospherePayloadAddress = 65008,
ExosphereLogConfiguration = 65009,
ExosphereApiVersion = 65000,
ExosphereNeedsReboot = 65001,
ExosphereNeedsShutdown = 65002,
ExosphereGitCommitHash = 65003,
ExosphereHasRcmBugPatch = 65004,
ExosphereBlankProdInfo = 65005,
ExosphereAllowCalWrites = 65006,
ExosphereEmummcType = 65007,
ExospherePayloadAddress = 65008,
ExosphereLogConfiguration = 65009,
ExosphereForceEnableUsb30 = 65010,
ExosphereSupportedHosVersion = 65011,
};
enum class SmcResult {

View File

@@ -103,54 +103,29 @@ namespace ams::kern {
auto it = m_tree.nfind_key({ addr, -1 });
/* Determine the updated value. */
s32 new_value;
if (GetTargetFirmware() >= TargetFirmware_7_0_0) {
if (count <= 0) {
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
new_value = value - 2;
} else {
new_value = value + 1;
}
if (count <= 0) {
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
new_value = value - 2;
} else {
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
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;
}
new_value = value + 1;
}
} else {
if (count <= 0) {
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
new_value = value - 1;
} else {
new_value = value + 1;
}
} else {
if ((it != m_tree.end()) && (it->GetAddressArbiterKey() == addr)) {
auto tmp_it = it;
s32 tmp_num_waiters = 0;
while ((tmp_it != m_tree.end()) && (tmp_it->GetAddressArbiterKey() == addr) && (tmp_num_waiters < count + 1)) {
++tmp_num_waiters;
++tmp_it;
while ((++tmp_it != m_tree.end()) && (tmp_it->GetAddressArbiterKey() == addr)) {
if ((tmp_num_waiters++) >= count) {
break;
}
}
if (tmp_num_waiters == 0) {
new_value = value + 1;
} else if (tmp_num_waiters <= count) {
if (tmp_num_waiters < count) {
new_value = value - 1;
} else {
new_value = value;
}
} else {
new_value = value + 1;
}
}

View File

@@ -132,7 +132,7 @@ namespace ams::kern {
can_access = cpu::CanAccessAtomic(address);
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);
}
}

View File

@@ -422,8 +422,8 @@ namespace ams::kern {
for (auto i = 0; i < static_cast<s32>(cpu::NumCores); ++i) {
if (thread == Kernel::GetScheduler(i).GetSchedulerCurrentThread()) {
current = true;
break;
}
break;
}
/* 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) {
if (thread == Kernel::GetScheduler(i).GetSchedulerCurrentThread()) {
current = true;
break;
}
break;
}
/* If the thread is current, retry until it isn't. */

View File

@@ -120,7 +120,7 @@ namespace ams::kern {
/* 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. */
R_TRY(m_table.Unmap(page_table, process_address, size, device_address));

View File

@@ -62,7 +62,7 @@ namespace ams::kern::KDumpObject {
const auto end = accessor.end();
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) {
/* Get the object + handle. */
ams::svc::Handle handle = ams::svc::InvalidHandle;
@@ -181,7 +181,7 @@ namespace ams::kern::KDumpObject {
const auto end = accessor.end();
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) {
/* Get the object + handle. */
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) {
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;
KScopedAutoObject cur_o = cur->GetHandleTable().GetObjectByIndex(std::addressof(cur_h), j);
if (cur_o.IsNotNull()) {
@@ -236,7 +236,7 @@ namespace ams::kern::KDumpObject {
{
for (auto it = accessor.begin(); it != end; ++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;
KScopedAutoObject cur_o = cur->GetHandleTable().GetObjectByIndex(std::addressof(cur_h), j);
if (cur_o.IsNull()) {

View File

@@ -804,7 +804,7 @@ namespace ams::kern {
/* Remove waiter thread. */
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);
}

View File

@@ -77,7 +77,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I.
.PHONY: clean all
.PHONY: clean all lib/$(TARGET).a
#---------------------------------------------------------------------------------
all: lib/$(TARGET).a

View File

@@ -164,6 +164,6 @@ namespace ams::fs {
static_assert(util::is_pod<HashSalt>::value);
static_assert(sizeof(HashSalt) == HashSalt::Size);
using SaveDataHashSalt = std::optional<HashSalt>;
using SaveDataHashSalt = util::optional<HashSalt>;
}

View File

@@ -54,7 +54,7 @@ namespace ams::fssrv::impl {
return m_list.size();
}
std::optional<fs::ProgramIndexMapInfo> Get(const ncm::ProgramId &program_id) const {
util::optional<fs::ProgramIndexMapInfo> Get(const ncm::ProgramId &program_id) const {
/* Acquire exclusive access to the map. */
std::scoped_lock lk(m_mutex);
@@ -134,9 +134,9 @@ namespace ams::fssrv::impl {
}
template<typename F>
std::optional<fs::ProgramIndexMapInfo> GetImpl(F f) const {
util::optional<fs::ProgramIndexMapInfo> GetImpl(F f) const {
/* Try to find an entry matching the predicate. */
std::optional<fs::ProgramIndexMapInfo> match = std::nullopt;
util::optional<fs::ProgramIndexMapInfo> match = util::nullopt;
for (const auto &entry : m_list) {
/* If the predicate matches, we want to return the relevant info. */

View File

@@ -92,7 +92,7 @@ namespace ams::fssrv::impl {
public:
bool IsDeepRetryEnabled() const;
bool IsAccessFailureDetectionObserved() const;
std::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
util::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
os::ReadWriteLock &GetReadWriteLockForCacheInvalidation();
public:
/* Command API. */

View File

@@ -44,7 +44,7 @@ namespace ams::fssrv::impl {
~StorageInterfaceAdapter();
private:
std::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
util::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
public:
/* Command API. */
Result Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size);

View File

@@ -34,9 +34,9 @@ namespace ams::fssystem {
virtual ~DirectoryRedirectionFileSystem();
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. */
return std::nullopt;
return util::nullopt;
}
private:
Result GetNormalizedDirectoryPath(char **out, size_t *out_size, const char *dir);

View File

@@ -33,9 +33,9 @@ namespace ams::fssystem {
virtual ~DirectorySaveDataFileSystem();
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. */
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:
Result AllocateWorkBuffer(std::unique_ptr<u8[]> *out, size_t *out_size, size_t ideal_size);

View File

@@ -107,7 +107,7 @@ namespace ams::fssystem {
class Sha256PartitionFileSystemMeta : public PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat> {
public:
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);
};
}

View File

@@ -32,9 +32,9 @@ namespace ams::fssystem {
virtual ~SubDirectoryFileSystem();
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. */
return std::nullopt;
return util::nullopt;
}
private:
Result Initialize(const char *bp);

View File

@@ -50,7 +50,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
@@ -58,7 +58,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
@@ -66,7 +66,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
@@ -74,7 +74,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
@@ -82,7 +82,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
@@ -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(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);
}
@@ -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(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);
}
@@ -110,7 +110,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
@@ -118,7 +118,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
@@ -126,12 +126,12 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
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();
}
@@ -139,7 +139,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
@@ -147,7 +147,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
@@ -155,7 +155,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
@@ -163,7 +163,7 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
@@ -171,23 +171,23 @@ namespace ams::fssystem::impl {
char full_path[fs::EntryNameLengthMax + 1];
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);
}
/* These aren't accessible as commands. */
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);
}
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();
}
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();
}
};

View File

@@ -57,8 +57,8 @@ namespace ams::kvdb {
public:
Result Initialize(void *buffer, size_t buffer_size, size_t capacity);
void Invalidate();
std::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> TryGet(void *out_value, size_t max_out_size, 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);
bool Contains(const void *key, size_t key_size);
};

View File

@@ -37,6 +37,6 @@ namespace ams::ncm {
void GetTicketFileStringFromRightsId(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);
}

View File

@@ -94,7 +94,7 @@ namespace ams::ncm {
StorageId storage_id;
SystemSaveDataInfo info;
sf::SharedPointer<IContentMetaDatabase> content_meta_database;
std::optional<kvdb::MemoryKeyValueStore<ContentMetaKey>> kvs;
util::optional<kvdb::MemoryKeyValueStore<ContentMetaKey>> kvs;
ContentMetaMemoryResource *memory_resource;
u32 max_content_metas;

View File

@@ -303,17 +303,17 @@ namespace ams::ncm {
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) {
case ContentMetaType::Application: return ApplicationId{ key.id };
case ContentMetaType::Patch: return this->GetExtendedHeader<PatchMetaExtendedHeader>()->application_id;
case ContentMetaType::AddOnContent: return this->GetExtendedHeader<AddOnContentMetaExtendedHeader>()->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());
}
};

View File

@@ -131,7 +131,7 @@ namespace ams::ncm {
protected:
Result Initialize(StorageId install_storage, InstallTaskDataBase *data, u32 config);
Result PrepareContentMeta(const InstallContentMetaInfo &meta_info, std::optional<ContentMetaKey> key, std::optional<u32> source_version);
Result PrepareContentMeta(const InstallContentMetaInfo &meta_info, util::optional<ContentMetaKey> key, util::optional<u32> source_version);
Result PrepareContentMeta(ContentId content_id, s64 size, ContentMetaType meta_type, AutoBuffer *buffer);
Result WritePlaceHolderBuffer(InstallContentInfo *content_info, const void *data, size_t data_size);
void PrepareAgain();
@@ -145,7 +145,7 @@ namespace ams::ncm {
Result PrepareSystemUpdateDependency();
virtual Result PrepareContentMetaIfLatest(const ContentMetaKey &key); /* NOTE: This is not virtual in Nintendo's code. We do so to facilitate downgrades. */
u32 GetConfig() const { return this->config; }
Result WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, std::optional<bool> is_temporary);
Result WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, util::optional<bool> is_temporary);
StorageId GetInstallStorage() const { return this->install_storage; }
@@ -164,7 +164,7 @@ namespace ams::ncm {
Result VerifyAllNotCommitted(const StorageContentMetaKey *keys, s32 num_keys);
virtual Result PrepareInstallContentMetaData() = 0;
virtual Result GetLatestVersion(std::optional<u32> *out_version, u64 id) { return ncm::ResultContentMetaNotFound(); }
virtual Result GetLatestVersion(util::optional<u32> *out_version, u64 id) { return ncm::ResultContentMetaNotFound(); }
virtual Result OnExecuteComplete() { return ResultSuccess(); }
@@ -187,9 +187,9 @@ namespace ams::ncm {
void StartThroughputMeasurement();
void UpdateThroughputMeasurement(s64 throughput);
Result GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, std::optional<u32> source_version);
Result GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, util::optional<u32> source_version);
InstallContentInfo MakeInstallContentInfoFrom(const InstallContentMetaInfo &info, const PlaceHolderId &placeholder_id, std::optional<bool> is_temporary);
InstallContentInfo MakeInstallContentInfoFrom(const InstallContentMetaInfo &info, const PlaceHolderId &placeholder_id, util::optional<bool> is_temporary);
Result ReadContentMetaInfoList(s32 *out_count, std::unique_ptr<ContentMetaInfo[]> *out_meta_infos, const ContentMetaKey &key);
Result ListRightsIdsByInstallContentMeta(s32 *out_count, Span<RightsId> out_span, const InstallContentMeta &content_meta, s32 offset);

View File

@@ -31,7 +31,7 @@ namespace ams::ncm {
void Inactivate();
Result Initialize(const char *package_root, const char *context_path, void *buffer, size_t buffer_size, bool requires_exfat_driver, FirmwareVariationId firmware_variation_id);
std::optional<ContentMetaKey> GetSystemUpdateMetaKey();
util::optional<ContentMetaKey> GetSystemUpdateMetaKey();
protected:
virtual Result PrepareInstallContentMetaData() override;
virtual Result GetInstallContentMetaInfo(InstallContentMetaInfo *out, const ContentMetaKey &key) override;

View File

@@ -223,17 +223,18 @@ namespace ams::spl {
Package2Hash = 17,
/* Extension config items for exosphere. */
ExosphereApiVersion = 65000,
ExosphereNeedsReboot = 65001,
ExosphereNeedsShutdown = 65002,
ExosphereGitCommitHash = 65003,
ExosphereHasRcmBugPatch = 65004,
ExosphereBlankProdInfo = 65005,
ExosphereAllowCalWrites = 65006,
ExosphereEmummcType = 65007,
ExospherePayloadAddress = 65008,
ExosphereLogConfiguration = 65009,
ExosphereForceEnableUsb30 = 65010,
ExosphereApiVersion = 65000,
ExosphereNeedsReboot = 65001,
ExosphereNeedsShutdown = 65002,
ExosphereGitCommitHash = 65003,
ExosphereHasRcmBugPatch = 65004,
ExosphereBlankProdInfo = 65005,
ExosphereAllowCalWrites = 65006,
ExosphereEmummcType = 65007,
ExospherePayloadAddress = 65008,
ExosphereLogConfiguration = 65009,
ExosphereForceEnableUsb30 = 65010,
ExosphereSupportedHosVersion = 65011,
};
}

View File

@@ -38,8 +38,8 @@ namespace ams::capsrv::server {
/* Destroy the server. */
os::FinalizeEvent(std::addressof(this->idle_event));
this->server_manager_holder = std::nullopt;
this->service_holder = std::nullopt;
this->server_manager_holder = util::nullopt;
this->service_holder = util::nullopt;
}
void DecoderControlServerManager::StartServer() {

View File

@@ -31,8 +31,8 @@ namespace ams::capsrv::server {
using ServerOptions = sf::hipc::DefaultServerManagerOptions;
using ServerManager = sf::hipc::ServerManager<NumServers, ServerOptions, MaxSessions>;
private:
std::optional<ServiceHolderType> service_holder;
std::optional<ServerManager> server_manager_holder;
util::optional<ServiceHolderType> service_holder;
util::optional<ServerManager> server_manager_holder;
os::EventType idle_event;
public:
constexpr DecoderControlServerManager() : service_holder(), server_manager_holder(), idle_event{} { /* ... */ }

View File

@@ -74,6 +74,10 @@ Result dmntchtResumeCheatProcess(void) {
return _dmntchtCmdVoid(&g_dmntchtSrv, 65005);
}
Result dmntchtForceCloseCheatProcess(void) {
return _dmntchtCmdVoid(&g_dmntchtSrv, 65006);
}
static Result _dmntchtGetCount(u64 *out_count, u32 cmd_id) {
return serviceDispatchOut(&g_dmntchtSrv, cmd_id, *out_count);
}
@@ -171,6 +175,13 @@ Result dmntchtResetStaticRegisters() {
return _dmntchtCmdVoid(&g_dmntchtSrv, 65208);
}
Result dmntchtSetMasterCheat(DmntCheatDefinition *cheat_def) {
return serviceDispatch(&g_dmntchtSrv, 65209,
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias | SfBufferAttr_FixedSize },
.buffers = { { cheat_def, sizeof(*cheat_def) } },
);
}
Result dmntchtGetFrozenAddressCount(u64 *out_count) {
return _dmntchtGetCount(out_count, 65300);
}

View File

@@ -66,6 +66,7 @@ Result dmntchtHasCheatProcess(bool *out);
Result dmntchtGetCheatProcessEvent(Event *event);
Result dmntchtGetCheatProcessMetadata(DmntCheatProcessMetadata *out_metadata);
Result dmntchtForceOpenCheatProcess(void);
Result dmntchtForceCloseCheatProcess(void);
Result dmntchtGetCheatProcessMappingCount(u64 *out_count);
Result dmntchtGetCheatProcessMappings(MemoryInfo *buffer, u64 max_count, u64 offset, u64 *out_count);
@@ -84,6 +85,7 @@ Result dmntchtRemoveCheat(u32 cheat_id);
Result dmntchtReadStaticRegister(u64 *out, u8 which);
Result dmntchtWriteStaticRegister(u8 which, u64 value);
Result dmntchtResetStaticRegisters();
Result dmntchtSetMasterCheat(DmntCheatDefinition *cheat);
Result dmntchtGetFrozenAddressCount(u64 *out_count);
Result dmntchtGetFrozenAddresses(DmntFrozenAddressEntry *buffer, u64 max_count, u64 offset, u64 *out_count);

View File

@@ -26,10 +26,10 @@ namespace ams::erpt::srv {
constinit char Reporter::s_serial_number[24] = "Unknown";
constinit char Reporter::s_os_version[24] = "Unknown";
constinit char Reporter::s_private_os_version[96] = "Unknown";
constinit std::optional<os::Tick> Reporter::s_application_launch_time;
constinit std::optional<os::Tick> Reporter::s_awake_time;
constinit std::optional<os::Tick> Reporter::s_power_on_time;
constinit std::optional<time::SteadyClockTimePoint> Reporter::s_initial_launch_settings_completion_time;
constinit util::optional<os::Tick> Reporter::s_application_launch_time;
constinit util::optional<os::Tick> Reporter::s_awake_time;
constinit util::optional<os::Tick> Reporter::s_power_on_time;
constinit util::optional<time::SteadyClockTimePoint> Reporter::s_initial_launch_settings_completion_time;
namespace {
@@ -78,13 +78,13 @@ namespace ams::erpt::srv {
entry->suspended_duration = suspended_duration;
}
std::optional<TimeSpan> GetActiveDuration(ncm::ProgramId program_id) const {
util::optional<TimeSpan> GetActiveDuration(ncm::ProgramId program_id) const {
/* Try to find a matching entry. */
const auto entry = util::range::find_if(m_list, [&](const AppletActiveTimeInfo &info) { return info.program_id == program_id; });
if (entry != m_list.end()) {
return (os::GetSystemTick() - entry->register_tick).ToTimeSpan() - entry->suspended_duration;
} else {
return std::nullopt;
return util::nullopt;
}
}
};

View File

@@ -25,13 +25,13 @@ namespace ams::erpt::srv {
static char s_serial_number[24];
static char s_os_version[24];
static char s_private_os_version[96];
static std::optional<os::Tick> s_application_launch_time;
static std::optional<os::Tick> s_awake_time;
static std::optional<os::Tick> s_power_on_time;
static std::optional<time::SteadyClockTimePoint> s_initial_launch_settings_completion_time;
static util::optional<os::Tick> s_application_launch_time;
static util::optional<os::Tick> s_awake_time;
static util::optional<os::Tick> s_power_on_time;
static util::optional<time::SteadyClockTimePoint> s_initial_launch_settings_completion_time;
public:
static void ClearApplicationLaunchTime() { s_application_launch_time = std::nullopt; }
static void ClearInitialLaunchSettingsCompletionTime() { s_initial_launch_settings_completion_time = std::nullopt; }
static void ClearApplicationLaunchTime() { s_application_launch_time = util::nullopt; }
static void ClearInitialLaunchSettingsCompletionTime() { s_initial_launch_settings_completion_time = util::nullopt; }
static void SetInitialLaunchSettingsCompletionTime(const time::SteadyClockTimePoint &time) { s_initial_launch_settings_completion_time = time; }

View File

@@ -238,7 +238,7 @@ namespace ams::fs {
class SdCardRedirectionCodeFileSystem : public OpenFileOnlyFileSystem {
private:
std::optional<ReadOnlyFileSystem> sd_content_fs;
util::optional<ReadOnlyFileSystem> sd_content_fs;
ReadOnlyFileSystem code_fs;
bool is_redirect;
public:
@@ -303,8 +303,8 @@ namespace ams::fs {
class AtmosphereCodeFileSystem : public OpenFileOnlyFileSystem {
private:
std::optional<SdCardRedirectionCodeFileSystem> code_fs;
std::optional<ReadOnlyFileSystem> hbl_fs;
util::optional<SdCardRedirectionCodeFileSystem> code_fs;
util::optional<ReadOnlyFileSystem> hbl_fs;
ncm::ProgramId program_id;
bool initialized;
public:

View File

@@ -154,8 +154,8 @@ namespace ams::fssrv::impl {
AMS_ABORT_UNLESS(false);
}
std::optional<std::shared_lock<os::ReadWriteLock>> FileSystemInterfaceAdapter::AcquireCacheInvalidationReadLock() {
std::optional<std::shared_lock<os::ReadWriteLock>> lock;
util::optional<std::shared_lock<os::ReadWriteLock>> FileSystemInterfaceAdapter::AcquireCacheInvalidationReadLock() {
util::optional<std::shared_lock<os::ReadWriteLock>> lock;
if (this->deep_retry_enabled) {
lock.emplace(this->invalidation_lock);
}

View File

@@ -34,8 +34,8 @@ namespace ams::fssrv::impl {
/* ... */
}
std::optional<std::shared_lock<os::ReadWriteLock>> StorageInterfaceAdapter::AcquireCacheInvalidationReadLock() {
std::optional<std::shared_lock<os::ReadWriteLock>> lock;
util::optional<std::shared_lock<os::ReadWriteLock>> StorageInterfaceAdapter::AcquireCacheInvalidationReadLock() {
util::optional<std::shared_lock<os::ReadWriteLock>> lock;
if (this->deep_retry_enabled) {
lock.emplace(this->invalidation_lock);
}

View File

@@ -113,7 +113,7 @@ namespace ams::fssystem {
constexpr inline s32 KeySlotCacheEntryCount = 3;
KeySlotCache g_key_slot_cache;
std::optional<KeySlotCacheEntry> g_key_slot_cache_entry[KeySlotCacheEntryCount];
util::optional<KeySlotCacheEntry> g_key_slot_cache_entry[KeySlotCacheEntryCount];
spl::AccessKey &GetNcaKekAccessKey(s32 key_type) {
static spl::AccessKey s_nca_kek_access_key_array[KeyAreaEncryptionKeyCount] = {};

View File

@@ -162,7 +162,7 @@ namespace ams::fssystem {
template class PartitionFileSystemMetaCore<impl::PartitionFileSystemFormat>;
template class PartitionFileSystemMetaCore<impl::Sha256PartitionFileSystemFormat>;
Result Sha256PartitionFileSystemMeta::Initialize(fs::IStorage *base_storage, MemoryResource *allocator, const void *hash, size_t hash_size, std::optional<u8> suffix) {
Result Sha256PartitionFileSystemMeta::Initialize(fs::IStorage *base_storage, MemoryResource *allocator, const void *hash, size_t hash_size, util::optional<u8> suffix) {
/* Ensure preconditions. */
R_UNLESS(hash_size == crypto::Sha256Generator::HashSize, fs::ResultPreconditionViolation());

View File

@@ -59,7 +59,7 @@ namespace ams::htclow::driver {
std::scoped_lock lk(m_mutex);
/* Clear our driver type. */
m_driver_type = std::nullopt;
m_driver_type = util::nullopt;
/* Close our driver. */
if (m_open_driver != nullptr) {

View File

@@ -23,7 +23,7 @@ namespace ams::htclow::driver {
class DriverManager {
private:
std::optional<htclow::impl::DriverType> m_driver_type{};
util::optional<htclow::impl::DriverType> m_driver_type{};
IDriver *m_debug_driver{};
SocketDriver m_socket_driver;
UsbDriver m_usb_driver{};

View File

@@ -47,7 +47,7 @@ namespace ams::htclow::mux {
u64 m_total_send_size;
u64 m_cur_max_data;
u64 m_prev_max_data;
std::optional<u64> m_share;
util::optional<u64> m_share;
os::Event m_state_change_event;
ChannelState m_state;
public:

View File

@@ -55,9 +55,9 @@ namespace ams::kvdb {
AMS_ABORT_UNLESS(this->entries != nullptr);
}
std::optional<size_t> FileKeyValueStore::Cache::TryGet(void *out_value, size_t max_out_size, const void *key, size_t key_size) {
util::optional<size_t> FileKeyValueStore::Cache::TryGet(void *out_value, size_t max_out_size, const void *key, size_t key_size) {
if (!this->HasEntries()) {
return std::nullopt;
return util::nullopt;
}
/* Try to find the entry. */
@@ -66,7 +66,7 @@ namespace ams::kvdb {
if (entry.key_size == key_size && std::memcmp(entry.key, key, key_size) == 0) {
/* If we don't have enough space, fail to read from cache. */
if (max_out_size < entry.value_size) {
return std::nullopt;
return util::nullopt;
}
std::memcpy(out_value, entry.value, entry.value_size);
@@ -74,12 +74,12 @@ namespace ams::kvdb {
}
}
return std::nullopt;
return util::nullopt;
}
std::optional<size_t> FileKeyValueStore::Cache::TryGetSize(const void *key, size_t key_size) {
util::optional<size_t> FileKeyValueStore::Cache::TryGetSize(const void *key, size_t key_size) {
if (!this->HasEntries()) {
return std::nullopt;
return util::nullopt;
}
/* Try to find the entry. */
@@ -90,7 +90,7 @@ namespace ams::kvdb {
}
}
return std::nullopt;
return util::nullopt;
}
void FileKeyValueStore::Cache::Set(const void *key, size_t key_size, const void *value, size_t value_size) {

View File

@@ -78,13 +78,13 @@ namespace ams::ncm {
util::SNPrintf(dst, dst_size, "%s.cert", str.data);
}
std::optional<ContentId> GetContentIdFromString(const char *str, size_t len) {
util::optional<ContentId> GetContentIdFromString(const char *str, size_t len) {
if (len < ContentIdStringLength) {
return std::nullopt;
return util::nullopt;
}
ContentId content_id;
return GetBytesFromString(std::addressof(content_id), sizeof(content_id), str, ContentIdStringLength) ? std::optional<ContentId>(content_id) : std::nullopt;
return GetBytesFromString(std::addressof(content_id), sizeof(content_id), str, ContentIdStringLength) ? util::optional<ContentId>(content_id) : util::nullopt;
}
}

View File

@@ -225,7 +225,7 @@ namespace ams::ncm {
out->max_content_metas = max_content_metas;
out->memory_resource = memory_resource;
out->content_meta_database = nullptr;
out->kvs = std::nullopt;
out->kvs = util::nullopt;
/* Create a new mount name and copy it to out. */
std::strcpy(out->mount_name, impl::CreateUniqueMountName().str);
@@ -240,7 +240,7 @@ namespace ams::ncm {
out->max_content_metas = max_content_metas;
out->memory_resource = memory_resource;
out->content_meta_database = nullptr;
out->kvs = std::nullopt;
out->kvs = util::nullopt;
return ResultSuccess();
}
@@ -649,7 +649,7 @@ namespace ams::ncm {
/* N doesn't bother checking the result of this */
root->content_meta_database->DisableForcibly();
root->content_meta_database = nullptr;
root->kvs = std::nullopt;
root->kvs = util::nullopt;
/* Also unmount, except in the case of game cards. */
if (storage_id != StorageId::GameCard) {

View File

@@ -18,7 +18,7 @@
namespace ams::ncm {
Result ContentMetaDatabaseImpl::GetContentIdImpl(ContentId *out, const ContentMetaKey &key, ContentType type, std::optional<u8> id_offset) const {
Result ContentMetaDatabaseImpl::GetContentIdImpl(ContentId *out, const ContentMetaKey &key, ContentType type, util::optional<u8> id_offset) const {
R_TRY(this->EnsureEnabled());
/* Find the meta key. */
@@ -78,7 +78,7 @@ namespace ams::ncm {
}
Result ContentMetaDatabaseImpl::GetContentIdByType(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type) {
return this->GetContentIdImpl(out_content_id.GetPointer(), key, type, std::nullopt);
return this->GetContentIdImpl(out_content_id.GetPointer(), key, type, util::nullopt);
}
Result ContentMetaDatabaseImpl::ListContentInfo(sf::Out<s32> out_count, const sf::OutArray<ContentInfo> &out_info, const ContentMetaKey &key, s32 offset) {
@@ -149,7 +149,7 @@ namespace ams::ncm {
Result ContentMetaDatabaseImpl::GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, u64 id) {
R_TRY(this->EnsureEnabled());
std::optional<ContentMetaKey> found_key = std::nullopt;
util::optional<ContentMetaKey> found_key = util::nullopt;
/* Find the last key with the desired program id. */
for (auto entry = this->kvs->lower_bound(ContentMetaKey::MakeUnknownType(id, 0)); entry != this->kvs->end(); entry++) {
@@ -308,15 +308,15 @@ namespace ams::ncm {
out_orphaned[i] = true;
}
auto IsOrphanedContent = [] ALWAYS_INLINE_LAMBDA (const sf::InArray<ContentId> &list, const ncm::ContentId &id) -> std::optional<size_t> {
auto IsOrphanedContent = [] ALWAYS_INLINE_LAMBDA (const sf::InArray<ContentId> &list, const ncm::ContentId &id) -> util::optional<size_t> {
/* Check if any input content ids match our found content id. */
for (size_t i = 0; i < list.GetSize(); i++) {
if (list[i] == id) {
return std::make_optional(i);
return util::make_optional(i);
}
}
return std::nullopt;
return util::nullopt;
};
/* Iterate over all entries. */
@@ -435,7 +435,7 @@ namespace ams::ncm {
}
Result ContentMetaDatabaseImpl::GetContentIdByTypeAndIdOffset(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type, u8 id_offset) {
return this->GetContentIdImpl(out_content_id.GetPointer(), key, type, std::make_optional(id_offset));
return this->GetContentIdImpl(out_content_id.GetPointer(), key, type, util::make_optional(id_offset));
}
Result ContentMetaDatabaseImpl::GetCount(sf::Out<u32> out_count) {

View File

@@ -25,7 +25,7 @@ namespace ams::ncm {
ContentMetaDatabaseImpl(ContentMetaKeyValueStore *kvs) : ContentMetaDatabaseImplBase(kvs) { /* ... */ }
private:
/* Helpers. */
Result GetContentIdImpl(ContentId *out, const ContentMetaKey &key, ContentType type, std::optional<u8> id_offset) const;
Result GetContentIdImpl(ContentId *out, const ContentMetaKey &key, ContentType type, util::optional<u8> id_offset) const;
public:
/* Actual commands. */
virtual Result Set(const ContentMetaKey &key, const sf::InBuffer &value) override;

View File

@@ -116,7 +116,7 @@ namespace ams::ncm {
R_UNLESS(reader.GetExtendedDataSize() != 0, ReadMetaInfoListFromBase());
SystemUpdateMetaExtendedDataReader extended_data_reader(reader.GetExtendedData(), reader.GetExtendedDataSize());
std::optional<s32> firmware_variation_index = std::nullopt;
util::optional<s32> firmware_variation_index = util::nullopt;
/* NOTE: Atmosphere extension to support downgrading. */
/* If all firmware variations refer to base, don't require the current variation be present. */

View File

@@ -208,7 +208,7 @@ namespace ams::ncm {
return this->OpenCurrentDirectory();
}
Result ContentStorageImpl::ContentIterator::GetNext(std::optional<fs::DirectoryEntry> *out) {
Result ContentStorageImpl::ContentIterator::GetNext(util::optional<fs::DirectoryEntry> *out) {
/* Iterate until we get the next entry. */
while (true) {
/* Ensure that we have entries loaded. */
@@ -216,7 +216,7 @@ namespace ams::ncm {
/* If we failed to load any entries, there's nothing to get. */
if (this->entry_count <= 0) {
*out = std::nullopt;
*out = util::nullopt;
return ResultSuccess();
}
@@ -353,7 +353,7 @@ namespace ams::ncm {
fs::CloseFile(this->cached_file_handle);
this->cached_content_id = InvalidContentId;
}
this->content_iterator = std::nullopt;
this->content_iterator = util::nullopt;
}
Result ContentStorageImpl::OpenContentIdFile(ContentId content_id) {
@@ -586,7 +586,7 @@ namespace ams::ncm {
/* Advance to the desired offset. */
for (auto current_offset = 0; current_offset < offset; /* ... */) {
/* Get the next directory entry. */
std::optional<fs::DirectoryEntry> dir_entry;
util::optional<fs::DirectoryEntry> dir_entry;
R_TRY(this->content_iterator->GetNext(std::addressof(dir_entry)));
/* If we run out of entries before reaching the desired offset, we're done. */
@@ -606,7 +606,7 @@ namespace ams::ncm {
s32 count = 0;
while (count < static_cast<s32>(out.GetSize())) {
/* Get the next directory entry. */
std::optional<fs::DirectoryEntry> dir_entry;
util::optional<fs::DirectoryEntry> dir_entry;
R_TRY(this->content_iterator->GetNext(std::addressof(dir_entry)));
/* Don't continue if the directory entry is absent. */

View File

@@ -42,7 +42,7 @@ namespace ams::ncm {
~ContentIterator();
Result Initialize(const char *root_path, size_t max_depth);
Result GetNext(std::optional<fs::DirectoryEntry> *out);
Result GetNext(util::optional<fs::DirectoryEntry> *out);
private:
Result OpenCurrentDirectory();
Result OpenDirectory(const char *dir);
@@ -53,14 +53,14 @@ namespace ams::ncm {
ContentId cached_content_id;
fs::FileHandle cached_file_handle;
RightsIdCache *rights_id_cache;
std::optional<ContentIterator> content_iterator;
std::optional<s32> last_content_offset;
util::optional<ContentIterator> content_iterator;
util::optional<s32> last_content_offset;
public:
static Result InitializeBase(const char *root_path);
static Result CleanupBase(const char *root_path);
static Result VerifyBase(const char *root_path);
public:
ContentStorageImpl() : placeholder_accessor(), cached_content_id(InvalidContentId), cached_file_handle(), rights_id_cache(nullptr), content_iterator(std::nullopt), last_content_offset(std::nullopt) { /* ... */ }
ContentStorageImpl() : placeholder_accessor(), cached_content_id(InvalidContentId), cached_file_handle(), rights_id_cache(nullptr), content_iterator(util::nullopt), last_content_offset(util::nullopt) { /* ... */ }
~ContentStorageImpl();
Result Initialize(const char *root_path, MakeContentPathFunction content_path_func, MakePlaceHolderPathFunction placeholder_path_func, bool delay_flush, RightsIdCache *rights_id_cache);

View File

@@ -87,8 +87,8 @@ namespace ams::ncm {
R_TRY(this->CountInstallContentMetaData(std::addressof(count)));
/* Iterate over content meta. */
std::optional<PlaceHolderId> placeholder_id;
std::optional<StorageId> storage_id;
util::optional<PlaceHolderId> placeholder_id;
util::optional<StorageId> storage_id;
for (s32 i = 0; i < count; i++) {
/* Obtain the content meta. */
InstallContentMeta content_meta;
@@ -716,7 +716,7 @@ namespace ams::ncm {
return ResultSuccess();
}
Result InstallTaskBase::WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, std::optional<bool> is_temporary) {
Result InstallTaskBase::WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, util::optional<bool> is_temporary) {
/* Generate a placeholder id. */
auto placeholder_id = storage->GeneratePlaceHolderId();
@@ -736,14 +736,14 @@ namespace ams::ncm {
return ResultSuccess();
}
Result InstallTaskBase::PrepareContentMeta(const InstallContentMetaInfo &meta_info, std::optional<ContentMetaKey> expected_key, std::optional<u32> source_version) {
Result InstallTaskBase::PrepareContentMeta(const InstallContentMetaInfo &meta_info, util::optional<ContentMetaKey> expected_key, util::optional<u32> source_version) {
/* Open the BuiltInSystem content storage. */
ContentStorage content_storage;
R_TRY(OpenContentStorage(&content_storage, StorageId::BuiltInSystem));
/* Write content meta to a placeholder. */
InstallContentInfo content_info;
R_TRY(this->WriteContentMetaToPlaceHolder(std::addressof(content_info), std::addressof(content_storage), meta_info, std::nullopt));
R_TRY(this->WriteContentMetaToPlaceHolder(std::addressof(content_info), std::addressof(content_storage), meta_info, util::nullopt));
/* Get the path of the placeholder. */
Path path;
@@ -929,7 +929,7 @@ namespace ams::ncm {
/* Get and prepare install content meta info. */
InstallContentMetaInfo install_content_meta_info;
R_TRY(this->GetInstallContentMetaInfo(std::addressof(install_content_meta_info), key));
R_TRY(this->PrepareContentMeta(install_content_meta_info, key, std::nullopt));
R_TRY(this->PrepareContentMeta(install_content_meta_info, key, util::nullopt));
}
return ResultSuccess();
@@ -997,7 +997,7 @@ namespace ams::ncm {
return this->data->Delete(keys, num_keys);
}
Result InstallTaskBase::GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, std::optional<u32> source_version) {
Result InstallTaskBase::GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, util::optional<u32> source_version) {
AutoBuffer meta;
{
fs::ScopedAutoAbortDisabler aad;
@@ -1027,7 +1027,7 @@ namespace ams::ncm {
return ResultSuccess();
}
InstallContentInfo InstallTaskBase::MakeInstallContentInfoFrom(const InstallContentMetaInfo &info, const PlaceHolderId &placeholder_id, std::optional<bool> is_tmp) {
InstallContentInfo InstallTaskBase::MakeInstallContentInfoFrom(const InstallContentMetaInfo &info, const PlaceHolderId &placeholder_id, util::optional<bool> is_tmp) {
return {
.digest = info.digest,
.info = ContentInfo::Make(info.content_id, info.content_size, ContentType::Meta, 0),

View File

@@ -67,7 +67,7 @@ namespace ams::ncm {
Result OnMemoryContentMetaDatabaseImpl::GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, u64 id) {
R_TRY(this->EnsureEnabled());
std::optional<ContentMetaKey> found_key = std::nullopt;
util::optional<ContentMetaKey> found_key = util::nullopt;
/* Find the last key with the desired program id. */
for (auto entry = this->kvs->lower_bound(ContentMetaKey::MakeUnknownType(id, 0)); entry != this->kvs->end(); entry++) {

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