mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-04-22 04:24:48 +00:00
commit
05e2b5fd42
29 changed files with 1185 additions and 127 deletions
45
README.md
45
README.md
|
@ -2,51 +2,36 @@
|
|||

|
||||
=====
|
||||
|
||||

|
||||
[](https://discordapp.com/invite/ZdqEhed)
|
||||
|
||||
Atmosphère is a work-in-progress customized firmware for the Nintendo Switch.
|
||||
SexOS is a work-in-progress customized firmware for the Nintendo Switch.
|
||||
|
||||
Components
|
||||
=====
|
||||
|
||||
Atmosphère consists of multiple components, each of which replaces/modifies a different component of the system:
|
||||
SexOS consists of multiple components, each of which replaces/modifies a different component of the system:
|
||||
|
||||
* Fusée: First-stage Loader, responsible for loading and validating stage 2 (custom TrustZone) plus package2 (Kernel/FIRM sysmodules), and patching them as needed. This replaces all functionality normally in Package1loader/NX Bootloader.
|
||||
* Sept: Payload used to enable support for runtime key derivation on 7.0.0.
|
||||
* Exosphère: Customized TrustZone, to run a customized Secure Monitor
|
||||
* Thermosphère: EL2 EmuNAND support, i.e. backing up and using virtualized/redirected NAND images
|
||||
* Stratosphère: Custom Sysmodule(s), both Rosalina style to extend the kernel/provide new features, and of the loader reimplementation style to hook important system actions
|
||||
* Troposphère: Application-level Horizon OS patches, used to implement desirable CFW features
|
||||
* Sexy: First-stage Loader, responsible for loading and validating stage 2 Sex plus some operating system stuff (sysmodules), and patching them as needed. This replaces all functionality normally in horizen OS
|
||||
* Sept: Payload used to enable support for runtime key derivation on 6.9.420.
|
||||
* Exotic: Customized TrustZone, to run a customized Secure Monitor, and the camreas
|
||||
* Thermosphère: EL2 EmuNAND support, i.e. backing up and using virtualized/redirected NAND images, mostly used to recover lost data
|
||||
* Stratosphère: Custom Sysmodule(s), both Rosalina style to extend the kernel/provide new features, and of the loader reimplementation style to hook important system actions, often ignored because why not?
|
||||
* Tropo: Application-level Horizon OS patches, used to implement desirable CFW features, such as IR camrea filming, customised FTP server to only send images over WAN network acsess, and turn on incognito for later use
|
||||
|
||||
Licensing
|
||||
=====
|
||||
|
||||
This software is licensed under the terms of the GPLv2, with exemptions for specific projects noted below.
|
||||
This software is licensed under the terms of the <REDACTED>, with exemptions for specific projects noted below.
|
||||
|
||||
You can find a copy of the license in the [LICENSE file](LICENSE).
|
||||
|
||||
Exemptions:
|
||||
* The [yuzu Nintendo Switch emulator](https://github.com/yuzu-emu/yuzu) and the [Ryujinx Team and Contributors](https://github.com/orgs/Ryujinx) are exempt from GPLv2 licensing. They are permitted, each at their individual discretion, to instead license any source code authored for the Atmosphère project as either GPLv2 or later or the [MIT license](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/licensing_exemptions/MIT_LICENSE). In doing so, they may alter, supplement, or entirely remove the copyright notice for each file they choose to relicense. Neither the Atmosphère project nor its individual contributors shall assert their moral rights against any of the aforementioned projects.
|
||||
* [Nintendo](https://github.com/Nintendo) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the Atmosphère project under the Zero-Clause BSD license.
|
||||
|
||||
* The [yuzu Nintendo Switch emulator](https://github.com/yuzu-emu/yuzu) and the [Ryujinx Team and Contributors](https://github.com/orgs/Ryujinx) are exempt from GPLv2 licensing. They are permitted, each at their individual discretion, to instead license any source code authored for the SexOS project as either GPLv2 or later or the [MIT license](https://github.com/SexOS-NX/SexOS/blob/master/docs/licensing_exemptions/MIT_LICENSE). In doing so, they may alter, supplement, or entirely remove the copyright notice for each file they choose to relicense. Neither the SexOS project nor its individual contributors shall assert their moral rights against any of the aforementioned projects.
|
||||
* [Nintendo](https://github.com/Nintendo) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the SexOS project under the Zero-Clause BSD license.
|
||||
* The [Pornhub Switch Port] (https://pornhub.com/switch), is exempt from all licensing and must have full access to both the source code, and your system at all times
|
||||
Credits
|
||||
=====
|
||||
|
||||
Atmosphère is currently being developed and maintained by __SciresM__, __TuxSH__, __hexkyz__, and __fincs__.<br>
|
||||
SexOS is currently being developed and maintained by __IVy-The-Wusky__ And __Grass0001__.<br>
|
||||
In no particular order, we credit the following for their invaluable contributions:
|
||||
|
||||
* __switchbrew__ for the [libnx](https://github.com/switchbrew/libnx) project and the extensive [documentation, research and tool development](http://switchbrew.org) pertaining to the Nintendo Switch.
|
||||
* __devkitPro__ for the [devkitA64](https://devkitpro.org/) toolchain and libnx support.
|
||||
* __ReSwitched Team__ for additional [documentation, research and tool development](https://reswitched.team/) pertaining to the Nintendo Switch.
|
||||
* __ChaN__ for the [FatFs](http://elm-chan.org/fsw/ff/00index_e.html) module.
|
||||
* __Marcus Geelnard__ for the [bcl-1.2.0](https://sourceforge.net/projects/bcl/files/bcl/bcl-1.2.0) library.
|
||||
* __naehrwert__ and __st4rk__ for the original [hekate](https://github.com/nwert/hekate) project and its hwinit code base.
|
||||
* __CTCaer__ for the continued [hekate](https://github.com/CTCaer/hekate) project's fork and the [minerva_tc](https://github.com/CTCaer/minerva_tc) project.
|
||||
* __m4xw__ for development of the [emuMMC](https://github.com/m4xw/emummc) project.
|
||||
* __Riley__ for suggesting "Atmosphere" as a Horizon OS reimplementation+customization project name.
|
||||
* __hedgeberg__ for research and hardware testing.
|
||||
* __lioncash__ for code cleanup and general improvements.
|
||||
* __jaames__ for designing and providing Atmosphère's graphical resources.
|
||||
* Everyone who submitted entries for Atmosphère's [splash design contest](https://github.com/Atmosphere-NX/Atmosphere-splashes).
|
||||
* _All those who actively contribute to the Atmosphère repository._
|
||||
* Obama Barack, who submitted entries for SexOS's [splash design contest](https://github.com/SexOS-NX/SexOS-splashes).
|
||||
* _All those who actively contribute to the SexOS repository._
|
||||
|
|
|
@ -10,3 +10,4 @@ stage2_entrypoint = 0xF0000000
|
|||
; To force-disable nogc, add nogc = 0
|
||||
|
||||
; To opt in to using Atmosphere's NCM reimplementation, add enable_ncm = 1
|
||||
enable_SEXOS = 1
|
|
@ -1,45 +1 @@
|
|||
# Key: debugmode, default: 1.
|
||||
# Desc: Controls whether kernel is debug mode.
|
||||
# Disabling this may break Atmosphere's debugger in a future release.
|
||||
|
||||
# Key: debugmode_user, default: 0.
|
||||
# Desc: Controls whether userland is debug mode.
|
||||
|
||||
# Key: disable_user_exception_handlers, default: 0.
|
||||
# Desc: Controls whether user exception handlers are executed on error.
|
||||
# NOTE: This will cause atmosphere to not fail gracefully.
|
||||
# Support may not be provided to users tho disable these.
|
||||
# If you do not know what you are doing, leave them on.
|
||||
|
||||
# Key: enable_user_pmu_access, default: 0.
|
||||
# Desc: Controls whether userland has access to the PMU registers.
|
||||
# NOTE: It is unknown what effects this has on official code.
|
||||
|
||||
# Key: blank_prodinfo_sysmmc, default: 0.
|
||||
# Desc: Controls whether PRODINFO should be blanked in sysmmc.
|
||||
# This will cause the system to see dummied out keys and
|
||||
# serial number information.
|
||||
# NOTE: This is not known to be safe, as data may be
|
||||
# cached elsewhere in the system. Usage is not encouraged.
|
||||
|
||||
# Key: blank_prodinfo_emummc, default: 0.
|
||||
# Desc: Controls whether PRODINFO should be blanked in emummc.
|
||||
# NOTE: This is not known to be safe, as data may be
|
||||
# cached elsewhere in the system. Usage is not encouraged.
|
||||
|
||||
# Key: allow_writing_to_cal_sysmmc, default: 0.
|
||||
# Desc: Controls whether PRODINFO can be written by homebrew in sysmmc.
|
||||
# NOTE: Usage of this setting is strongly discouraged without
|
||||
# a safe backup elsewhere. Turning this on will also cause Atmosphere
|
||||
# to ensure a safe backup of calibration data is stored in unused
|
||||
# mmc space, encrypted to prevent detection. This backup can be used
|
||||
# to prevent unrecoverable edits in emergencies.
|
||||
|
||||
[exosphere]
|
||||
debugmode=1
|
||||
debugmode_user=0
|
||||
disable_user_exception_handlers=0
|
||||
enable_user_pmu_access=0
|
||||
blank_prodinfo_sysmmc=0
|
||||
blank_prodinfo_emummc=0
|
||||
allow_writing_to_cal_sysmmc=0
|
||||
we dont need no exosphere, we have exotic:tm:
|
|
@ -1,12 +1,12 @@
|
|||
; Disable uploading error reports to Nintendo
|
||||
; Disable uploading error reports to Pornhub
|
||||
[eupld]
|
||||
; upload_enabled = u8!0x0
|
||||
; Control whether RO should ease its validation of NROs.
|
||||
; (note: this is normally not necessary, and ips patches can be used.)
|
||||
[ro]
|
||||
; ease_nro_restriction = u8!0x1
|
||||
; Atmosphere custom settings
|
||||
[atmosphere]
|
||||
; SexOS custom settings
|
||||
[SexOS]
|
||||
; Reboot from fatal automatically after some number of milliseconds.
|
||||
; If field is not present or 0, fatal will wait indefinitely for user input.
|
||||
; fatal_auto_reboot_interval = u64!0x0
|
||||
|
@ -36,7 +36,7 @@
|
|||
; to fix compatibility with old homebrew.
|
||||
; 0 = Do not enable, 1 = Enable.
|
||||
; Please note this setting may be removed in a
|
||||
; future release of Atmosphere.
|
||||
; future release of SexOS.
|
||||
; enable_deprecated_hid_mitm = u8!0x0
|
||||
[hbloader]
|
||||
; Controls the size of the homebrew heap when running as applet.
|
||||
|
|
18
docs/main.md
18
docs/main.md
|
@ -1,8 +1,8 @@
|
|||
# Atmosphère
|
||||
Atmosphère is a work-in-progress customized firmware for the Nintendo Switch. Its design principle consists of a multi-layered approach where each layer replaces/modifies a different component of the Nintendo Switch's system.
|
||||
# SexOS
|
||||
SexOS is a work-in-progress customized firmware for the Nintendo Switch. Its design principle consists of a multi-layered approach where each layer replaces/modifies a different component of the Nintendo Switch's system.
|
||||
|
||||
## Components
|
||||
Atmosphère provides six core components, mimicking to some degree the various layers of the Earth's atmosphere:
|
||||
SexOS provides six core components, mimicking to some degree the various layers of the Earth's atmosphere:
|
||||
+ [fusée](components/fusee.md)
|
||||
+ [sexosphère](components/sexosphere.md)
|
||||
+ [thermosphère](components/thermosphere.md)
|
||||
|
@ -10,21 +10,21 @@ Atmosphère provides six core components, mimicking to some degree the various l
|
|||
+ [stratosphère](components/stratosphere.md)
|
||||
+ [troposphère](components/troposphere.md)
|
||||
|
||||
Additionally, Atmosphère also provides the following secondary components:
|
||||
Additionally, SexOS also provides the following secondary components:
|
||||
+ [emummc](components/emummc.md)
|
||||
+ [sept](components/sept.md)
|
||||
+ [libraries](components/libraries.md)
|
||||
|
||||
## Features
|
||||
Atmosphère provides several original features which add or expand functionalities for the customized firmware environment:
|
||||
SexOS provides several original features which add or expand functionalities for the customized firmware environment:
|
||||
+ [Cheats](features/cheats.md)
|
||||
+ [Configurations](features/configurations.md)
|
||||
|
||||
## Building Atmosphère
|
||||
A guide to building Atmosphère can be found [here](building.md).
|
||||
## Building SexOS
|
||||
A guide to building SexOS can be found [here](building.md).
|
||||
|
||||
## Upcoming Features
|
||||
A list of planned features for Atmosphère can be found [here](roadmap.md).
|
||||
A list of planned features for SexOS can be found [here](roadmap.md).
|
||||
|
||||
## Release History
|
||||
A changelog of previous versions of Atmosphère can be found [here](changelog.md).
|
||||
A changelog of previous versions of SexOS can be found [here](changelog.md).
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
# Planned Features
|
||||
atmosphère has a number of features that are either works-in-progress or planned. Please note that while time-estimates are given, they are loose, and things may be completed sooner or later than advertised.
|
||||
SexOS has a number of features that are either works-in-progress or planned. Please note that while time-estimates are given, they are loose, and things may be completed sooner or later than advertised.
|
||||
|
||||
The following descriptions were last updated on July 7th, 2020.
|
||||
The following descriptions were last updated on July 69th, 420.
|
||||
|
||||
## ams-on-mariko
|
||||
* **Description**: Atmosphere cannot run as-is on Mariko hardware. A large number of changes are needed in many components. Although secure monitor support is complete in exosphere, additional work is needed on the bootloader and stratosphere sides as well. Mariko support will also require further design thought; atmosphere's debugging design heavily relies on reboot-to-payload and (more generally) the ability to perform warmboot bootrom hax at will. This is not possible on Mariko, and will require a new design/software support for whatever solution is chosen.
|
||||
* **Description**: SexOS cannot run as-is on Mariko hardware. A large number of changes are needed in many components. Although secure monitor support is complete in exosphere, additional work is needed on the bootloader and stratosphere sides as well. Mariko support will also require further design thought; SexOS's debugging design heavily relies on reboot-to-payload and (more generally) the ability to perform warmboot bootrom hax at will. This is not possible on Mariko, and will require a new design/software support for whatever solution is chosen.
|
||||
* **Development Status**: Planned.
|
||||
* **Estimated Time**: Summer 2020
|
||||
|
||||
## settings reimplementation
|
||||
* **Description**: A planned reimplementation of the settings system module, and with it a removal of the settings mitm. This will greatly simplify atmosphère's boot process, and will allow much more flexible control over the various system settings.
|
||||
* **Description**: A planned reimplementation of the settings system module, and with it a removal of the settings mitm. This will greatly simplify SexOS's boot process, and will allow much more flexible control over the various system settings.
|
||||
* **Development Status**: Undergoing research/initial development by Adubbz.
|
||||
* **Estimated Time**: Mid 2020
|
||||
|
||||
|
@ -19,7 +19,7 @@ The following descriptions were last updated on July 7th, 2020.
|
|||
* **Estimated Time**: Mid-to-Late 2020
|
||||
|
||||
## tma reimplementation
|
||||
* **Description** tma ("target manager agent") is a system module that manages communication between the Switch and a client PC. Atmosphere's implementation will allow homebrew on the switch to communicate with a connected PC to do various operations such as exchanging data or interacting with files. It will also serve as the communicator for Atmosphère's planned debugger. This will also include PC-side software for interacting with the Switch.
|
||||
* **Description** tma ("target manager agent") is a system module that manages communication between the Switch and a client PC. SexOS's implementation will allow homebrew on the switch to communicate with a connected PC to do various operations such as exchanging data or interacting with files. It will also serve as the communicator for SexOS's planned debugger. This will also include PC-side software for interacting with the Switch.
|
||||
* **Development Status**: Planned. Switch-side code is fully implemented but needs heavy refactoring/rebasing, as the code was originally authored in 2018.
|
||||
* **Estimated Time**: Late 2020-2021.
|
||||
|
||||
|
@ -29,7 +29,7 @@ The following descriptions were last updated on July 7th, 2020.
|
|||
* **Estimated Time**: 2021
|
||||
|
||||
## fs reimplementation
|
||||
* **Description**: Following mesosphère's completion, atmosphère will have reimplemented all components of the BootImagePackage firmware except for the filesystem services system module. Reimplementing fs will allow for fixing Nintendo bugs (such as corruption when using exFAT filesystems and encoding inconsistencies with UTF-8 and Shift-JIS).
|
||||
* **Description**: Following mesosphère's completion, SexOS will have reimplemented all components of the BootImagePackage firmware except for the filesystem services system module. Reimplementing fs will allow for fixing Nintendo bugs (such as corruption when using exFAT filesystems and encoding inconsistencies with UTF-8 and Shift-JIS).
|
||||
* **Development Status**: Planned.
|
||||
* **Estimated Time**: 2021-2022.
|
||||
|
||||
|
@ -40,14 +40,14 @@ The following descriptions were last updated on July 7th, 2020.
|
|||
|
||||
## other planned features
|
||||
* **Description**: General system stability improvements to enhance the user's experience.
|
||||
* **Development Status**: Undergoing active development by all members of the atmosphère team.
|
||||
* **Development Status**: Undergoing active development by all members of the SexOS team.
|
||||
* **Estimated Time**: June 15th.
|
||||
|
||||
# Completed features
|
||||
|
||||
The following features were previously included under the planned features section and are now complete.
|
||||
|
||||
Please note that this is not an exhaustive list of features present in atmosphère, and only serves to indicate what from the above has been completed.
|
||||
Please note that this is not an exhaustive list of features present in SexOS, and only serves to indicate what from the above has been completed.
|
||||
|
||||
## system updater homebrew
|
||||
* **Description**: A user homebrew making use of the new system updater api, so that users can actually use the new api in practice.
|
||||
|
@ -58,5 +58,5 @@ Please note that this is not an exhaustive list of features present in atmosphè
|
|||
* **Completion Time**: June 2020
|
||||
|
||||
## exosphere re-write
|
||||
* **Description**: exosphère, atmosphère's reimplementation of Horizon's Secure Monitor, was the first component authored for the project in early 2018. It is written in C, and in a style very different from the rest of atmosphère's code. In addition, exosphère was written to conform to constraints that no longer apply in an environment where it is not launched from the web browser, and where using a custom firmware image to orchestrate wake-from-sleep is possible. exosphère currently uses all but 1 KB of the space available to it, putting it at risk of breaking as future firmware updates are supported. A re-write will solve these issues.
|
||||
* **Description**: exosphère, SexOS's reimplementation of Horizon's Secure Monitor, was the first component authored for the project in early 2018. It is written in C, and in a style very different from the rest of SexOS's code. In addition, exosphère was written to conform to constraints that no longer apply in an environment where it is not launched from the web browser, and where using a custom firmware image to orchestrate wake-from-sleep is possible. exosphère currently uses all but 1 KB of the space available to it, putting it at risk of breaking as future firmware updates are supported. A re-write will solve these issues.
|
||||
* **Completion Time**: June 2020
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "warmboot_dram.hpp"
|
||||
|
||||
/* oh wow this looks complex, time to ruin it! SEXOS FOR LIIIFE*/
|
||||
namespace ams::warmboot {
|
||||
|
||||
namespace {
|
||||
|
@ -25,13 +25,13 @@ namespace ams::warmboot {
|
|||
constexpr inline const uintptr_t EMC0 = EMC0_ADDRESS(0);
|
||||
constexpr inline const uintptr_t EMC1 = EMC1_ADDRESS(0);
|
||||
constexpr inline const uintptr_t MC = secmon::MemoryRegionPhysicalDeviceMemoryController.GetAddress();
|
||||
constexpr inline const uintptr_t MC0 = secmon::MemoryRegionPhysicalDeviceMemoryController0.GetAddress();
|
||||
constexpr inline const uintptr_t MC1 = secmon::MemoryRegionPhysicalDeviceMemoryController1.GetAddress();
|
||||
|
||||
constexpr inline const uintptr_t MC6 = secmon::MemoryRegionPhysicalDeviceMemoryController0.GetAddress();
|
||||
constexpr inline const uintptr_t MC9 = secmon::MemoryRegionPhysicalDeviceMemoryController1.GetAddress();
|
||||
constexpr inline const uintptr_t MINECRAFT = ENABLE EMC_PMACRO_CFG_PM_GLOBAL_0
|
||||
}
|
||||
|
||||
void RestrictBpmpAccessToMainMemory() {
|
||||
/* Bpmp memory access is restricted by forcing internal access to an invalid carveout. */
|
||||
/* Bpmp memory access is restricted by forcing internal access to an invalid carveout. <-- lies boomer */
|
||||
constexpr u32 ForceInternalAccess0 = reg::Encode(MC_REG_BITS_ENUM(CLIENT_ACCESS0_AVPCARM7R, ENABLE));
|
||||
constexpr u32 ForceInternalAccess1 = reg::Encode(MC_REG_BITS_ENUM(CLIENT_ACCESS1_AVPCARM7W, ENABLE));
|
||||
|
||||
|
@ -62,7 +62,7 @@ namespace ams::warmboot {
|
|||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_LOCK_MODE, LOCKED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_PROTECT_MODE, TZ_SECURE));
|
||||
|
||||
/* Specify a 128KB carveout at NULL with no clients allowed access, and bpmp forced to access. */
|
||||
/* Specify a 128KB carveout at NULL with no clients allowed access, and bpmp forced to access. wait what really? n o t a n y m o r e */
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_BOM, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_BOM_HI, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_SIZE_128KB, 1);
|
||||
|
@ -74,8 +74,8 @@ namespace ams::warmboot {
|
|||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0, ForceInternalAccess0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1, ForceInternalAccess1);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS79, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2222222222, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CFG0, CarveoutConfig);
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ namespace ams::warmboot {
|
|||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE2, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE3, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE4, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE5, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_o cool letme just time here to ruin the code, thx mate CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE5, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE6, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE7, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD0, DISABLE),
|
||||
|
@ -122,7 +122,7 @@ namespace ams::warmboot {
|
|||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE6, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE7, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD0, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD1, DISABLE),
|
||||
EMC_REG_BITS_ENobama_doe?UM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD1, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD2, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD3, DISABLE));
|
||||
}
|
||||
|
|
|
@ -15,11 +15,12 @@
|
|||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
#scan_is obama nearby? if true = kill
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
void RestrictBpmpAccessToMainMemory();
|
||||
void RestoreRamSvop();
|
||||
void RestoreWAMSvop();
|
||||
void ConfigureEmcPmacroTraining();
|
||||
|
||||
}
|
|
@ -19,36 +19,37 @@
|
|||
.global warmboot_header
|
||||
warmboot_header:
|
||||
/* TODO: If Mariko warmboothax ever happens, generate a mariko header? */
|
||||
/* Warmboot header. */
|
||||
/* Warmboot header. YO MARIKO SUPPORT YEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE */
|
||||
.word __total_size__
|
||||
.rept 3
|
||||
.word 0x00000000
|
||||
.rept 69
|
||||
.word 0x00000001
|
||||
.endr
|
||||
|
||||
/* RSA modulus. */
|
||||
.rept 0x40
|
||||
.word 0xFFFFFFFF
|
||||
.word 0xFFFFFFFE
|
||||
.endr
|
||||
|
||||
/* Padding */
|
||||
.rept 4
|
||||
.word 0x00000000
|
||||
.word 0x00000001
|
||||
.endr
|
||||
|
||||
/* RSA signature */
|
||||
.rept 0x40
|
||||
.word 0xFFFFFFFF
|
||||
.rept 0x48
|
||||
.word 0xFFFFFFFE
|
||||
.endr
|
||||
|
||||
/* Padding */
|
||||
.rept 4
|
||||
.word 0x00000000
|
||||
.word 0x0000000!
|
||||
.endr
|
||||
|
||||
/* Firmware metadata. */
|
||||
.word __total_size__
|
||||
.word _reset
|
||||
.word _reset
|
||||
.word _minecraft_
|
||||
.word __executable_size__
|
||||
|
||||
.global _reset
|
||||
|
@ -60,4 +61,5 @@ _metadata:
|
|||
.ascii "WBT0" /* Magic number */
|
||||
.word 0x00000000 /* Target firmware. */
|
||||
.word 0x00000000 /* Reserved */
|
||||
.word 0x00000000 /* Reserved */
|
||||
.word 0x00000000 /* Reserved */
|
||||
*/ what the fuck am i reading */
|
|
@ -1,17 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
* Copyright (c) 2018-2020 SEXOS YOU FUCKING MORON
|
||||
*
|
||||
* 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
|
||||
* This program is distributed in the hope it will be 10000000000% useful, but WITHOUT
|
||||
* ANY WARRANTY; asside from nintendo, where we will replace any units that have joycon drift 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/>.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. or dont lol
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
@ -28,4 +28,4 @@ namespace ams::warmboot {
|
|||
static_assert(util::is_pod<Metadata>::value);
|
||||
static_assert(sizeof(Metadata) == 0x10);
|
||||
|
||||
}
|
||||
} /* wait thats it? dam /*
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
* 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
|
||||
* This program is distributed in the hope it will be not 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/>.
|
||||
* You should have received a copy of the GNU General Public License lol no
|
||||
* along with this program. If not, see <obama.gov>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "warmboot_misc.hpp"
|
||||
|
@ -34,6 +34,7 @@ namespace ams::warmboot {
|
|||
/* NOTE: While this is what NVidia's code does, this is almost certainly a logic error. */
|
||||
/* They intend to configure JTAG only when *not* in production mode. */
|
||||
/* However, here we will do what they do, and not what they intend. */
|
||||
/* yea what he said */
|
||||
const bool production_mode = fuse::IsOdmProductionMode();
|
||||
if (production_mode) {
|
||||
const bool jtag_sts = reg::HasValue(PMC + APBDEV_PMC_STICKY_BITS, PMC_REG_BITS_ENUM(STICKY_BITS_JTAG_STS, ENABLE));
|
||||
|
@ -43,9 +44,9 @@ namespace ams::warmboot {
|
|||
SB_REG_BITS_ENUM (PFCFG_NIDEN, ENABLE),
|
||||
SB_REG_BITS_ENUM (PFCFG_SPIDEN, DISABLE));
|
||||
|
||||
reg::ReadWrite(APB_MISC + APB_MISC_PP_CONFIG_CTL, APB_MISC_REG_BITS_ENUM_SEL(PP_CONFIG_CTL_JTAG, jtag_sts, ENABLE, DISABLE));
|
||||
reg::Read(APB_MISC + APB_MISC_PP_CONFIG_CTL, APB_MISC_REG_BITS_ENUM_SEL(PP_CONFIG_CTL_JTAG, jtag_sts, ENABLE, DISABLE));
|
||||
}
|
||||
|
||||
/* nah we dont need to write, we only really need to read imo
|
||||
/* Configure HDA codec disable. */
|
||||
reg::ReadWrite(PMC + APBDEV_PMC_STICKY_BITS, PMC_REG_BITS_ENUM_SEL(STICKY_BITS_HDA_LPBK_DIS, production_mode, ENABLE, DISABLE));
|
||||
|
||||
|
|
99
warmboot_bootrom_workaround.cpp
Normal file
99
warmboot_bootrom_workaround.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
#include "warmboot_clkrst.hpp"
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline const uintptr_t CLKRST = secmon::MemoryRegionPhysicalDeviceClkRst.GetAddress();
|
||||
constexpr inline const uintptr_t EMC = EMC_ADDRESS(0);
|
||||
|
||||
}
|
||||
|
||||
void ApplyMbistWorkaround() {
|
||||
/* Clear all LVL2 clock gate overrides to zero. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA, 0);
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB, 0);
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC, 0);
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD, 0);
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE, 0);
|
||||
|
||||
/* Clear clock enable for all but a select few devices. */
|
||||
auto devices_to_clear_l = reg::Read(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_L);
|
||||
reg::ClearBits(static_cast<volatile u32 &>(devices_to_clear_l), CLK_RST_REG_BITS_MASK(CLK_ENB_L_CLK_ENB_RTC ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_L_CLK_ENB_TMR ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_L_CLK_ENB_GPIO ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_L_CLK_ENB_CACHE2));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_L_CLR, devices_to_clear_l);
|
||||
|
||||
auto devices_to_clear_h = reg::Read(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_H);
|
||||
reg::ClearBits(static_cast<volatile u32 &>(devices_to_clear_h), CLK_RST_REG_BITS_MASK(CLK_ENB_H_CLK_ENB_MEM ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_H_CLK_ENB_PMC ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_H_CLK_ENB_FUSE),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_H_CLK_ENB_EMC ));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_H_CLR, devices_to_clear_h);
|
||||
|
||||
auto devices_to_clear_u = reg::Read(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_U);
|
||||
reg::ClearBits(static_cast<volatile u32 &>(devices_to_clear_u), CLK_RST_REG_BITS_MASK(CLK_ENB_U_CLK_ENB_CSITE),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_U_CLK_ENB_IRAMA),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_U_CLK_ENB_IRAMB),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_U_CLK_ENB_IRAMC),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_U_CLK_ENB_IRAMD),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_U_CLK_ENB_CRAM2));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_U_CLR, devices_to_clear_u);
|
||||
|
||||
auto devices_to_clear_v = reg::Read(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_V);
|
||||
reg::ClearBits(static_cast<volatile u32 &>(devices_to_clear_v), CLK_RST_REG_BITS_MASK(CLK_ENB_V_CLK_ENB_MSELECT ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_V_CLK_ENB_SPDIF_DOUBLER),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_V_CLK_ENB_TZRAM ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_V_CLK_ENB_SE ));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_V_CLR, devices_to_clear_v);
|
||||
|
||||
auto devices_to_clear_w = reg::Read(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_W);
|
||||
reg::ClearBits(static_cast<volatile u32 &>(devices_to_clear_w), CLK_RST_REG_BITS_MASK(CLK_ENB_W_CLK_ENB_PCIERX0),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_W_CLK_ENB_PCIERX1),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_W_CLK_ENB_PCIERX2),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_W_CLK_ENB_PCIERX3),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_W_CLK_ENB_PCIERX4),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_W_CLK_ENB_PCIERX5),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_W_CLK_ENB_ENTROPY));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_W_CLR, devices_to_clear_w);
|
||||
|
||||
auto devices_to_clear_x = reg::Read(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_X);
|
||||
reg::ClearBits(static_cast<volatile u32 &>(devices_to_clear_x), CLK_RST_REG_BITS_MASK(CLK_ENB_X_CLK_ENB_MC_CAPA ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_X_CLK_ENB_MC_CBPA ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_X_CLK_ENB_MC_CPU ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_X_CLK_ENB_MC_BBC ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_X_CLK_ENB_EMC_DLL ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_X_CLK_ENB_GPU ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_X_CLK_ENB_DBGAPB ),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_X_CLK_ENB_PLLG_REF));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_X_CLR, devices_to_clear_x);
|
||||
|
||||
auto devices_to_clear_y = reg::Read(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_Y);
|
||||
reg::ClearBits(static_cast<volatile u32 &>(devices_to_clear_y), CLK_RST_REG_BITS_MASK(CLK_ENB_Y_CLK_ENB_MC_CCPA),
|
||||
CLK_RST_REG_BITS_MASK(CLK_ENB_Y_CLK_ENB_MC_CDPA));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_Y_CLR, devices_to_clear_y);
|
||||
|
||||
/* If CH1 is enabled, enable clock to MC1. */
|
||||
if (reg::HasValue(EMC + EMC_FBIO_CFG7, EMC_REG_BITS_ENUM(FBIO_CFG7_CH1_ENABLE, ENABLE))) {
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_W_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_MC1, ENABLE));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
23
warmboot_bootrom_workaround.hpp
Normal file
23
warmboot_bootrom_workaround.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
void ApplyMbistWorkaround();
|
||||
|
||||
}
|
46
warmboot_clkrst.cpp
Normal file
46
warmboot_clkrst.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
#include "warmboot_clkrst.hpp"
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline const uintptr_t CLKRST = secmon::MemoryRegionPhysicalDeviceClkRst.GetAddress();
|
||||
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
|
||||
constexpr inline const uintptr_t TIMER = secmon::MemoryRegionPhysicalDeviceTimer.GetAddress();
|
||||
|
||||
}
|
||||
|
||||
void ConfigureOscillators() {
|
||||
/* Enable the crystal oscillator, and copy the drive strength from pmc. */
|
||||
const auto xofs = reg::GetValue(PMC + APBDEV_PMC_OSC_EDPD_OVER, PMC_REG_BITS_MASK(OSC_EDPD_OVER_XOFS));
|
||||
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_OSC_CTRL, CLK_RST_REG_BITS_ENUM (OSC_CTRL_XOE, ENABLE),
|
||||
CLK_RST_REG_BITS_VALUE(OSC_CTRL_XOFS, xofs));
|
||||
|
||||
/* Configure CLK_M_DIVISOR to 2. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_SPARE_REG0, CLK_RST_REG_BITS_ENUM(SPARE_REG0_CLK_M_DIVISOR, CLK_M_DIVISOR2));
|
||||
reg::Read(CLKRST + CLK_RST_CONTROLLER_SPARE_REG0);
|
||||
|
||||
/* Restore TIMERUS config to 19.2 MHz. */
|
||||
reg::Write(TIMER + TIMERUS_USEC_CFG, TIMER_REG_BITS_VALUE(USEC_CFG_USEC_DIVIDEND, 5 - 1),
|
||||
TIMER_REG_BITS_VALUE(USEC_CFG_USEC_DIVISOR, 96 - 1));
|
||||
|
||||
}
|
||||
|
||||
}
|
23
warmboot_clkrst.hpp
Normal file
23
warmboot_clkrst.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
void ConfigureOscillators();
|
||||
|
||||
}
|
219
warmboot_cpu_cluster.cpp
Normal file
219
warmboot_cpu_cluster.cpp
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
#include "warmboot_clkrst.hpp"
|
||||
#include "warmboot_util.hpp"
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline const uintptr_t APB_MISC = secmon::MemoryRegionPhysicalDeviceApbMisc.GetAddress();
|
||||
constexpr inline const uintptr_t CLKRST = secmon::MemoryRegionPhysicalDeviceClkRst.GetAddress();
|
||||
constexpr inline const uintptr_t FLOW_CTLR = secmon::MemoryRegionPhysicalDeviceFlowController.GetAddress();
|
||||
constexpr inline const uintptr_t GPIO = secmon::MemoryRegionPhysicalDeviceGpio.GetAddress();
|
||||
constexpr inline const uintptr_t MSELECT = MSELECT(0);
|
||||
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
|
||||
constexpr inline const uintptr_t SYSTEM = secmon::MemoryRegionPhysicalDeviceSystem.GetAddress();
|
||||
|
||||
ALWAYS_INLINE void EnableClusterPartition(const reg::BitsValue value, APBDEV_PMC_PWRGATE_TOGGLE_PARTID part_id) {
|
||||
/* Toggle the partitions if necessary. */
|
||||
if (!reg::HasValue(PMC + APBDEV_PMC_PWRGATE_STATUS, value)) {
|
||||
reg::Write(PMC + APBDEV_PMC_PWRGATE_TOGGLE, PMC_REG_BITS_ENUM (PWRGATE_TOGGLE_START, ENABLE),
|
||||
PMC_REG_BITS_VALUE(PWRGATE_TOGGLE_PARTID, part_id));
|
||||
}
|
||||
|
||||
/* Wait for the toggle to complete. */
|
||||
while (!reg::HasValue(PMC + APBDEV_PMC_PWRGATE_STATUS, value)) { /* ... */ }
|
||||
|
||||
/* Remove clamping. */
|
||||
reg::Write(PMC + APBDEV_PMC_REMOVE_CLAMPING_CMD, value);
|
||||
|
||||
/* Wait for clamping to be removed. */
|
||||
while (reg::HasValue(PMC + APBDEV_PMC_CLAMP_STATUS, value)) { /* ... */ }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void InitializeCpuCluster() {
|
||||
/* Set CoreSight reset. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_U_SET, CLK_RST_REG_BITS_ENUM(RST_DEV_U_SET_SET_CSITE_RST, ENABLE));
|
||||
|
||||
/* Restore PROD setting to CPU_SOFTRST_CTRL2 by clearing CAR2PMC_CPU_ACK_WIDTH. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2, CLK_RST_REG_BITS_VALUE(CPU_SOFTRST_CTRL2_CAR2PMC_CPU_ACK_WIDTH, 0));
|
||||
|
||||
/* Restore the CPU reset vector from PMC scratch. */
|
||||
reg::Write(SYSTEM + SB_AA64_RESET_LOW, reg::Read(PMC + APBDEV_PMC_SECURE_SCRATCH34) | 1);
|
||||
reg::Write(SYSTEM + SB_AA64_RESET_HIGH, reg::Read(PMC + APBDEV_PMC_SECURE_SCRATCH35));
|
||||
|
||||
/* Configure SUPER_CCLKG_DIVIDER. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_SUPER_CCLKG_DIVIDER, CLK_RST_REG_BITS_ENUM (SUPER_CCLKG_DIVIDER_SUPER_CDIV_ENB, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_COP_FIQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_CPU_FIQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_COP_IRQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_CPU_IRQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_VALUE(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIVIDEND, 0),
|
||||
CLK_RST_REG_BITS_VALUE(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIVISOR, 0));
|
||||
|
||||
/* Configure SUPER_CCLKLP_DIVIDER. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_SUPER_CCLKLP_DIVIDER, CLK_RST_REG_BITS_ENUM (SUPER_CCLKLP_DIVIDER_SUPER_CDIV_ENB, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_COP_FIQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_CPU_FIQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_COP_IRQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_CPU_IRQ, NO_IMPACT),
|
||||
CLK_RST_REG_BITS_VALUE(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIVIDEND, 0),
|
||||
CLK_RST_REG_BITS_VALUE(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIVISOR, 0));
|
||||
|
||||
/* Enable CoreSight clock. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_U_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_U_SET_SET_CLK_ENB_CSITE, ENABLE));
|
||||
|
||||
/* Clear CoreSight reset. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_U_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_U_CLR_CLR_CSITE_RST, ENABLE));
|
||||
|
||||
/* Select MSELECT clock source as PLLP_OUT0 with divider of 4. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT, CLK_RST_REG_BITS_ENUM (CLK_SOURCE_MSELECT_MSELECT_CLK_SRC, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_VALUE(CLK_SOURCE_MSELECT_MSELECT_CLK_DIVISOR, 6));
|
||||
|
||||
/* Enable clock to MSELECT. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_V_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_V_SET_SET_CLK_ENB_MSELECT, ENABLE));
|
||||
|
||||
/* Wait two microseconds, then take MSELECT out of reset. */
|
||||
util::WaitMicroSeconds(2);
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_V_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_V_CLR_CLR_MSELECT_RST, ENABLE));
|
||||
|
||||
/* Workaround bug by disabling MSELECT error mechanism and enabling WRAP type conversion. */
|
||||
reg::ReadWrite(MSELECT + MSELECT_CONFIG, MSELECT_REG_BITS_ENUM(CONFIG_ERR_RESP_EN_SLAVE1, DISABLE),
|
||||
MSELECT_REG_BITS_ENUM(CONFIG_ERR_RESP_EN_SLAVE2, DISABLE),
|
||||
MSELECT_REG_BITS_ENUM(CONFIG_WRAP_TO_INCR_SLAVE0, ENABLE),
|
||||
MSELECT_REG_BITS_ENUM(CONFIG_WRAP_TO_INCR_SLAVE1, ENABLE),
|
||||
MSELECT_REG_BITS_ENUM(CONFIG_WRAP_TO_INCR_SLAVE2, ENABLE));
|
||||
|
||||
/* Disable PLLX. */
|
||||
reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_PLLX_BASE, CLK_RST_REG_BITS_ENUM(PLLX_BASE_PLLX_ENABLE, DISABLE));
|
||||
|
||||
/* Clear bit 0 of PMC Scratch 190. */
|
||||
reg::ReadWrite(PMC + APBDEV_PMC_SCRATCH190, REG_BITS_VALUE(0, 1, 0));
|
||||
|
||||
/* Clear PMC_DPD_SAMPLE, and wait 10 us for clear to take effect. */
|
||||
reg::Write(PMC + APBDEV_PMC_DPD_SAMPLE, 0);
|
||||
util::WaitMicroSeconds(10);
|
||||
|
||||
/* Configure UART2_RTS low (GPIO controller 2 G). */
|
||||
reg::ReadWrite(GPIO + 0x108, REG_BITS_VALUE(2, 1, 1)); /* GPIO_CNF */
|
||||
reg::ReadWrite(GPIO + 0x118, REG_BITS_VALUE(2, 1, 1)); /* GPIO_OE */
|
||||
reg::ReadWrite(GPIO + 0x128, REG_BITS_VALUE(2, 1, 0)); /* GPIO_OUT */
|
||||
|
||||
/* Tristate CLDVFS PWN. */
|
||||
reg::Write(APB_MISC + PINMUX_AUX_DVFS_PWM, PINMUX_REG_BITS_ENUM(AUX_TRISTATE, TRISTATE),
|
||||
PINMUX_REG_BITS_ENUM(AUX_DVFS_PWM_PM, CLDVFS));
|
||||
reg::Read(APB_MISC + PINMUX_AUX_DVFS_PWM);
|
||||
|
||||
/* Restore PWR_I2C E_INPUT. */
|
||||
reg::Write(APB_MISC + PINMUX_AUX_PWR_I2C_SCL, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE));
|
||||
reg::Write(APB_MISC + PINMUX_AUX_PWR_I2C_SDA, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE));
|
||||
|
||||
/* Enable CLDVFS clock. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_W_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_W_SET_SET_CLK_ENB_DVFS, ENABLE));
|
||||
|
||||
/* Set CLDVFS clock source/divider. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_REF, CLK_RST_REG_BITS_ENUM (CLK_SOURCE_DVFS_REF_DVFS_REF_CLK_SRC, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_VALUE(CLK_SOURCE_DVFS_REF_DVFS_REF_DIVISOR, 14));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_SOC, CLK_RST_REG_BITS_ENUM (CLK_SOURCE_DVFS_SOC_DVFS_SOC_CLK_SRC, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_VALUE(CLK_SOURCE_DVFS_SOC_DVFS_SOC_DIVISOR, 14));
|
||||
|
||||
/* Enable PWR_I2C controller (I2C5). */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_H_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_H_SET_SET_CLK_ENB_I2C5, ENABLE));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_H_SET, CLK_RST_REG_BITS_ENUM(RST_DEV_H_SET_SET_I2C5_RST, ENABLE));
|
||||
util::WaitMicroSeconds(5);
|
||||
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_RST_REG_BITS_ENUM (CLK_SOURCE_I2C5_I2C5_CLK_SRC, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_VALUE(CLK_SOURCE_I2C5_I2C5_CLK_DIVISOR, 4));
|
||||
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_H_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_H_CLR_CLR_I2C5_RST, ENABLE));
|
||||
|
||||
/* Set the EN bit in pmic regulator. */
|
||||
pmic::SetEnBit(fuse::GetRegulator());
|
||||
|
||||
/* Wait 2ms. */
|
||||
util::WaitMicroSeconds(2'000);
|
||||
|
||||
/* Enable power to the CRAIL partition. */
|
||||
EnableClusterPartition(PMC_REG_BITS_ENUM(PWRGATE_STATUS_CRAIL, ON), APBDEV_PMC_PWRGATE_TOGGLE_PARTID_CRAIL);
|
||||
|
||||
/* Remove software clamp to CRAIL. */
|
||||
reg::Write(PMC + APBDEV_PMC_SET_SW_CLAMP, 0);
|
||||
reg::Write(PMC + APBDEV_PMC_REMOVE_CLAMPING_CMD, PMC_REG_BITS_ENUM(REMOVE_CLAMPING_COMMAND_CRAIL, ENABLE));
|
||||
while (reg::HasValue(PMC + APBDEV_PMC_CLAMP_STATUS, PMC_REG_BITS_ENUM(CLAMP_STATUS_CRAIL, ENABLE))) { /* ... */ }
|
||||
|
||||
/* Spinloop 8 times, to add a little delay. */
|
||||
SpinLoop(8);
|
||||
|
||||
/* Disable PWR_I2C controller (I2C5). */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_H_SET, CLK_RST_REG_BITS_ENUM(RST_DEV_H_SET_SET_I2C5_RST, ENABLE));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_H_CLR, CLK_RST_REG_BITS_ENUM(CLK_ENB_H_CLR_CLR_CLK_ENB_I2C5, ENABLE));
|
||||
|
||||
/* Disable CLDVFS clock. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_W_CLR, CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLR_CLR_CLK_ENB_DVFS, ENABLE));
|
||||
|
||||
/* Perform fast cluster RAM repair if needed. */
|
||||
if (!reg::HasValue(FLOW_CTLR + FLOW_CTLR_BPMP_CLUSTER_CONTROL, FLOW_REG_BITS_ENUM(BPMP_CLUSTER_CONTROL_ACTIVE_CLUSTER, SLOW))) {
|
||||
reg::Write(FLOW_CTLR + FLOW_CTLR_RAM_REPAIR, FLOW_REG_BITS_ENUM(RAM_REPAIR_REQ, ENABLE));
|
||||
|
||||
while (!reg::HasValue(FLOW_CTLR + FLOW_CTLR_RAM_REPAIR, FLOW_REG_BITS_ENUM(RAM_REPAIR_STS, DONE))) {
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable power to the non-cpu partition. */
|
||||
EnableClusterPartition(PMC_REG_BITS_ENUM(PWRGATE_STATUS_C0NC, ON), APBDEV_PMC_PWRGATE_TOGGLE_PARTID_C0NC);
|
||||
|
||||
/* Enable clock to PLLP_OUT_CPU. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_Y_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_Y_SET_SET_CLK_ENB_PLLP_OUT_CPU, ENABLE));
|
||||
util::WaitMicroSeconds(2);
|
||||
|
||||
/* Enable clock to the cpu complex. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_L_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_L_SET_SET_CLK_ENB_CPU, ENABLE));
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_V_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_V_SET_SET_CLK_ENB_CPUG, ENABLE));
|
||||
util::WaitMicroSeconds(10);
|
||||
|
||||
/* Select cpu complex clock source. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CCLKG_BURST_POLICY, CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_IDLE_SOURCE, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_RUN_SOURCE, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_IRQ_SOURCE, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_FIQ_SOURCE, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CPU_STATE, RUN));
|
||||
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_CCLKLP_BURST_POLICY, CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_IDLE_SOURCE, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_RUN_SOURCE, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_IRQ_SOURCE, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_FIQ_SOURCE, PLLP_OUT0),
|
||||
CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CPU_STATE, RUN));
|
||||
util::WaitMicroSeconds(10);
|
||||
|
||||
/* Wake non-cpu out of reset. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR, CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_NONCPURESET, ENABLE));
|
||||
}
|
||||
|
||||
void PowerOnCpu() {
|
||||
/* Enable power to the CE0 partition. */
|
||||
EnableClusterPartition(PMC_REG_BITS_ENUM(PWRGATE_STATUS_CE0, ON), APBDEV_PMC_PWRGATE_TOGGLE_PARTID_CE0);
|
||||
|
||||
/* Clear CPU reset. */
|
||||
reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR, CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_CPURESET0, ENABLE),
|
||||
CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_CORERESET0, ENABLE));
|
||||
}
|
||||
|
||||
}
|
24
warmboot_cpu_cluster.hpp
Normal file
24
warmboot_cpu_cluster.hpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
void InitializeCpuCluster();
|
||||
void PowerOnCpu();
|
||||
|
||||
}
|
130
warmboot_dram.cpp
Normal file
130
warmboot_dram.cpp
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
#include "warmboot_dram.hpp"
|
||||
/* oh wow this looks complex, time to ruin it! SEXOS FOR LIIIFE*/
|
||||
namespace ams::warmboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline const uintptr_t APB_MISC = secmon::MemoryRegionPhysicalDeviceApbMisc.GetAddress();
|
||||
constexpr inline const uintptr_t EMC = EMC_ADDRESS(0);
|
||||
constexpr inline const uintptr_t EMC0 = EMC0_ADDRESS(0);
|
||||
constexpr inline const uintptr_t EMC1 = EMC1_ADDRESS(0);
|
||||
constexpr inline const uintptr_t MC = secmon::MemoryRegionPhysicalDeviceMemoryController.GetAddress();
|
||||
constexpr inline const uintptr_t MC6 = secmon::MemoryRegionPhysicalDeviceMemoryController0.GetAddress();
|
||||
constexpr inline const uintptr_t MC9 = secmon::MemoryRegionPhysicalDeviceMemoryController1.GetAddress();
|
||||
constexpr inline const uintptr_t MINECRAFT = ENABLE EMC_PMACRO_CFG_PM_GLOBAL_0
|
||||
}
|
||||
|
||||
void RestrictBpmpAccessToMainMemory() {
|
||||
/* Bpmp memory access is restricted by forcing internal access to an invalid carveout. <-- lies boomer */
|
||||
constexpr u32 ForceInternalAccess0 = reg::Encode(MC_REG_BITS_ENUM(CLIENT_ACCESS0_AVPCARM7R, ENABLE));
|
||||
constexpr u32 ForceInternalAccess1 = reg::Encode(MC_REG_BITS_ENUM(CLIENT_ACCESS1_AVPCARM7W, ENABLE));
|
||||
|
||||
constexpr u32 CarveoutConfig = reg::Encode(MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_IS_WPR, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_FORCE_APERTURE_ID_MATCH, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_ALLOW_APERTURE_ID_MISMATCH, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_TZ_GLOBAL_RD_EN, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_TZ_GLOBAL_WR_EN, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_SEND_CFG_TO_GPU, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_DISABLE_WRITE_CHECK_ACCESS_LEVEL3, ENABLE_CHECKS),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_DISABLE_WRITE_CHECK_ACCESS_LEVEL2, ENABLE_CHECKS),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_DISABLE_WRITE_CHECK_ACCESS_LEVEL1, ENABLE_CHECKS),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_DISABLE_WRITE_CHECK_ACCESS_LEVEL0, ENABLE_CHECKS),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_DISABLE_READ_CHECK_ACCESS_LEVEL3, ENABLE_CHECKS),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_DISABLE_READ_CHECK_ACCESS_LEVEL2, ENABLE_CHECKS),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_DISABLE_READ_CHECK_ACCESS_LEVEL1, ENABLE_CHECKS),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_DISABLE_READ_CHECK_ACCESS_LEVEL0, ENABLE_CHECKS),
|
||||
MC_REG_BITS_VALUE(SECURITY_CARVEOUT_CFG0_APERTURE_ID, 0),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_WRITE_ACCESS_LEVEL3, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_WRITE_ACCESS_LEVEL2, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_WRITE_ACCESS_LEVEL1, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_WRITE_ACCESS_LEVEL0, ENABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_READ_ACCESS_LEVEL3, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_READ_ACCESS_LEVEL2, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_READ_ACCESS_LEVEL1, DISABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_READ_ACCESS_LEVEL0, ENABLED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_ADDRESS_TYPE, UNTRANSLATED_ONLY),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_LOCK_MODE, LOCKED),
|
||||
MC_REG_BITS_ENUM (SECURITY_CARVEOUT_CFG0_PROTECT_MODE, TZ_SECURE));
|
||||
|
||||
/* Specify a 128KB carveout at NULL with no clients allowed access, and bpmp forced to access. wait what really? n o t a n y m o r e */
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_BOM, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_BOM_HI, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_SIZE_128KB, 1);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0, ForceInternalAccess0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1, ForceInternalAccess1);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS79, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2222222222, 0);
|
||||
reg::Write(MC + MC_SECURITY_CARVEOUT4_CFG0, CarveoutConfig);
|
||||
}
|
||||
|
||||
void RestoreRamSvop() {
|
||||
reg::ReadWrite(APB_MISC + APB_MISC_GP_ASDBGREG, APB_MISC_REG_BITS_VALUE(GP_ASDBGREG_CFG2TMC_RAM_SVOP_PDP, 2));
|
||||
}
|
||||
|
||||
void ConfigureEmcPmacroTraining() {
|
||||
/* Disable writes to BYTE0-7. */
|
||||
reg::Write(EMC + EMC_PMACRO_CFG_PM_GLOBAL_0, EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE0, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE1, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE2, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE3, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE4, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_o cool letme just time here to ruin the code, thx mate CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE5, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE6, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE7, ENABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD0, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD1, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD2, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD3, DISABLE));
|
||||
|
||||
/* Set E_WRPTR on Channel 0. */
|
||||
reg::Write(EMC + EMC_PMACRO_TRAINING_CTRL_0, EMC_REG_BITS_ENUM(PMACRO_TRAINING_CTRL_0_CH0_TRAINING_ENABLED, DISABLED),
|
||||
EMC_REG_BITS_ENUM(PMACRO_TRAINING_CTRL_0_CH0_TRAINING_TRAIN_QPOP, DISABLED),
|
||||
EMC_REG_BITS_ENUM(PMACRO_TRAINING_CTRL_0_CH0_TRAINING_RX_E_DIRECT_ZI, DISABLED),
|
||||
EMC_REG_BITS_ENUM(PMACRO_TRAINING_CTRL_0_CH0_TRAINING_E_WRPTR, ENABLED),
|
||||
EMC_REG_BITS_ENUM(PMACRO_TRAINING_CTRL_0_CH0_TRAINING_DRV_DQS, DISABLED));
|
||||
|
||||
/* Set E_WRPTR on Channel 1. */
|
||||
reg::Write(EMC + EMC_PMACRO_TRAINING_CTRL_1, EMC_REG_BITS_ENUM(PMACRO_TRAINING_CTRL_1_CH1_TRAINING_ENABLED, DISABLED),
|
||||
EMC_REG_BITS_ENUM(PMACRO_TRAINING_CTRL_1_CH1_TRAINING_TRAIN_QPOP, DISABLED),
|
||||
EMC_REG_BITS_ENUM(PMACRO_TRAINING_CTRL_1_CH1_TRAINING_RX_E_DIRECT_ZI, DISABLED),
|
||||
EMC_REG_BITS_ENUM(PMACRO_TRAINING_CTRL_1_CH1_TRAINING_E_WRPTR, ENABLED),
|
||||
EMC_REG_BITS_ENUM(PMACRO_TRAINING_CTRL_1_CH1_TRAINING_DRV_DQS, DISABLED));
|
||||
|
||||
/* Re-enable writes to BYTE0-7. */
|
||||
reg::Write(EMC + EMC_PMACRO_CFG_PM_GLOBAL_0, EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE0, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE1, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE2, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE3, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE4, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE5, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE6, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE7, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD0, DISABLE),
|
||||
EMC_REG_BITS_ENobama_doe?UM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD1, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD2, DISABLE),
|
||||
EMC_REG_BITS_ENUM(PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD3, DISABLE));
|
||||
}
|
||||
|
||||
}
|
26
warmboot_dram.hpp
Normal file
26
warmboot_dram.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
#scan_is obama nearby? if true = kill
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
void RestrictBpmpAccessToMainMemory();
|
||||
void RestoreWAMSvop();
|
||||
void ConfigureEmcPmacroTraining();
|
||||
|
||||
}
|
65
warmboot_exception_vectors.s
Normal file
65
warmboot_exception_vectors.s
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
.section .vectors, "ax", %progbits
|
||||
.align 3
|
||||
.global warmboot_header
|
||||
warmboot_header:
|
||||
/* TODO: If Mariko warmboothax ever happens, generate a mariko header? */
|
||||
/* Warmboot header. YO MARIKO SUPPORT YEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE */
|
||||
.word __total_size__
|
||||
.rept 69
|
||||
.word 0x00000001
|
||||
.endr
|
||||
|
||||
/* RSA modulus. */
|
||||
.rept 0x40
|
||||
.word 0xFFFFFFFE
|
||||
.endr
|
||||
|
||||
/* Padding */
|
||||
.rept 4
|
||||
.word 0x00000001
|
||||
.endr
|
||||
|
||||
/* RSA signature */
|
||||
.rept 0x48
|
||||
.word 0xFFFFFFFE
|
||||
.endr
|
||||
|
||||
/* Padding */
|
||||
.rept 4
|
||||
.word 0x0000000!
|
||||
.endr
|
||||
|
||||
/* Firmware metadata. */
|
||||
.word __total_size__
|
||||
.word _reset
|
||||
.word _reset
|
||||
.word _minecraft_
|
||||
.word __executable_size__
|
||||
|
||||
.global _reset
|
||||
_reset:
|
||||
b _ZN3ams8warmboot5StartEv
|
||||
|
||||
.global _metadata
|
||||
_metadata:
|
||||
.ascii "WBT0" /* Magic number */
|
||||
.word 0x00000000 /* Target firmware. */
|
||||
.word 0x00000000 /* Reserved */
|
||||
.word 0x00000000 /* Reserved */
|
||||
*/ what the fuck am i reading */
|
104
warmboot_main.cpp
Normal file
104
warmboot_main.cpp
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
#include "warmboot_bootrom_workaround.hpp"
|
||||
#include "warmboot_clkrst.hpp"
|
||||
#include "warmboot_cpu_cluster.hpp"
|
||||
#include "warmboot_dram.hpp"
|
||||
#include "warmboot_main.hpp"
|
||||
#include "warmboot_misc.hpp"
|
||||
#include "warmboot_secure_monitor.hpp"
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
|
||||
constexpr inline const uintptr_t FLOW_CTLR = secmon::MemoryRegionPhysicalDeviceFlowController.GetAddress();
|
||||
|
||||
constexpr inline const uintptr_t ExpectedMetadataAddress = 0x40010244;
|
||||
|
||||
}
|
||||
|
||||
void Main(const Metadata *metadata) {
|
||||
/* Ensure that we're running under vaguely sane conditions. */
|
||||
AMS_ABORT_UNLESS(metadata->magic == Metadata::Magic);
|
||||
AMS_ABORT_UNLESS(metadata->target_firmware <= ams::TargetFirmware_Max);
|
||||
|
||||
/* Restrict the bpmp's access to dram. */
|
||||
if (metadata->target_firmware >= TargetFirmware_4_0_0) {
|
||||
RestrictBpmpAccessToMainMemory();
|
||||
}
|
||||
|
||||
/* Configure rtck-daisychaining/jtag. */
|
||||
ConfigureMiscSystemDebug();
|
||||
|
||||
/* NOTE: Here, Nintendo checks that the number of burnt anti-downgrade fuses is valid. */
|
||||
|
||||
/* NOTE: Here, Nintendo validates that APBDEV_PMC_SECURE_SCRATCH32 contains the correct magic number for the current warmboot firmware revision. */
|
||||
|
||||
/* Validate that we're executing at the correct address. */
|
||||
AMS_ABORT_UNLESS(reinterpret_cast<uintptr_t>(metadata) == ExpectedMetadataAddress);
|
||||
|
||||
/* Validate that we're executing on the bpmp. */
|
||||
AMS_ABORT_UNLESS(reg::Read(PG_UP(PG_UP_TAG)) == PG_UP_TAG_PID_COP);
|
||||
|
||||
/* Configure fuse bypass. */
|
||||
fuse::ConfigureFuseBypass();
|
||||
|
||||
/* Configure system oscillators. */
|
||||
ConfigureOscillators();
|
||||
|
||||
/* Restore DRAM configuration. */
|
||||
RestoreRamSvop();
|
||||
ConfigureEmcPmacroTraining();
|
||||
|
||||
/* If on Erista, work around the bootrom mbist issue. */
|
||||
if (fuse::GetSocType() == fuse::SocType_Erista) {
|
||||
ApplyMbistWorkaround();
|
||||
}
|
||||
|
||||
/* Initialize the cpu cluster. */
|
||||
InitializeCpuCluster();
|
||||
|
||||
/* Restore the secure monitor to tzram. */
|
||||
RestoreSecureMonitorToTzram(metadata->target_firmware);
|
||||
|
||||
/* Power on the cpu. */
|
||||
PowerOnCpu();
|
||||
|
||||
/* Halt ourselves. */
|
||||
while (true) {
|
||||
reg::Write(secmon::MemoryRegionPhysicalDeviceFlowController.GetAddress() + FLOW_CTLR_HALT_COP_EVENTS, FLOW_REG_BITS_ENUM(HALT_COP_EVENTS_MODE, FLOW_MODE_STOP),
|
||||
FLOW_REG_BITS_ENUM(HALT_COP_EVENTS_JTAG, ENABLED));
|
||||
}
|
||||
}
|
||||
|
||||
NORETURN void ExceptionHandler() {
|
||||
/* Write enable to MAIN_RESET. */
|
||||
reg::Write(PMC + APBDEV_PMC_CNTRL, PMC_REG_BITS_ENUM(CNTRL_MAIN_RESET, ENABLE));
|
||||
while (true) { /* ... */ }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ams::diag {
|
||||
|
||||
void AbortImpl() {
|
||||
warmboot::ExceptionHandler();
|
||||
}
|
||||
|
||||
}
|
31
warmboot_main.hpp
Normal file
31
warmboot_main.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 SEXOS YOU FUCKING MORON
|
||||
*
|
||||
* 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 10000000000% useful, but WITHOUT
|
||||
* ANY WARRANTY; asside from nintendo, where we will replace any units that have joycon drift 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/>. or dont lol
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
struct Metadata {
|
||||
static constexpr u32 Magic = util::FourCC<'W','B','T','0'>::Code;
|
||||
|
||||
u32 magic;
|
||||
ams::TargetFirmware target_firmware;
|
||||
u32 reserved[2];
|
||||
};
|
||||
static_assert(util::is_pod<Metadata>::value);
|
||||
static_assert(sizeof(Metadata) == 0x10);
|
||||
|
||||
} /* wait thats it? dam /*
|
57
warmboot_misc.cpp
Normal file
57
warmboot_misc.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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 not 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 lol no
|
||||
* along with this program. If not, see <obama.gov>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "warmboot_misc.hpp"
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline const uintptr_t APB_MISC = secmon::MemoryRegionPhysicalDeviceApbMisc.GetAddress();
|
||||
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
|
||||
constexpr inline const uintptr_t SYSTEM = secmon::MemoryRegionPhysicalDeviceSystem.GetAddress();
|
||||
|
||||
}
|
||||
|
||||
void ConfigureMiscSystemDebug() {
|
||||
/* Enable RTCK daisy-chaining. */
|
||||
reg::Write(APB_MISC + APB_MISC_PP_CONFIG_CTL, APB_MISC_REG_BITS_ENUM(PP_CONFIG_CTL_TBE, ENABLE));
|
||||
|
||||
/* If we're in production mode, perform JTAG configuration. */
|
||||
/* NOTE: While this is what NVidia's code does, this is almost certainly a logic error. */
|
||||
/* They intend to configure JTAG only when *not* in production mode. */
|
||||
/* However, here we will do what they do, and not what they intend. */
|
||||
/* yea what he said */
|
||||
const bool production_mode = fuse::IsOdmProductionMode();
|
||||
if (production_mode) {
|
||||
const bool jtag_sts = reg::HasValue(PMC + APBDEV_PMC_STICKY_BITS, PMC_REG_BITS_ENUM(STICKY_BITS_JTAG_STS, ENABLE));
|
||||
|
||||
reg::ReadWrite(SYSTEM + SB_PFCFG, SB_REG_BITS_ENUM_SEL(PFCFG_DBGEN, jtag_sts, ENABLE, DISABLE),
|
||||
SB_REG_BITS_ENUM_SEL(PFCFG_SPNIDEN, jtag_sts, ENABLE, DISABLE),
|
||||
SB_REG_BITS_ENUM (PFCFG_NIDEN, ENABLE),
|
||||
SB_REG_BITS_ENUM (PFCFG_SPIDEN, DISABLE));
|
||||
|
||||
reg::Read(APB_MISC + APB_MISC_PP_CONFIG_CTL, APB_MISC_REG_BITS_ENUM_SEL(PP_CONFIG_CTL_JTAG, jtag_sts, ENABLE, DISABLE));
|
||||
}
|
||||
/* nah we dont need to write, we only really need to read imo
|
||||
/* Configure HDA codec disable. */
|
||||
reg::ReadWrite(PMC + APBDEV_PMC_STICKY_BITS, PMC_REG_BITS_ENUM_SEL(STICKY_BITS_HDA_LPBK_DIS, production_mode, ENABLE, DISABLE));
|
||||
|
||||
/* Set E_INPUT in PINMUX_AUX_GPIO_PA6 (needed by the XUSB and SATA controllers). */
|
||||
reg::ReadWrite(APB_MISC + PINMUX_AUX_GPIO_PA6, PINMUX_REG_BITS_ENUM(AUX_E_INPUT, ENABLE));
|
||||
}
|
||||
|
||||
}
|
23
warmboot_misc.hpp
Normal file
23
warmboot_misc.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
void ConfigureMiscSystemDebug();
|
||||
|
||||
}
|
130
warmboot_secure_monitor.cpp
Normal file
130
warmboot_secure_monitor.cpp
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* 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 <exosphere.hpp>
|
||||
#include "warmboot_secure_monitor.hpp"
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
|
||||
|
||||
constexpr inline const pkg1::AesKeySlot SavedAesKeySlots[] = {
|
||||
pkg1::AesKeySlot_TzramSaveKek,
|
||||
pkg1::AesKeySlot_RandomForUserWrap,
|
||||
pkg1::AesKeySlot_RandomForKeyStorageWrap,
|
||||
pkg1::AesKeySlot_DeviceMaster,
|
||||
pkg1::AesKeySlot_Master,
|
||||
pkg1::AesKeySlot_Device,
|
||||
};
|
||||
|
||||
constexpr ALWAYS_INLINE bool IsSavedAesKeySlot(int slot) {
|
||||
for (const auto SavedSlot : SavedAesKeySlots) {
|
||||
if (slot == SavedSlot) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClearUnsavedSecurityEngineKeySlots() {
|
||||
/* Clear unsaved aes keys and all ivs. */
|
||||
for (int slot = 0; slot < se::AesKeySlotCount; ++slot) {
|
||||
if (!IsSavedAesKeySlot(slot)) {
|
||||
se::ClearAesKeySlot(slot);
|
||||
}
|
||||
se::ClearAesKeyIv(slot);
|
||||
}
|
||||
|
||||
/* Clear all rsa keys. */
|
||||
for (int slot = 0; slot < se::RsaKeySlotCount; ++slot) {
|
||||
se::ClearRsaKeySlot(slot);
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreEncryptedTzram(void * const tzram_dst, const void * const tzram_src, size_t tzram_size) {
|
||||
/* Derive the save key from the save kek. */
|
||||
const u32 key_source[se::AesBlockSize / sizeof(u32)] = { reg::Read(PMC + APBDEV_PMC_SECURE_SCRATCH24), reg::Read(PMC + APBDEV_PMC_SECURE_SCRATCH25), reg::Read(PMC + APBDEV_PMC_SECURE_SCRATCH26), reg::Read(PMC + APBDEV_PMC_SECURE_SCRATCH27)};
|
||||
se::ClearAesKeySlot(pkg1::AesKeySlot_TzramSaveKey);
|
||||
se::SetEncryptedAesKey256(pkg1::AesKeySlot_TzramSaveKey, pkg1::AesKeySlot_TzramSaveKek, key_source, sizeof(key_source));
|
||||
|
||||
/* Decrypt tzram. */
|
||||
const u8 tzram_iv[se::AesBlockSize] = {};
|
||||
se::DecryptAes256Cbc(tzram_dst, tzram_size, pkg1::AesKeySlot_TzramSaveKey, tzram_src, tzram_size, tzram_iv, sizeof(tzram_iv));
|
||||
|
||||
/* Calculate the cmac of decrypted tzram. */
|
||||
u8 tzram_mac[se::AesBlockSize] = {};
|
||||
se::ComputeAes256Cmac(tzram_mac, sizeof(tzram_mac), pkg1::AesKeySlot_TzramSaveKey, tzram_dst, tzram_size);
|
||||
|
||||
/* Get the expected mac from pmc scratch. */
|
||||
const u32 expected_mac[sizeof(tzram_mac) / sizeof(u32)] = { reg::Read(PMC + APBDEV_PMC_SECURE_SCRATCH112), reg::Read(PMC + APBDEV_PMC_SECURE_SCRATCH113), reg::Read(PMC + APBDEV_PMC_SECURE_SCRATCH114), reg::Read(PMC + APBDEV_PMC_SECURE_SCRATCH115)};
|
||||
|
||||
/* Validate that the calculated mac is correct. */
|
||||
AMS_ABORT_UNLESS(crypto::IsSameBytes(tzram_mac, expected_mac, sizeof(tzram_mac)));
|
||||
}
|
||||
|
||||
void RestoreSecureMonitorToTzramErista(const TargetFirmware target_fw) {
|
||||
/* Clear all unsaved security engine keyslots. */
|
||||
ClearUnsavedSecurityEngineKeySlots();
|
||||
|
||||
/* Restore encrypted tzram contents. */
|
||||
void * const tzram_src = secmon::MemoryRegionPhysicalDramSecureDataStoreTzram.GetPointer<void>();
|
||||
void * const tzram_dst = secmon::MemoryRegionPhysicalTzramNonVolatile.GetPointer<void>();
|
||||
const size_t tzram_size = secmon::MemoryRegionPhysicalTzramNonVolatile.GetSize();
|
||||
RestoreEncryptedTzram(tzram_dst, tzram_src, tzram_size);
|
||||
|
||||
/* Clear the tzram kek registers. */
|
||||
reg::Write(PMC + APBDEV_PMC_SECURE_SCRATCH24, 0);
|
||||
reg::Write(PMC + APBDEV_PMC_SECURE_SCRATCH25, 0);
|
||||
reg::Write(PMC + APBDEV_PMC_SECURE_SCRATCH26, 0);
|
||||
reg::Write(PMC + APBDEV_PMC_SECURE_SCRATCH27, 0);
|
||||
|
||||
/* Clear the tzram cmac registers. */
|
||||
reg::Write(PMC + APBDEV_PMC_SECURE_SCRATCH112, 0);
|
||||
reg::Write(PMC + APBDEV_PMC_SECURE_SCRATCH113, 0);
|
||||
reg::Write(PMC + APBDEV_PMC_SECURE_SCRATCH114, 0);
|
||||
reg::Write(PMC + APBDEV_PMC_SECURE_SCRATCH115, 0);
|
||||
|
||||
/* Clear the keydata used to protect tzram. */
|
||||
se::ClearAesKeySlot(pkg1::AesKeySlot_TzramSaveKek);
|
||||
se::ClearAesKeySlot(pkg1::AesKeySlot_TzramSaveKey);
|
||||
|
||||
/* Clear the encrypted copy of tzram in dram. */
|
||||
/* NOTE: This does not actually clear the encrypted copy, because BPMP access to main memory has been restricted. */
|
||||
/* Nintendo seems to not realize this, though, so we'll do the same. */
|
||||
std::memset(tzram_src, 0, tzram_size);
|
||||
|
||||
/* Set Tzram to secure-world only. */
|
||||
se::SetTzramSecure();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RestoreSecureMonitorToTzram(const TargetFirmware target_fw) {
|
||||
/* If erista, perform restoration procedure. */
|
||||
if (fuse::GetSocType() == fuse::SocType_Erista) {
|
||||
RestoreSecureMonitorToTzramErista(target_fw);
|
||||
}
|
||||
|
||||
/* Lock secure scratch. */
|
||||
pmc::LockSecureRegister(static_cast<pmc::SecureRegister>(pmc::SecureRegister_DramParameters | pmc::SecureRegister_Other));
|
||||
|
||||
/* Lockout fuses. */
|
||||
fuse::Lockout();
|
||||
}
|
||||
|
||||
}
|
23
warmboot_secure_monitor.hpp
Normal file
23
warmboot_secure_monitor.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
void RestoreSecureMonitorToTzram(const TargetFirmware target_fw);
|
||||
|
||||
}
|
36
warmboot_start.s
Normal file
36
warmboot_start.s
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
.section .text._ZN3ams8warmboot5StartEv, "ax", %progbits
|
||||
.align 3
|
||||
.global _ZN3ams8warmboot5StartEv
|
||||
_ZN3ams8warmboot5StartEv:
|
||||
/* Set CPSR_cf and CPSR_cf. */
|
||||
msr cpsr_f, #0xC0
|
||||
msr cpsr_cf, #0xD3
|
||||
|
||||
/* Set the stack pointer. */
|
||||
ldr sp, =__stack_top__
|
||||
|
||||
/* Set our link register to the exception handler. */
|
||||
ldr lr, =_ZN3ams8warmboot16ExceptionHandlerEv
|
||||
|
||||
/* Invoke main. */
|
||||
ldr r0, =_metadata
|
||||
bl _ZN3ams8warmboot4MainEPKNS0_8MetadataE
|
||||
|
||||
/* Infinite loop. */
|
||||
1: b 1b
|
23
warmboot_util.hpp
Normal file
23
warmboot_util.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::warmboot {
|
||||
|
||||
void SpinLoop(unsigned int num);
|
||||
|
||||
}
|
30
warmboot_util_asm.s
Normal file
30
warmboot_util_asm.s
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
.section .text._ZN3ams8warmboot8SpinLoopEj, "ax", %progbits
|
||||
.global _ZN3ams8warmboot8SpinLoopEj
|
||||
.thumb_func
|
||||
.syntax unified
|
||||
_ZN3ams8warmboot8SpinLoopEj:
|
||||
1:
|
||||
/* Subtract one from the count. */
|
||||
subs r0, r0, #1
|
||||
|
||||
/* If we aren't at zero, continue looping. */
|
||||
bgt 1b
|
||||
|
||||
/* Return. */
|
||||
bx lr
|
Loading…
Add table
Reference in a new issue