Compare commits
183 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2677cf68d4 | ||
|
|
cedbcba3e3 | ||
|
|
5b1bb71787 | ||
|
|
7d4a257d57 | ||
|
|
051789c430 | ||
|
|
0e4c300745 | ||
|
|
f99dea798a | ||
|
|
f15fc6645e | ||
|
|
c56db864eb | ||
|
|
5b4e81aa8b | ||
|
|
e75f4e9f5a | ||
|
|
08d1e9b880 | ||
|
|
b2fb42e39d | ||
|
|
776ab21641 | ||
|
|
031c9e545b | ||
|
|
c6f06e2c40 | ||
|
|
c9c8f64f09 | ||
|
|
9bc45475f4 | ||
|
|
8bf8503fcd | ||
|
|
8a73ad996a | ||
|
|
24f74312f2 | ||
|
|
5f179cf19f | ||
|
|
254ac59016 | ||
|
|
2711702e29 | ||
|
|
18ee6eb2e6 | ||
|
|
4711d0565d | ||
|
|
f61f5feaf4 | ||
|
|
2165555170 | ||
|
|
260a819fd2 | ||
|
|
83025080c8 | ||
|
|
b6684ff845 | ||
|
|
deb124138b | ||
|
|
eeef08e58e | ||
|
|
295574740d | ||
|
|
a52e601f2e | ||
|
|
d349bdb1f8 | ||
|
|
caba025e97 | ||
|
|
add52b90c9 | ||
|
|
c42fc16d8e | ||
|
|
a09137c008 | ||
|
|
2a2d1bc78b | ||
|
|
50db685274 | ||
|
|
d0285fb57c | ||
|
|
a899a61f80 | ||
|
|
da0d22f05a | ||
|
|
35cf3b65a3 | ||
|
|
d0505d3c11 | ||
|
|
d1abc53d33 | ||
|
|
36a727ef81 | ||
|
|
3ce32d2014 | ||
|
|
a01d0e94f8 | ||
|
|
34c16e211f | ||
|
|
95a9e1e215 | ||
|
|
3924a2ef76 | ||
|
|
4f9ecc9d50 | ||
|
|
f6bc4abfd0 | ||
|
|
7a704827f1 | ||
|
|
72594c6783 | ||
|
|
754aaecc18 | ||
|
|
b419c0df29 | ||
|
|
a4ce50ffd5 | ||
|
|
802830d8d4 | ||
|
|
83941f8647 | ||
|
|
8d08e60916 | ||
|
|
0b15539479 | ||
|
|
a94bee71d2 | ||
|
|
5f905c6b42 | ||
|
|
e0f1e637f7 | ||
|
|
fc4912ef54 | ||
|
|
dca51291aa | ||
|
|
b72a68f622 | ||
|
|
a9a71fbeed | ||
|
|
84c776fa6b | ||
|
|
a21b5d453a | ||
|
|
0ef3368893 | ||
|
|
4827fd71b4 | ||
|
|
00aa283a54 | ||
|
|
ef373d954f | ||
|
|
d452d6f89d | ||
|
|
a51d355707 | ||
|
|
a79f4cf6f6 | ||
|
|
903789cf6e | ||
|
|
49ba3a86e2 | ||
|
|
021d84ff04 | ||
|
|
8ecf68cb65 | ||
|
|
bbed78149c | ||
|
|
3fa973f430 | ||
|
|
bd76e73b25 | ||
|
|
fc426a06b2 | ||
|
|
ef17dc16fa | ||
|
|
ed4a999caa | ||
|
|
6b3662d047 | ||
|
|
33b7e227d4 | ||
|
|
be5b58d033 | ||
|
|
8d3b8354c3 | ||
|
|
25956c4fa1 | ||
|
|
5201803685 | ||
|
|
c6003ff530 | ||
|
|
72f028efae | ||
|
|
72a2c10896 | ||
|
|
49ad66e478 | ||
|
|
bcdfc53d7d | ||
|
|
ed37706915 | ||
|
|
e321f0ac04 | ||
|
|
87c0c8b83e | ||
|
|
7bc95f35d7 | ||
|
|
ae4d29a49f | ||
|
|
67ff4fe913 | ||
|
|
dd255df90d | ||
|
|
ab33329129 | ||
|
|
767a4b3606 | ||
|
|
a71d98d78b | ||
|
|
c3569ec5e2 | ||
|
|
eab5e0df9b | ||
|
|
e214f4d325 | ||
|
|
982797df31 | ||
|
|
77bbb0ef78 | ||
|
|
13aa774d7a | ||
|
|
6e7eb47d33 | ||
|
|
a07e37121d | ||
|
|
d88fd04c73 | ||
|
|
abde50f162 | ||
|
|
2b4e6bf25d | ||
|
|
ff09efb1bf | ||
|
|
cff283f77d | ||
|
|
e0c7bfc93d | ||
|
|
ac391d9c5e | ||
|
|
46cc08160d | ||
|
|
7e3b5c37d0 | ||
|
|
a00e120bf7 | ||
|
|
1932662b4c | ||
|
|
b4781b8a4f | ||
|
|
83644692fe | ||
|
|
420361597e | ||
|
|
05187502b3 | ||
|
|
878ac59aae | ||
|
|
e1cc1b8d29 | ||
|
|
d95fc102db | ||
|
|
66da896347 | ||
|
|
c530bb8910 | ||
|
|
8054b2d219 | ||
|
|
7c61e935ee | ||
|
|
e5e9968d22 | ||
|
|
962fa0a690 | ||
|
|
9714db14d2 | ||
|
|
50c65ea7e1 | ||
|
|
98bdb2a7a3 | ||
|
|
d4ee772714 | ||
|
|
fa9d7f40fc | ||
|
|
20026587fd | ||
|
|
f16423c413 | ||
|
|
1bface09d5 | ||
|
|
560d899a9b | ||
|
|
2838e41819 | ||
|
|
8550f722ca | ||
|
|
9f6ff2ed6e | ||
|
|
164fb96da0 | ||
|
|
31c1338dba | ||
|
|
7d729e1836 | ||
|
|
36530a5501 | ||
|
|
1aba87ef76 | ||
|
|
b19e50e720 | ||
|
|
caf9d11c8c | ||
|
|
f7a7ce1847 | ||
|
|
893bad0db2 | ||
|
|
29833539bb | ||
|
|
f914edeebd | ||
|
|
5f3187300d | ||
|
|
5d5f8ad3d5 | ||
|
|
f8abd2b402 | ||
|
|
6335d21901 | ||
|
|
5649b6d63f | ||
|
|
e96eaa3d7c | ||
|
|
aa86d1abfa | ||
|
|
1228cd6903 | ||
|
|
6f240b1665 | ||
|
|
13e5043d64 | ||
|
|
b771c42f7f | ||
|
|
4d1481e2eb | ||
|
|
21b0f228b6 | ||
|
|
b9091e9466 | ||
|
|
a520481168 | ||
|
|
8daa2da97c |
47
.github/ISSUE_TEMPLATE/bug_report.md
vendored
47
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,25 +1,56 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Something doesn't work correctly in Atmosphère.
|
||||
|
||||
#assignees:
|
||||
---
|
||||
|
||||
## Bug Report
|
||||
|
||||
[ If any section does not apply, replace its contents with "N/A". ]</br>
|
||||
[ Lines between [ ] (square brackets) should be removed before posting. ]</br>
|
||||
|
||||
[ * ]</br>
|
||||
[ Note: If the bug or crash you encountered is related to; ]</br>
|
||||
[ - software used to make "backups", ]</br>
|
||||
[ - software explicitly distributed for piracy, etc ]</br>
|
||||
[ then contributors will not provide support for your issue and your issue will be closed. ]</br>
|
||||
|
||||
### What's the issue you encountered?
|
||||
|
||||
[ Describe the issue in detail and what you were doing beforehand. ]</br>
|
||||
[ Did you make any changes related to Atmosphère itself? ]</br>
|
||||
[ If so, make sure to include details relating to what exactly you changed. ]</br>
|
||||
|
||||
### How can the issue be reproduced?
|
||||
|
||||
### Crash report?
|
||||
[ * ]</br>
|
||||
[ Include a detailed step by step process for recreating your issue. ]</br>
|
||||
|
||||
(If a crash report was created under /atmosphere/crash_reports/, please upload it to
|
||||
[gist](https://gist.github.com/) and paste the link here.)
|
||||
### Crash Report
|
||||
|
||||
[ Crash reports can be found under ``/atmosphere/crash_reports``. ]</br>
|
||||
[ If your issue caused Atmosphère to crash, include the crash report(s) by creating a [gist](https://gist.github.com/) and pasting the link here. ]</br>
|
||||
[ If you don't include a crash report in instances of crash related issues, we will ask you one to provide one. ]</br>
|
||||
|
||||
### System Firmware Version
|
||||
|
||||
X.X.X</br>
|
||||
[ Replace X's with system firmware version at time of crash. ]</br>
|
||||
[ You can find your firmware version in the Settings -> System, under "System Update". ]</br>
|
||||
[ If it says "Update Pending", you can clear the pending update by rebooting to Maintenance Mode. ]</br>
|
||||
|
||||
### Environment?
|
||||
|
||||
- What bootloader (fusee, hekate, etc) was Atmosphère launched by:
|
||||
- Official release or unofficial build:
|
||||
- Do you have additional kips you're loading:
|
||||
- Additional info about your environment:
|
||||
- What bootloader (fusèe, hekate, etc) was Atmosphère launched by:
|
||||
- Official release or unofficial build:
|
||||
- [ Offical release version x.x.x (or) unofficial build ]
|
||||
- [ If using an unofficial build, include details on where/how you acquired the build. ]
|
||||
- [ Ex: Self-compilation ]
|
||||
- [ Ex: Kosmos' distribution of Atmosphère ]
|
||||
- Do you have additional kips or sysmodules you're loading:
|
||||
- Homebrew software installed: [ * ]
|
||||
|
||||
### Additional context?
|
||||
|
||||
- Additional info about your environment:
|
||||
- [ Any other information relevant to your issue. ]
|
||||
|
||||
42
.github/ISSUE_TEMPLATE/feature_request.md
vendored
42
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,12 +1,48 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: You want to suggest a new feature for Atmosphère.
|
||||
|
||||
about: Suggest a new feature for Atmosphère.
|
||||
#assignees:
|
||||
---
|
||||
|
||||
## Feature Request
|
||||
|
||||
[ If any section does not apply, replace its contents with "N/A". ]</br>
|
||||
[ If you do not have the information needed for a section, replace its contents with "Unknown". ]</br>
|
||||
[ Lines between [ ] (square brackets) are to be removed before posting. ]
|
||||
|
||||
[ Please search for existing [feature requests](https://github.com/Atmosphere-NX/Atmosphere/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22features%2Ffeature-request%22) before you make your own request. ]</br>
|
||||
[ Duplicate requests will be marked as such and you will be referred to the original request. ]
|
||||
|
||||
### What feature are you suggesting?
|
||||
#### Overview:
|
||||
- [ Include the basic, high-level concepts for this feature here. ]</br>
|
||||
|
||||
#### Smaller Details:
|
||||
- [ These may include specific methods of implementation etc. ]</br>
|
||||
|
||||
#### Nature of Request:
|
||||
[ Remove all that do not apply to your request. ]
|
||||
- Addition
|
||||
- [ Ex: Addition of certain original features or features from other community projects. ]
|
||||
- [ If you are suggesting porting features or including features from other projects, include what license they are distributed under and what, if any libraries those project use. ]
|
||||
- Change
|
||||
- Removal
|
||||
- [Ex: Removal of certain features or implementation due to a specific issue/bug or because of low quality code, etc.]
|
||||
|
||||
### What component do you feel this would best fit within?
|
||||
- [Fusée](https://github.com/Atmosphere-NX/Atmosphere#components)</br>
|
||||
- Atmosphère's custom bootloader.</br>
|
||||
- [Exosphère](https://github.com/Atmosphere-NX/Atmosphere#components)</br>
|
||||
- Fully-featured custom secure monitor.</br>
|
||||
- [Stratosphère](https://github.com/Atmosphere-NX/Atmosphere#components)</br>
|
||||
- Custom system modules.</br>
|
||||
- [**Thermosphère**](https://github.com/Atmosphere-NX/Atmosphere#components)</br>
|
||||
- Atmosphère's emuNAND implementation.</br>
|
||||
- [**Troposphère**](https://github.com/Atmosphere-NX/Atmosphere#components)</br>
|
||||
- Application-level patches to the Horizon OS.</br>
|
||||
|
||||
[ Note: **Bolded components are not implemented** or are still at the prototyping phase. ]
|
||||
|
||||
### Why would this feature be useful?
|
||||
|
||||
[ If this is a feature for an end-user, how does it benefit the end-user? ]</br>
|
||||
[ If this feature is for developers, what does it add to Atmosphère that did not already exist? ]</br>
|
||||
|
||||
15
.github/ISSUE_TEMPLATE/question.md
vendored
15
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -1,12 +1,7 @@
|
||||
---
|
||||
name: Question
|
||||
about: Please ask questions in the ReSwitched discord, instead of making issues.
|
||||
|
||||
---
|
||||
|
||||
We would like to use GitHub to keep track of problems/feature requests.
|
||||
|
||||
If you have a question, please join the ReSwitched discord for help.
|
||||
|
||||
- Discord link: https://discordapp.com/invite/DThbZ7z
|
||||
|
||||
about: Please ask questions in the ReSwitched discord, instead of making issues.
|
||||
---
|
||||
We would like to use GitHub to keep track of problems/feature requests.
|
||||
If you have a question, please join the ReSwitched discord for help.
|
||||
- Discord link: https://discordapp.com/invite/DThbZ7z
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -65,6 +65,14 @@ dkms.conf
|
||||
*.tgz
|
||||
*.zip
|
||||
|
||||
# IDA binaries
|
||||
*.id0
|
||||
*.id1
|
||||
*.id2
|
||||
*.idb
|
||||
*.nam
|
||||
*.til
|
||||
|
||||
.**/
|
||||
|
||||
# NOTE: make sure to make exceptions to this pattern when needed!
|
||||
|
||||
19
Makefile
19
Makefile
@@ -6,7 +6,7 @@ ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
all: fusee stratosphere exosphere thermosphere
|
||||
all: fusee stratosphere exosphere thermosphere troposphere
|
||||
|
||||
thermosphere:
|
||||
$(MAKE) -C thermosphere all
|
||||
@@ -17,6 +17,9 @@ exosphere: thermosphere
|
||||
stratosphere: exosphere
|
||||
$(MAKE) -C stratosphere all
|
||||
|
||||
troposphere: stratosphere
|
||||
$(MAKE) -C troposphere all
|
||||
|
||||
fusee: exosphere stratosphere
|
||||
$(MAKE) -C $@ all
|
||||
|
||||
@@ -39,14 +42,22 @@ dist: all
|
||||
rm -rf out
|
||||
mkdir atmosphere-$(AMSVER)
|
||||
mkdir atmosphere-$(AMSVER)/atmosphere
|
||||
mkdir atmosphere-$(AMSVER)/switch
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032
|
||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/fusee-secondary.bin
|
||||
cp common/defaults/BCT.ini atmosphere-$(AMSVER)/BCT.ini
|
||||
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
||||
cp common/defaults/BCT.ini atmosphere-$(AMSVER)/atmosphere/BCT.ini
|
||||
cp common/defaults/loader.ini atmosphere-$(AMSVER)/atmosphere/loader.ini
|
||||
cp common/defaults/system_settings.ini atmosphere-$(AMSVER)/atmosphere/system_settings.ini
|
||||
cp -r common/defaults/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches
|
||||
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036/exefs.nsp
|
||||
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034/exefs.nsp
|
||||
cp stratosphere/set_mitm/set_mitm.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/exefs.nsp
|
||||
touch atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/boot2.flag
|
||||
cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/flags
|
||||
touch atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/flags/boot2.flag
|
||||
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
|
||||
rm -r atmosphere-$(AMSVER)
|
||||
mkdir out
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
=====
|
||||
|
||||

|
||||
[](https://discordapp.com/invite/ZdqEhed)
|
||||
|
||||
Atmosphère is a work-in-progress customized firmware for the Nintendo Switch.
|
||||
|
||||
@@ -20,7 +21,7 @@ Atmosphère consists of multiple components, each of which replaces/modifies a d
|
||||
Credits
|
||||
=====
|
||||
|
||||
Atmosphère is currently being developed and maintained by __SciresM__, __TuxSH__ and __hexkyz__.<br>
|
||||
Atmosphère is currently being developed and maintained by __SciresM__, __TuxSH__, __hexkyz__, and __fincs__.<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.
|
||||
@@ -29,7 +30,7 @@ In no particular order, we credit the following for their invaluable contributio
|
||||
* __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.
|
||||
* __CTCaer__ for the continued [hekate](https://github.com/CTCaer/hekate) project's fork and the [minerva_tc](https://github.com/CTCaer/minerva_tc) 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.
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
BCT0
|
||||
[stage1]
|
||||
stage2_path = fusee-secondary.bin
|
||||
stage2_path = atmosphere/fusee-secondary.bin
|
||||
stage2_addr = 0xF0000000
|
||||
stage2_entrypoint = 0xF0000000
|
||||
stage2_entrypoint = 0xF0000000
|
||||
|
||||
[exosphere]
|
||||
; Note: Disabling debugmode will cause parts of ams.tma to not work, in the future.
|
||||
debugmode = 1
|
||||
debugmode_user = 0
|
||||
|
||||
[stratosphere]
|
||||
; To force-enable nogc, add nogc = 1
|
||||
; To force-disable nogc, add nogc = 0
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
6
common/defaults/system_settings.ini
Normal file
6
common/defaults/system_settings.ini
Normal file
@@ -0,0 +1,6 @@
|
||||
; Disable uploading error reports to Nintendo
|
||||
[eupld]
|
||||
upload_enabled = u8!0x0
|
||||
; Enable USB 3.0 superspeed for homebrew
|
||||
[usb]
|
||||
usb30_force_enabled = u8!0x1
|
||||
@@ -22,6 +22,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include "atmosphere/version.h"
|
||||
#include "atmosphere/target_fw.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
36
common/include/atmosphere/target_fw.h
Normal file
36
common/include/atmosphere/target_fw.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 ATMOSPHERE_TARGET_FIRMWARE_H
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_H
|
||||
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_100 1
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_200 2
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_300 3
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_400 4
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_500 5
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_600 6
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_620 7
|
||||
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_620
|
||||
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE_100
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_620
|
||||
|
||||
/* TODO: What should this be, for release? */
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG ATMOSPHERE_TARGET_FIRMWARE_CURRENT
|
||||
|
||||
#endif
|
||||
@@ -18,7 +18,7 @@
|
||||
#define ATMOSPHERE_VERSION_H
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 7
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 4
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 8
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 3
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,115 @@
|
||||
# Changelog
|
||||
## 0.8.3
|
||||
+ A custom warmboot firmware was implemented, which does not perform anti-downgrade fuse checks.
|
||||
+ This fixes sleep mode when using a downgraded NAND.
|
||||
+ This also removes Atmosphère's final dependency on Nintendo's encrypted PK11 binary; all components are now re-implemented.
|
||||
+ The ExternalContentSource API was changed to not clear on failure.
|
||||
+ Content override now supports an "app" setting, that causes all applications to be overridden with HBL instead of a specific title.
|
||||
+ Note: because override keys are system-wide, using this setting will prevent using mods in games (as every game will be HBL).
|
||||
+ A bug was fixed causing incorrect fatal-error output when svcBreak was called on 5.0.0+.
|
||||
+ An extension was added to set.mitm to support customization of system settings.
|
||||
+ These are controlled by `atmosphere/system_settings.ini`, see [here](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/modules/set_mitm.md) for documentation.
|
||||
+ An extension was added to sm, adding a new `sm:dmnt` service.
|
||||
+ This can be used by a debug monitor in order to debug the registration state of various other services.
|
||||
+ A bug was fixed in the MitM API that could sometimes cause a system hang during boot.
|
||||
+ A change was made to the MitM API: in cases where sm would have returned 0xE15 when installing a mitm service, it now defers the result (following GetService semantics).
|
||||
+ Support for booting into maintenance mode by holding +/- was added to PM.
|
||||
+ An extension was added to exosphere, adding a custom SMC that allows for DMA to IRAM.
|
||||
+ In addition, smcGetConfig was extended to reboot to a payload in IRAM at 0x40010000 when ConfigItem 65001 is set to 2.
|
||||
+ Fatal will now use this to reboot to sdmc:/atmosphere/reboot_payload.bin if present, when a vol button is pressed.
|
||||
+ An example homebrew ("reboot_to_payload") was also written and is now included with Atmosphère.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.8.2
|
||||
+ A number of bugs were fixed causing users to sometimes see `Key Derivation Failed!`.
|
||||
+ KFUSE clock enable timings have been adjusted to allow time to stabilize before TSEC is granted access.
|
||||
+ A race condition was fixed that could cause wrong key data to be used on 6.2.0
|
||||
+ The TSEC firmware is now retried on failure, fixing a failure affecting ~1/50 boots on 6.2.0.
|
||||
+ A bug was fixed causing some modules to not work on firmware 1.0.0.
|
||||
+ A bug was fixed causing sleep mode to not work with debugmode enabled.
|
||||
+ As a result, debugmode is now enabled in the default BCT.ini.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.8.1
|
||||
+ A bug was fixed causing users to see `Failed to enable SMMU!` if fusee had previously rebooted.
|
||||
+ This message will still occur sporadically if fusee is not launched from coldboot, but it can never happen twice in a row.
|
||||
+ A race condition was fixed in Atmosphere `bis_protect` functionality that could cause NS to be able to overwrite BCT public keys.
|
||||
+ This sometimes broke AutoRCM protection, the current fix has been tested on hardware and verified to work.
|
||||
+ Support was added for enabling `debugmode` based on the `exosphere` section of `BCT.ini`:
|
||||
+ Setting `debugmode = 1` will cause exosphere to tell the kernel that debugmode is active.
|
||||
+ Setting `debugmode_user = 1` will cause exosphere to tell userland that debugmode is active.
|
||||
+ These are completely independent of one another, allowing fine control of system behavior.
|
||||
+ Support was added for `nogc` functionality; thanks to @rajkosto for the patches.
|
||||
+ By default, `nogc` patches will automatically apply if the user is booting into 4.0.0+ with fuses from <= 3.0.2.
|
||||
+ Users can override this functionality via the `nogc` entry in the `stratosphere` section of `BCT.ini`:
|
||||
+ Setting `nogc = 1` will force enable `nogc` patches.
|
||||
+ Setting `nogc = 0` will force disable `nogc` patches.
|
||||
+ If patches are enabled but not found for the booting system, a fatal error will be thrown.
|
||||
+ This should prevent running FS without `nogc` patches after updating to an unsupported system version.
|
||||
+ An extension was added to `exosphere` allowing userland applications to cause the system to reboot into RCM:
|
||||
+ This is done by calling smcSetConfig(id=65001, value=<nonzero>); user homebrew can use splSetConfig for this.
|
||||
+ On fatal error, the user can now choose to perform a standard reboot via the power button, or a reboot into RCM via either volume button.
|
||||
+ A custom message was added to `fatal` for when an Atmosphère API version mismatch is detected (2495-1623).
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.8.0
|
||||
+ A custom `fatal` system module was added.
|
||||
+ This re-implements and extends Nintendo's fatal module, with the following features:
|
||||
+ Atmosphère's `fatal` does not create error reports.
|
||||
+ Atmosphère's `fatal` draws a custom error screen, showing registers and a backtrace.
|
||||
+ Atmosphère's `fatal` attempts to gather debugging info for all crashes, and not just ones that include info.
|
||||
+ Atmosphère's `fatal` will attempt saving reports to the SD, if a crash report was not generated by `creport`.
|
||||
+ Title flag handling was changed to prevent folder clutter.
|
||||
+ Instead of living in `atmosphere/titles/<tid>/%s.flag`, flags are now located in `atmosphere/titles/<tid>/flags/%s.flag`
|
||||
+ The old format will continue to be supported for some time, but is deprecated.
|
||||
+ Flags can now be applied to HBL by placing them at `atmosphere/flags/hbl_%s.flag`.
|
||||
+ Changes were made to the mitm API, greatly improving caller semantics.
|
||||
+ `sm` now informs mitm services of a new session's process id, enabling custom handling based on title id/process id.
|
||||
+ smhax is no longer enabled, because it is no longer needed and breaks significant functionality.
|
||||
+ Users with updated HBL/homebrew should see no observable differences due to this change.
|
||||
+ Functionality was added implementing basic protections for NAND from userland homebrew:
|
||||
+ BOOT0 now has write protection for the BCT public key and keyblob regions.
|
||||
+ The `ns` sysmodule is no longer allowed to write the BCT public keys; all other processes can.
|
||||
+ This should prevent system updates from removing AutoRCM.
|
||||
+ No processes should be allowed to write to the keyblob region.
|
||||
+ By default, BIS partitions other than BOOT0 are now read-only, and CAL0 is neither readable nor writable.
|
||||
+ Adding a `bis_write` flag for a title will allow it to write to BIS.
|
||||
+ Adding a `cal_read` flag for a title will allow it to read CAL0.
|
||||
+ An automatic backup is now made of CAL0 on boot.
|
||||
+ `fs.mitm` maintains a file handle to this backup, so userland software cannot read it.
|
||||
+ To facilitate this, `fs.mitm` now mitms all sessions for non-system modules; content overriding has been made separate from service interception.
|
||||
+ Please note: these protections are basic, and sufficiently malicious homebrew ++can defeat them++.
|
||||
+ Please be careful to only run homebrew software from sources that you trust.
|
||||
+ A bug involving HDCP titles crashing on newer firmwares was fixed.
|
||||
+ Support was added for system version 6.2.0; our thanks to @motezazer for his invaluable help.
|
||||
+ By default, new keys will automatically be derived without user input.
|
||||
+ Support is also present for loading new keys from `atmosphere/prod.keys` or `atmosphere/dev.keys`
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.7.5
|
||||
+ DRAM training was added to fusee-secondary, courtesy @hexkyz.
|
||||
+ This greatly improves the speed of memory accesses during boot, resulting in a boot time that is ~200-400% faster.
|
||||
+ creport has had its code region detection improved.
|
||||
+ Instead of only checking one of the crashing thread's PC/LR for code region presence, creport now checks both + every address in the stacktrace. This is also now done for every thread.
|
||||
+ This matches the improvement Nintendo added to official creport in 6.1.0.
|
||||
+ The code region detection heuristic was further improved by checking whether an address points to .rodata or .rwdata, instead of just .text.
|
||||
+ This means that a crash appears in a loaded NRO (or otherwise discontiguous) code region, creport will be able to detect all active code regions, and not just that one.
|
||||
## 0.7.4
|
||||
+ [libstratosphere](https://github.com/Atmosphere-NX/libstratosphere) has been completely refactored/rewritten, and split into its own, separate submodule.
|
||||
+ While this is mostly "under the hood" for end-users, the refactor is faster (improving both boot-time and runtime performance), more accurate (many of the internal IPC structures are now bug-for-bug compatible with Nintendo's implementations), and significantly more stable (it fixes a large number of bugs present in the old library).
|
||||
+ The refactored API is significantly cleaner and easier to write system module code for, which should improve/speed up development of stratosphere.
|
||||
+ Developers looking to write their own custom system modules for the Switch can now easily include libstratosphere as a submodule in their projects.
|
||||
+ Loader was extended to add a new generic way to redirect content (ExternalContentSources), courtesy @misson20000:
|
||||
+ A new command was added to ldr:shel, taking in a tid to redirect and returning a session handle.
|
||||
+ When the requested TID is loading, Loader will query the handle as though it were an IFileSystem.
|
||||
+ This allows clients to generically define their own filesystems, and override content with them in loader.
|
||||
+ fs.mitm has gotten several optimizations that should improve its performance and stability:
|
||||
+ RomFS redirection now only occurs when there is content to redirect, even if the title is being mitm'd elsewhere.
|
||||
+ A cache is now maintained of the active data storage, if any, for all opened title IDs. This means if two processes both try to open the same archive, fs.mitm won't duplicate any of its work.
|
||||
+ RomFS metadata is now cached to the SD card on build instead of being persisted in memory -- this greatly reduces memory footprint and allows fs.mitm to redirect more titles simultaneously than before.
|
||||
+ A number of bugs were fixed, including:
|
||||
+ A resource leak was fixed in process creation. This fixes crashes that occur when a large number (>32) games have been launched since the last reboot.
|
||||
+ fs.mitm no longer errors when receiving a zero-sized buffer. This fixes crashes in some games, including The Messenger.
|
||||
+ Multi-threaded server semantics should no longer cause deadlocks in certain circumstances. This fixes crashes in some games, including NES Classics.
|
||||
+ PM now only gives full FS permissions to the active KIPs. This fixes a potential crash where new processes might be unable to be registered with FS.
|
||||
+ The `make dist` target now includes the branch in the generated zip name.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.7.3
|
||||
+ Loader and fs.mitm now try to reload loader.ini before reading it. This allows for changing the override button combination/HBL title id at runtime.
|
||||
+ Added a MitM between set:sys and qlaunch, used to override the system version string displayed in system settings.
|
||||
|
||||
12
docs/flags.md
Normal file
12
docs/flags.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Flags
|
||||
Atmosphère supports customizing CFW behavior based on the presence of `flags` on the SD card.
|
||||
|
||||
The following flags are supported on a per-title basis, by placing `<flag_name>.flag` inside `/atmosphere/titles/<title_id>/flags/`:
|
||||
+ `boot2`, which indicates to PM that the title should be launched during the `boot2` process.
|
||||
+ `fsmitm`, which indicates that `fs.mitm` should override contents for the title even if it otherwise wouldn't.
|
||||
+ `fsmitm_disable`, which indicates that `fs.mitm` should not override contents for the title, even it it otherwise would.
|
||||
+ `bis_write`, which indicates that `fs.mitm` should allow the title to write to BIS partitions.
|
||||
+ `cal_read`, which indicates that `fs.mitm` should allow the title to read the CAL0/PRODINFO partition.
|
||||
|
||||
The following global flags are supported, by placing `<flag name>.flag` inside `/atmosphere/flags/`:
|
||||
+ `hbl_bis_write` and `hbl_cal_read` enable the BIS write and CAL0 read functionality for HBL, without needing to specify its title id.
|
||||
@@ -66,3 +66,36 @@ For example, `override_key=!R` will run the game only while holding down R when
|
||||
### SM MITM Integration
|
||||
|
||||
When the Stratosphere implementation of loader creates a new process, it notifies [sm](sm.md) through the `AtmosphereAssociatePidTidForMitm` command to notify any MITM services of new processes' identities.
|
||||
|
||||
### IPC: AtmosphereSetExternalContentSource and AtmosphereClearExternalContentSource
|
||||
|
||||
Two additional commands are added to the [`ldr:shel`](https://reswitched.github.io/SwIPC/ifaces.html#nn::ro::detail::ILdrShellInterface) interface, called `AtmosphereSetExternalContentSource` and `AtmosphereClearExternalContentSource`.
|
||||
Their command IDs are `65000` and `65001` on all system firmware versions.
|
||||
|
||||
`AtmosphereSetExternalContentSource` takes a `u64 tid` and returns a server-side session handle.
|
||||
The client is expected to implement the `IFileSystem` interface on the returned handle. The next
|
||||
time the title specified by the given title ID is launched, its ExeFS contents will be loaded from
|
||||
the custom `IFileSystem` instead of from SD card or original ExeFS. NSOs loaded from external
|
||||
content source may still be subject to exefs IPS patches. After the title is launched successfuly,
|
||||
the `IFileSystem` is closed and the external content source override is removed. If
|
||||
`AtmosphereSetExternalContentSource` is called on a title that already has an external content
|
||||
source set for it, the existing one will be removed and replaced with the new one. It is illegal to
|
||||
call `AtmosphereSetExternalContentSource` while the title is being launched.
|
||||
|
||||
If title launching fails, the external content source remains registered. The
|
||||
`AtmosphereClearExternalContentSource` command can be used to clear an external content source if
|
||||
title launch fails.
|
||||
|
||||
The `IFileSystem` only needs to implement `OpenFile` and `GetFileTimeStampRaw`. The paths received
|
||||
by the `IFileSystem`'s `OpenFile` command begin with slashes, as in `/main`, `/rtld`, and `/main.npdm`.
|
||||
A result code of 0x202 should be returned if the file does not exist. `GetFileTimeStampRaw` can just
|
||||
be a stub. The `IFile`s returned from `OpenFile` only need to implement `Read` and `GetSize`.
|
||||
|
||||
The SwIPC definitions for the extension commands follow.
|
||||
```
|
||||
interface nn::ldr::detail::IShellInterface is ldr:shel {
|
||||
...
|
||||
[65000] AtmosphereSetExternalContentSource(u64 tid) -> handle<copy, session_server> ifilesystem_handle;
|
||||
[65001] AtmosphereClearExternalContentSource(u64 tid);
|
||||
}
|
||||
```
|
||||
|
||||
54
docs/modules/set_mitm.md
Normal file
54
docs/modules/set_mitm.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# set_mitm
|
||||
set_mitm is a sysmodule that enables intercepting requests to the system settings service.
|
||||
|
||||
## Atmosphère Extensions
|
||||
|
||||
set_mitm intercepts the `GetFirmwareVersion` command, if the requester is `qlaunch` or `maintenance`.\
|
||||
It modifies the `display_version` field of the returned system version, causing the version to display\
|
||||
in settings as `#.#.# (AMS #.#.#)`. This allows users to easily verify what version of Atmosphère they are running.
|
||||
|
||||
set_mitm also intercepts the `GetSettingsItemValueSize` and `GetSettingsItemValue` commands for all requesters.\
|
||||
It does so in order to enable user configuration of system settings, which are parsed from `atmosphere/system_settings.ini` on boot.\
|
||||
The format for settings is described below.
|
||||
|
||||
### Atmosphère Settings Format
|
||||
|
||||
Settings are parsed from the `atmosphere/system_settings.ini` file during the boot process. This file is a normal ini file,\
|
||||
with some specific interpretations.
|
||||
|
||||
The standard representation of a system setting's identifier takes the form `name!key`. This is represented within\
|
||||
`system_settings.ini` as a section `name`, with an entry `key`. For example:
|
||||
|
||||
```
|
||||
[name]
|
||||
key = ...
|
||||
```
|
||||
|
||||
System settings can have variable types (strings, integral values, byte arrays, etc). To accommodate this, `system_settings.ini`\
|
||||
must store values as a `type_identifier!value_store` pair. A number of different types are supported, with identifiers detailed below.\
|
||||
Please note that a malformed value string will cause a fatal error to occur on boot. A full example of a custom setting is given below\
|
||||
(setting `eupld!upload_enabled = 0`), for posterity:
|
||||
|
||||
```
|
||||
[eupld]
|
||||
upload_enabled = u8!0x0
|
||||
```
|
||||
|
||||
### Supported Types
|
||||
|
||||
* Strings
|
||||
* Type identifiers: `str`, `string`
|
||||
* The value string is used directly as the setting, with null terminator appended.
|
||||
* Integral types
|
||||
* Type identifiers: `u8`, `u16`, `u32`, `u64`
|
||||
* The value string is parsed via a call to `strtoul(value, NULL, 0)`.
|
||||
* Setting bitwidth is determined by the identifier (8 for 1 byte, 16 for 2 bytes, and so on).
|
||||
* Raw bytes
|
||||
* Type identifiers: `hex`, `bytes`
|
||||
* The value string is parsed as a hexadecimal string.
|
||||
* The value string must be of even length, or a fatal error will be thrown on parse.
|
||||
|
||||
### Atmosphère Custom Settings
|
||||
|
||||
At present, Atmosphère implements no custom settings. However, this is subject to change in the future, and any\
|
||||
custom settings will be documented here as they are added.
|
||||
@@ -20,6 +20,18 @@ interface nn::sm::detail::IUserInterface is sm: {
|
||||
}
|
||||
```
|
||||
|
||||
Additionally, an interface `sm:dmnt` has been created to allow a debug monitor to query sm's state.
|
||||
|
||||
Its SwIPC definition follows.
|
||||
```
|
||||
interface nn::sm::detail::IDebugMonitorInterface is sm:dmnt {
|
||||
[65000] AtmosphereGetServiceRecord(ServiceName name) -> SmServiceRecord;
|
||||
[65001] AtmosphereListServiceRecords(u64 offset) -> buffer<SmServiceRecord, 6>, u64 count;
|
||||
[65002] AtmosphereGetServiceRecordSize() -> u64 record_size;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### AtmosphereInstallMitm
|
||||
|
||||
This command alters the registration for the named service, in order to allow services to intercept communication between client processes and their intended services. It is used by [fs_mitm](fs_mitm.md).
|
||||
@@ -40,11 +52,11 @@ The `AssociatePidTid` command is invoked on all MITM query sessions whenever a n
|
||||
|
||||
If the process that installed the MITM attempts to connect to the service, it will always connect to the original service.
|
||||
|
||||
This command requires that the session be initialized, returning error code 0x415 if it is not.
|
||||
If the given service name is invalid, error code 0xC15 is returned.
|
||||
If the user does not have service registration permission for the named service, error code 0x1015 is returned.
|
||||
If the service has not yet been registered, error code 0xE15 is returned.
|
||||
If the service already has an MITM installed, error code 0x815 is returned.
|
||||
This command requires that the session be initialized, returning error code 0x415 if it is not.\
|
||||
If the given service name is invalid, error code 0xC15 is returned.\
|
||||
If the user does not have service registration permission for the named service, error code 0x1015 is returned.\
|
||||
If the service already has an MITM installed, error code 0x815 is returned.\
|
||||
If the service has not yet been registered, the request will be deferred until the service is registered in the same manner as IUserInterface::GetService.
|
||||
|
||||
#### AtmosphereUninstallMitm
|
||||
|
||||
@@ -58,6 +70,50 @@ This command is used internally by the Stratosphere implementation of the [loade
|
||||
|
||||
If the given process ID refers to a kernel internal process, error code 0x1015 is returned. This command requires that the session be initialized, returning error code 0x415 if it is not.
|
||||
|
||||
#### AtmosphereGetServiceRecordSize
|
||||
|
||||
Retrieves `sizeof(SmServiceRecord)` for a service. The current format of `SmServiceRecord` structure follows.
|
||||
|
||||
```
|
||||
struct SmServiceRecord {
|
||||
uint64_t service_name;
|
||||
uint64_t owner_pid;
|
||||
uint64_t max_sessions;
|
||||
uint64_t mitm_pid;
|
||||
uint64_t mitm_waiting_ack_pid;
|
||||
bool is_light;
|
||||
bool mitm_waiting_ack;
|
||||
};
|
||||
```
|
||||
|
||||
#### AtmosphereGetServiceRecord
|
||||
|
||||
Retrieves a service registration record for a service.
|
||||
|
||||
#### AtmosphereListServiceRecords
|
||||
|
||||
Provides a list of service registrations records.
|
||||
|
||||
The command will return an array of `SmServiceRecord`s, skipping `offset` records. The number of records returned is indicated by `count`.
|
||||
If `count` is less than the size of the buffer divided by `sizeof(SmServiceRecord)` (the buffer was not completely filled), the end of the service registration list has been reached. Otherwise, client code
|
||||
should increment `offset` by `count` and call again. Client code should retrieve a record size using `AtmosphereGetServiceRecordSize`, and either make sure that the size of a record matches what it expects,
|
||||
or should make sure to use the correct size as the stride while iterating over the array of returned records. Example pseudocode is shown below.
|
||||
|
||||
```
|
||||
offset = 0;
|
||||
record_size = AtmosphereGetServiceRecordSize();
|
||||
do {
|
||||
SmServiceRecord records[16];
|
||||
count = AtmosphereListServiceRecords(offset, buffer(records));
|
||||
for (i = 0; i < count; i++) {
|
||||
SmServiceRecord record = {0};
|
||||
memcpy(&record, &records[i], min(record_size, sizeof(SmServiceRecord));
|
||||
/* process record */
|
||||
offset++;
|
||||
}
|
||||
} while(count == sizeof(records) / record_size);
|
||||
```
|
||||
|
||||
### Minimum Session Limit
|
||||
|
||||
When a service is registered, the sysmodule registering it must specify a limit on the number of sessions that are allowed to be active for that service at a time. This is used to ensure that services like `fs-pr`, `fs-ldr`, and `ldr:pm` can only be connected to once, adding an additional layer of safety over the regular service verification to ensure that those services are only connected to by the highly priveleged process they are intended to be used by.
|
||||
|
||||
@@ -9,6 +9,13 @@ endif
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/devkitA64/base_rules
|
||||
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
||||
|
||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
@@ -26,7 +33,7 @@ INCLUDES := include ../common/include
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mgeneral-regs-only #<- important
|
||||
DEFINES := -D__CCPLEX__
|
||||
DEFINES := -D__CCPLEX__ -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
|
||||
CFLAGS := \
|
||||
-g \
|
||||
-O2 \
|
||||
@@ -68,14 +75,16 @@ export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
||||
$(TOPDIR)/bpmpfw
|
||||
$(TOPDIR)/lp0fw \
|
||||
$(TOPDIR)/sc7fw \
|
||||
$(TOPDIR)/rebootstub
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) bpmpfw.bin
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) sc7fw.bin lp0fw.bin rebootstub.bin
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
@@ -102,22 +111,30 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
.PHONY: $(BUILD) build_bpmpfw clean all
|
||||
.PHONY: $(BUILD) build_sc7fw build_lp0fw build_rebootstub clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
check_bpmpfw:
|
||||
@$(MAKE) -C bpmpfw all
|
||||
check_sc7fw:
|
||||
@$(MAKE) -C sc7fw all
|
||||
|
||||
$(BUILD): check_bpmpfw
|
||||
check_lp0fw:
|
||||
@$(MAKE) -C lp0fw all
|
||||
|
||||
check_rebootstub:
|
||||
@$(MAKE) -C rebootstub all
|
||||
|
||||
$(BUILD): check_sc7fw check_lp0fw check_rebootstub
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@$(MAKE) -C $(TOPDIR)/bpmpfw clean
|
||||
@$(MAKE) -C $(TOPDIR)/sc7fw clean
|
||||
@$(MAKE) -C $(TOPDIR)/lp0fw clean
|
||||
@$(MAKE) -C $(TOPDIR)/rebootstub clean
|
||||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
|
||||
|
||||
|
||||
|
||||
154
exosphere/lp0fw/Makefile
Normal file
154
exosphere/lp0fw/Makefile
Normal file
@@ -0,0 +1,154 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITARM)/base_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := src
|
||||
DATA := data
|
||||
INCLUDES := include ../../common/include
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
||||
|
||||
CFLAGS := \
|
||||
-g \
|
||||
-O2 \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-fomit-frame-pointer \
|
||||
-fno-inline \
|
||||
-std=gnu11 \
|
||||
-Werror \
|
||||
-Wall \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__BPMP__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS :=
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
all : $(OUTPUT).bin
|
||||
|
||||
$(OUTPUT).bin : $(OUTPUT).elf
|
||||
$(OBJCOPY) -S -O binary $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
%.elf: $(OFILES)
|
||||
@echo linking $(notdir $@)
|
||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
@$(NM) -CSn $@ > $(notdir $*.lst)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
24
exosphere/lp0fw/linker.ld
Normal file
24
exosphere/lp0fw/linker.ld
Normal file
@@ -0,0 +1,24 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x40010000;
|
||||
|
||||
__start__ = ABSOLUTE(.);
|
||||
|
||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||
.bss : ALIGN(8) { __bss_start__ = .; *(.bss* COMMON); . = ALIGN(8); __bss_end__ = .; }
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
__end__ = ABSOLUTE(.);
|
||||
|
||||
__total_size__ = (__end__ - __start__);
|
||||
__executable_size__ = (__end__ - _start);
|
||||
|
||||
__stack_top__ = 0x40013000;
|
||||
__stack_bottom__ = 0x40012000;
|
||||
}
|
||||
134
exosphere/lp0fw/src/car.c
Normal file
134
exosphere/lp0fw/src/car.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "car.h"
|
||||
#include "timer.h"
|
||||
#include "pmc.h"
|
||||
#include "emc.h"
|
||||
#include "lp0.h"
|
||||
|
||||
static inline uint32_t get_special_clk_reg(CarDevice dev) {
|
||||
switch (dev) {
|
||||
case CARDEVICE_UARTA: return 0x178;
|
||||
case CARDEVICE_UARTB: return 0x17C;
|
||||
case CARDEVICE_I2C1: return 0x124;
|
||||
case CARDEVICE_I2C5: return 0x128;
|
||||
case CARDEVICE_ACTMON: return 0x3E8;
|
||||
case CARDEVICE_BPMP: return 0;
|
||||
default: reboot();
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t get_special_clk_val(CarDevice dev) {
|
||||
switch (dev) {
|
||||
case CARDEVICE_UARTA: return 0;
|
||||
case CARDEVICE_UARTB: return 0;
|
||||
case CARDEVICE_I2C1: return (6 << 29);
|
||||
case CARDEVICE_I2C5: return (6 << 29);
|
||||
case CARDEVICE_ACTMON: return (6 << 29);
|
||||
case CARDEVICE_BPMP: return 0;
|
||||
default: reboot();
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t g_clk_reg_offsets[NUM_CAR_BANKS] = {0x010, 0x014, 0x018, 0x360, 0x364, 0x280, 0x298};
|
||||
static uint32_t g_rst_reg_offsets[NUM_CAR_BANKS] = {0x004, 0x008, 0x00C, 0x358, 0x35C, 0x28C, 0x2A4};
|
||||
|
||||
static uint32_t g_clk_clr_reg_offsets[NUM_CAR_BANKS] = {0x324, 0x32C, 0x334, 0x444, 0x44C, 0x228, 0x2A0};
|
||||
|
||||
void car_configure_oscillators(void) {
|
||||
/* Enable the crystal oscillator, setting drive strength to the saved value in PMC. */
|
||||
CLK_RST_CONTROLLER_OSC_CTRL_0 = (CLK_RST_CONTROLLER_OSC_CTRL_0 & 0xFFFFFC0E) | 1 | (((APBDEV_PMC_OSC_EDPD_OVER_0 >> 1) & 0x3F) << 4);
|
||||
|
||||
/* Set CLK_M_DIVISOR to 1 (causes actual division by 2.) */
|
||||
CLK_RST_CONTROLLER_SPARE_REG0_0 = (1 << 2);
|
||||
/* Reading the register after writing it is required to ensure value takes. */
|
||||
(void)(CLK_RST_CONTROLLER_SPARE_REG0_0);
|
||||
|
||||
/* Set TIMERUS_USEC_CFG to cycle at 0x60 / 0x5 = 19.2 MHz. */
|
||||
/* Value is (dividend << 8) | (divisor). */
|
||||
TIMERUS_USEC_CFG_0 = 0x45F;
|
||||
}
|
||||
|
||||
void car_mbist_workaround(void) {
|
||||
/* This code works around MBIST bug. */
|
||||
|
||||
/* Clear LVL2_CLK_GATE_OVR* registers. */
|
||||
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA_0 = 0;
|
||||
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_0 = 0;
|
||||
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC_0 = 0;
|
||||
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 = 0;
|
||||
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE_0 = 0;
|
||||
|
||||
/* Clear bit patterns in CAR. */
|
||||
/* L: Reset all but RTC, TMR, GPIO, BPMP Cache (CACHE2). */
|
||||
MAKE_CAR_REG(g_clk_clr_reg_offsets[0]) = MAKE_CAR_REG(g_clk_reg_offsets[0]) & 0x7FFFFECF;
|
||||
/* H: Reset all but MC, PMC, FUSE, EMC. */
|
||||
MAKE_CAR_REG(g_clk_clr_reg_offsets[1]) = MAKE_CAR_REG(g_clk_reg_offsets[1]) & 0xFDFFFF3E;
|
||||
/* U: Reset all but CSITE, IRAM[A-D], BPMP Cache RAM (CRAM2). */
|
||||
MAKE_CAR_REG(g_clk_clr_reg_offsets[2]) = MAKE_CAR_REG(g_clk_reg_offsets[2]) & 0xFE0FFDFF;
|
||||
/* V: Reset all but MSELECT, S/PDIF audio doubler, TZRAM, SE. */
|
||||
MAKE_CAR_REG(g_clk_clr_reg_offsets[3]) = MAKE_CAR_REG(g_clk_reg_offsets[3]) & 0x3FBFFFF7;
|
||||
/* W: Reset all but PCIERX[0-5], ENTROPY. */
|
||||
MAKE_CAR_REG(g_clk_clr_reg_offsets[4]) = MAKE_CAR_REG(g_clk_reg_offsets[4]) & 0xFFDFFF03;
|
||||
/* X: Reset all but ETC, MCLK, MCLK2, I2C6, EMC_DLL, GPU, DBGAPB, PLLG_REF, . */
|
||||
MAKE_CAR_REG(g_clk_clr_reg_offsets[5]) = MAKE_CAR_REG(g_clk_reg_offsets[5]) & 0xDCFFB87F;
|
||||
/* Y: Reset all but MC_CDPA, MC_CCPA. */
|
||||
MAKE_CAR_REG(g_clk_clr_reg_offsets[6]) = MAKE_CAR_REG(g_clk_reg_offsets[6]) & 0xFFFFFCFF;
|
||||
|
||||
/* Enable clock to MC1, if CH1 is enabled in EMC. */
|
||||
if (EMC_FBIO_CFG7_0 & 4) { /* CH1_ENABLE */
|
||||
CLK_RST_CONTROLLER_CLK_ENB_W_SET_0 |= 0x40000000; /* SET_CLK_ENB_MC1 */
|
||||
}
|
||||
}
|
||||
|
||||
void clk_enable(CarDevice dev) {
|
||||
uint32_t special_reg;
|
||||
if ((special_reg = get_special_clk_reg(dev))) {
|
||||
MAKE_CAR_REG(special_reg) = get_special_clk_val(dev);
|
||||
}
|
||||
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
|
||||
}
|
||||
|
||||
void clk_disable(CarDevice dev) {
|
||||
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
|
||||
}
|
||||
|
||||
void rst_enable(CarDevice dev) {
|
||||
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
|
||||
}
|
||||
|
||||
void rst_disable(CarDevice dev) {
|
||||
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
|
||||
}
|
||||
|
||||
void clkrst_enable(CarDevice dev) {
|
||||
clk_enable(dev);
|
||||
rst_disable(dev);
|
||||
}
|
||||
|
||||
void clkrst_disable(CarDevice dev) {
|
||||
rst_enable(dev);
|
||||
clk_disable(dev);
|
||||
}
|
||||
|
||||
void clkrst_reboot(CarDevice dev) {
|
||||
clkrst_disable(dev);
|
||||
clkrst_enable(dev);
|
||||
}
|
||||
109
exosphere/lp0fw/src/car.h
Normal file
109
exosphere/lp0fw/src/car.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_CLOCK_AND_RESET_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_CLOCK_AND_RESET_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define CAR_BASE 0x60006000
|
||||
|
||||
#define MAKE_CAR_REG(n) MAKE_REG32(CAR_BASE + n)
|
||||
|
||||
#define CLK_RST_CONTROLLER_MISC_CLK_ENB_0 MAKE_CAR_REG(0x048)
|
||||
#define CLK_RST_CONTROLLER_OSC_CTRL_0 MAKE_CAR_REG(0x050)
|
||||
#define CLK_RST_CONTROLLER_PLLX_BASE_0 MAKE_CAR_REG(0x0E0)
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 MAKE_CAR_REG(0x3A4)
|
||||
#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET_0 MAKE_CAR_REG(0x450)
|
||||
#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR_0 MAKE_CAR_REG(0x454)
|
||||
|
||||
#define CLK_RST_CONTROLLER_SUPER_CCLKG_DIVIDER_0 MAKE_CAR_REG(0x36C)
|
||||
#define CLK_RST_CONTROLLER_SUPER_CCLKP_DIVIDER_0 MAKE_CAR_REG(0x374)
|
||||
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C5_0 MAKE_CAR_REG(0x128)
|
||||
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_REF_0 MAKE_CAR_REG(0x62C)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_SOC_0 MAKE_CAR_REG(0x630)
|
||||
|
||||
#define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2_0 MAKE_CAR_REG(0x388)
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT_0 MAKE_CAR_REG(0x3B4)
|
||||
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA_0 MAKE_CAR_REG(0x0F8)
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_0 MAKE_CAR_REG(0x0FC)
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC_0 MAKE_CAR_REG(0x3A0)
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 MAKE_CAR_REG(0x3A4)
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE_0 MAKE_CAR_REG(0x554)
|
||||
|
||||
#define CLK_RST_CONTROLLER_CCLKG_BURST_POLICY_0 MAKE_CAR_REG(0x368)
|
||||
#define CLK_RST_CONTROLLER_CCLKP_BURST_POLICY_0 MAKE_CAR_REG(0x370)
|
||||
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_H_0 MAKE_CAR_REG(0x008)
|
||||
|
||||
#define CLK_RST_CONTROLLER_SPARE_REG0_0 MAKE_CAR_REG(0x55C)
|
||||
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_H_SET_0 MAKE_CAR_REG(0x308)
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_U_SET_0 MAKE_CAR_REG(0x310)
|
||||
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_H_CLR_0 MAKE_CAR_REG(0x30C)
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_U_CLR_0 MAKE_CAR_REG(0x314)
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_V_CLR_0 MAKE_CAR_REG(0x434)
|
||||
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_L_SET_0 MAKE_CAR_REG(0x320)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_H_SET_0 MAKE_CAR_REG(0x328)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_U_SET_0 MAKE_CAR_REG(0x330)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_V_SET_0 MAKE_CAR_REG(0x440)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_W_SET_0 MAKE_CAR_REG(0x448)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_Y_SET_0 MAKE_CAR_REG(0x29C)
|
||||
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_H_CLR_0 MAKE_CAR_REG(0x32C)
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_W_CLR_0 MAKE_CAR_REG(0x44C)
|
||||
|
||||
#define NUM_CAR_BANKS 7
|
||||
|
||||
typedef enum {
|
||||
CARDEVICE_UARTA = ((0 << 5) | 0x6),
|
||||
CARDEVICE_UARTB = ((0 << 5) | 0x7),
|
||||
CARDEVICE_UARTC = ((1 << 5) | 0x17),
|
||||
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
|
||||
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
|
||||
CARDEVICE_UNK = ((3 << 5) | 0x1E),
|
||||
CARDEVICE_SE = ((3 << 5) | 0x1F),
|
||||
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
|
||||
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
||||
CARDEVICE_SOR_SAFE = ((6 << 5) | 0x1E),
|
||||
CARDEVICE_SOR0 = ((5 << 5) | 0x16),
|
||||
CARDEVICE_SOR1 = ((5 << 5) | 0x17),
|
||||
CARDEVICE_KFUSE = ((1 << 5) | 0x8),
|
||||
CARDEVICE_CL_DVFS = ((4 << 5) | 0x1B),
|
||||
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
|
||||
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
|
||||
CARDEVICE_BPMP = ((0 << 5) | 0x1)
|
||||
} CarDevice;
|
||||
|
||||
void car_configure_oscillators(void);
|
||||
void car_mbist_workaround(void);
|
||||
|
||||
void clk_enable(CarDevice dev);
|
||||
void clk_disable(CarDevice dev);
|
||||
void rst_enable(CarDevice dev);
|
||||
void rst_disable(CarDevice dev);
|
||||
|
||||
void clkrst_enable(CarDevice dev);
|
||||
void clkrst_disable(CarDevice dev);
|
||||
|
||||
void clkrst_reboot(CarDevice dev);
|
||||
|
||||
#endif
|
||||
163
exosphere/lp0fw/src/cluster.c
Normal file
163
exosphere/lp0fw/src/cluster.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "cluster.h"
|
||||
#include "car.h"
|
||||
#include "timer.h"
|
||||
#include "pmc.h"
|
||||
#include "misc.h"
|
||||
#include "i2c.h"
|
||||
#include "flow.h"
|
||||
#include "sysreg.h"
|
||||
|
||||
static void cluster_pmc_enable_partition(uint32_t mask, uint32_t toggle) {
|
||||
/* Set toggle if unset. */
|
||||
if (!(APBDEV_PMC_PWRGATE_STATUS_0 & mask)) {
|
||||
APBDEV_PMC_PWRGATE_TOGGLE_0 = toggle;
|
||||
}
|
||||
|
||||
/* Wait until toggle set. */
|
||||
while (!(APBDEV_PMC_PWRGATE_STATUS_0 & mask)) { }
|
||||
|
||||
/* Remove clamping. */
|
||||
APBDEV_PMC_REMOVE_CLAMPING_CMD_0 = mask;
|
||||
while (APBDEV_PMC_CLAMP_STATUS_0 & mask) { }
|
||||
}
|
||||
|
||||
void cluster_initialize_cpu(void) {
|
||||
/* Hold CoreSight in reset. */
|
||||
CLK_RST_CONTROLLER_RST_DEV_U_SET_0 = 0x200;
|
||||
|
||||
/* CAR2PMC_CPU_ACK_WIDTH should be set to 0. */
|
||||
CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2_0 &= 0xFFFFF000;
|
||||
|
||||
/* Restore SB_AA64_RESET values from PMC scratch. */
|
||||
SB_AA64_RESET_LOW_0 = APBDEV_PMC_SECURE_SCRATCH34_0 | 1;
|
||||
SB_AA64_RESET_HIGH_0 = APBDEV_PMC_SECURE_SCRATCH35_0;
|
||||
|
||||
/* Set CDIV_ENB for CCLKG/CCLKP. */
|
||||
CLK_RST_CONTROLLER_SUPER_CCLKG_DIVIDER_0 = 0x80000000;
|
||||
CLK_RST_CONTROLLER_SUPER_CCLKP_DIVIDER_0 = 0x80000000;
|
||||
|
||||
/* Enable CoreSight clock, take CoreSight out of reset. */
|
||||
CLK_RST_CONTROLLER_CLK_ENB_U_SET_0 = 0x200;
|
||||
CLK_RST_CONTROLLER_RST_DEV_U_CLR_0 = 0x200;
|
||||
|
||||
/* Configure MSELECT to divide by 4, enable MSELECT clock. */
|
||||
CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT_0 = 6; /* (6/2) + 1 = 4. */
|
||||
CLK_RST_CONTROLLER_CLK_ENB_V_SET_0 = 0x8;
|
||||
|
||||
/* Wait 2 us, then take MSELECT out of reset. */
|
||||
timer_wait(2);
|
||||
CLK_RST_CONTROLLER_RST_DEV_V_CLR_0 = 0x8;
|
||||
|
||||
/* Set MSELECT WRAP_TO_SLAVE_INCR[0-2], clear ERR_RESP_EN_SLAVE[1-2]. */
|
||||
MSELECT_CONFIG_0 = (MSELECT_CONFIG_0 & 0xFCFFFFFF) | 0x38000000;
|
||||
|
||||
/* Clear PLLX_ENABLE. */
|
||||
CLK_RST_CONTROLLER_PLLX_BASE_0 &= 0xBFFFFFFF;
|
||||
|
||||
/* Clear PMC scratch 190, disable PMC DPD then wait 10 us. */
|
||||
APBDEV_PMC_SCRATCH190_0 &= 0xFFFFFFFE;
|
||||
APBDEV_PMC_DPD_SAMPLE_0 = 0;
|
||||
timer_wait(10);
|
||||
|
||||
/* Configure UART2 via GPIO controller 2 G. */
|
||||
MAKE_REG32(0x6000D108) |= 4; /* GPIO_CNF */
|
||||
MAKE_REG32(0x6000D118) |= 4; /* GPIO_OE */
|
||||
MAKE_REG32(0x6000D128) &= ~4; /* GPIO_OUT */
|
||||
|
||||
/* Set CL_DVFS RSVD0 + TRISTATE, read register to make it stick. */
|
||||
PINMUX_AUX_DVFS_PWM_0 = 0x11;
|
||||
(void)PINMUX_AUX_DVFS_PWM_0;
|
||||
|
||||
/* Configure I2C. */
|
||||
PINMUX_AUX_PWR_I2C_SCL_0 = 0x40;
|
||||
PINMUX_AUX_PWR_I2C_SDA_0 = 0x40;
|
||||
|
||||
/* Enable clock to CL_DVFS, and set its source/divider. */
|
||||
CLK_RST_CONTROLLER_CLK_ENB_W_SET_0 = 0x08000000;
|
||||
CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_REF_0 = 0xE;
|
||||
CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_SOC_0 = 0xE;
|
||||
|
||||
/* Power on I2C5, wait 5 us, set source + take out of reset. */
|
||||
CLK_RST_CONTROLLER_CLK_ENB_H_SET_0 = 0x8000;
|
||||
CLK_RST_CONTROLLER_RST_DEV_H_SET_0 = 0x8000;
|
||||
timer_wait(5);
|
||||
CLK_RST_CONTROLLER_CLK_SOURCE_I2C5_0 = 0x4;
|
||||
CLK_RST_CONTROLLER_RST_DEV_H_CLR_0 = 0x8000;
|
||||
|
||||
/* Enable the PMIC, wait 2ms. */
|
||||
i2c_enable_pmic();
|
||||
timer_wait(2000);
|
||||
|
||||
/* Enable power to the CRAIL partition. */
|
||||
cluster_pmc_enable_partition(1, 0x100);
|
||||
|
||||
/* Remove SW clamp to CRAIL. */
|
||||
APBDEV_PMC_SET_SW_CLAMP_0 = 0;
|
||||
APBDEV_PMC_REMOVE_CLAMPING_CMD_0 = 1;
|
||||
while (APBDEV_PMC_CLAMP_STATUS_0 & 1) { }
|
||||
|
||||
/* Nintendo manually counts down from 8. I am not sure why this happens. */
|
||||
{
|
||||
volatile int32_t counter = 8;
|
||||
while (counter >= 0) {
|
||||
counter--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Power off I2C5. */
|
||||
CLK_RST_CONTROLLER_RST_DEV_H_SET_0 = 0x8000;
|
||||
CLK_RST_CONTROLLER_CLK_ENB_H_CLR_0 = 0x8000;
|
||||
|
||||
/* Disable clock to CL_DVFS */
|
||||
CLK_RST_CONTROLLER_CLK_ENB_W_CLR_0 = 0x08000000;
|
||||
|
||||
/* Perform RAM repair if necessary. */
|
||||
flow_perform_ram_repair();
|
||||
|
||||
/* Enable power to the non-CPU partition. */
|
||||
cluster_pmc_enable_partition(0x8000, 0x10F);
|
||||
|
||||
/* Enable clock to PLLP_OUT_CPU, wait 2 us. */
|
||||
CLK_RST_CONTROLLER_CLK_ENB_Y_SET_0 = 0x80000000;
|
||||
timer_wait(2);
|
||||
|
||||
/* Enable clock to CPU, CPUG, wait 10 us. */
|
||||
CLK_RST_CONTROLLER_CLK_ENB_L_SET_0 = 1;
|
||||
CLK_RST_CONTROLLER_CLK_ENB_V_SET_0 = 1;
|
||||
timer_wait(10);
|
||||
|
||||
/* Set CPU clock sources to PLLP_OUT_0 + state to RUN, wait 10 us. */
|
||||
CLK_RST_CONTROLLER_CCLKG_BURST_POLICY_0 = 0x20004444;
|
||||
CLK_RST_CONTROLLER_CCLKP_BURST_POLICY_0 = 0x20004444;
|
||||
timer_wait(10);
|
||||
|
||||
/* Take non-CPU out of reset (write CLR_NONCPURESET). */
|
||||
CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR_0 = 0x20000000;
|
||||
}
|
||||
|
||||
void cluster_power_on_cpu(void) {
|
||||
/* Enable power to CE0 partition. */
|
||||
cluster_pmc_enable_partition(0x4000, 0x10E);
|
||||
|
||||
/* Clear CPU reset. */
|
||||
CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR_0 = 0x10001;
|
||||
}
|
||||
30
exosphere/lp0fw/src/cluster.h
Normal file
30
exosphere/lp0fw/src/cluster.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_CLUSTER_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_CLUSTER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define MSELECT_CONFIG_0 MAKE_REG32(0x50060000)
|
||||
|
||||
void cluster_initialize_cpu(void);
|
||||
void cluster_power_on_cpu(void);
|
||||
|
||||
#endif
|
||||
33
exosphere/lp0fw/src/emc.c
Normal file
33
exosphere/lp0fw/src/emc.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 "utils.h"
|
||||
#include "lp0.h"
|
||||
#include "emc.h"
|
||||
#include "pmc.h"
|
||||
#include "timer.h"
|
||||
|
||||
void emc_configure_pmacro_training(void) {
|
||||
/* Set DISABLE_CFG_BYTEN for all N. */
|
||||
EMC_PMACRO_CFG_PM_GLOBAL_0_0 = 0xFF0000;
|
||||
|
||||
/* Set CHN_TRAINING_E_WRPTR for channel 0 + channel 1. */
|
||||
EMC_PMACRO_TRAINING_CTRL_0_0 = 8;
|
||||
EMC_PMACRO_TRAINING_CTRL_1_0 = 8;
|
||||
|
||||
/* Clear DISABLE_CFG_BYTEN for all N. */
|
||||
EMC_PMACRO_CFG_PM_GLOBAL_0_0 = 0x0;
|
||||
}
|
||||
71
exosphere/lp0fw/src/emc.h
Normal file
71
exosphere/lp0fw/src/emc.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_EMC_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_EMC_H
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define EMC_BASE (0x7001B000)
|
||||
|
||||
#define EMC0_BASE (0x7001E000)
|
||||
#define EMC1_BASE (0x7001F000)
|
||||
|
||||
|
||||
#define MAKE_EMC_REG(ofs) (MAKE_REG32(EMC_BASE + ofs))
|
||||
|
||||
#define MAKE_EMC0_REG(ofs) (MAKE_REG32(EMC0_BASE + ofs))
|
||||
#define MAKE_EMC1_REG(ofs) (MAKE_REG32(EMC1_BASE + ofs))
|
||||
|
||||
#define EMC_CFG_0 MAKE_EMC_REG(0x00C)
|
||||
|
||||
#define EMC_ADR_CFG_0 MAKE_EMC_REG(0x10)
|
||||
|
||||
#define EMC_TIMING_CONTROL_0 MAKE_EMC_REG(0x028)
|
||||
|
||||
#define EMC_SELF_REF_0 MAKE_EMC_REG(0x0E0)
|
||||
|
||||
#define EMC_MRW_0 MAKE_EMC_REG(0x0E8)
|
||||
|
||||
#define EMC_FBIO_CFG5_0 MAKE_EMC_REG(0x104)
|
||||
|
||||
#define EMC_MRW3_0 MAKE_EMC_REG(0x138)
|
||||
|
||||
#define EMC_AUTO_CAL_CONFIG_0 MAKE_EMC_REG(0x2A4)
|
||||
|
||||
#define EMC_REQ_CTRL_0 MAKE_EMC_REG(0x2B0)
|
||||
|
||||
#define EMC_EMC_STATUS_0 MAKE_EMC_REG(0x2B4)
|
||||
#define EMC0_EMC_STATUS_0 MAKE_EMC0_REG(0x2B4)
|
||||
#define EMC1_EMC_STATUS_0 MAKE_EMC1_REG(0x2B4)
|
||||
|
||||
#define EMC_CFG_DIG_DLL_0 MAKE_EMC_REG(0x2BC)
|
||||
#define EMC0_CFG_DIG_DLL_0 MAKE_EMC0_REG(0x2BC)
|
||||
#define EMC1_CFG_DIG_DLL_0 MAKE_EMC1_REG(0x2BC)
|
||||
|
||||
#define EMC_ZCAL_INTERVAL_0 MAKE_EMC_REG(0x2E0)
|
||||
|
||||
#define EMC_PMC_SCRATCH3_0 MAKE_EMC_REG(0x448)
|
||||
|
||||
#define EMC_FBIO_CFG7_0 MAKE_EMC_REG(0x584)
|
||||
|
||||
#define EMC_PMACRO_CFG_PM_GLOBAL_0_0 MAKE_EMC_REG(0xC30)
|
||||
#define EMC_PMACRO_TRAINING_CTRL_0_0 MAKE_EMC_REG(0xCF8)
|
||||
#define EMC_PMACRO_TRAINING_CTRL_1_0 MAKE_EMC_REG(0xCFC)
|
||||
|
||||
void emc_configure_pmacro_training(void);
|
||||
|
||||
#endif
|
||||
31
exosphere/lp0fw/src/flow.c
Normal file
31
exosphere/lp0fw/src/flow.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "flow.h"
|
||||
|
||||
void flow_perform_ram_repair(void) {
|
||||
/* Perform repair only if not active cluster. */
|
||||
if (!(FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 & 1)) {
|
||||
/* Set REQ, to begin RAM repair. */
|
||||
FLOW_CTLR_RAM_REPAIR_0 = 1;
|
||||
|
||||
/* Wait for STS to say RAM repair has completed. */
|
||||
while (!(FLOW_CTLR_RAM_REPAIR_0 & 2)) { }
|
||||
}
|
||||
}
|
||||
35
exosphere/lp0fw/src/flow.h
Normal file
35
exosphere/lp0fw/src/flow.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_FLOW_CTLR_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_FLOW_CTLR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define FLOW_BASE (0x60007000)
|
||||
|
||||
#define MAKE_FLOW_REG(ofs) MAKE_REG32(FLOW_BASE + ofs)
|
||||
|
||||
#define FLOW_CTLR_HALT_COP_EVENTS_0 MAKE_FLOW_REG(0x004)
|
||||
#define FLOW_CTLR_RAM_REPAIR_0 MAKE_FLOW_REG(0x040)
|
||||
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 MAKE_FLOW_REG(0x098)
|
||||
|
||||
void flow_perform_ram_repair(void);
|
||||
|
||||
#endif
|
||||
75
exosphere/lp0fw/src/fuse.c
Normal file
75
exosphere/lp0fw/src/fuse.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "fuse.h"
|
||||
#include "car.h"
|
||||
#include "pmc.h"
|
||||
|
||||
#define NUM_FUSE_BYPASS_ENTRIES 0
|
||||
|
||||
bool fuse_check_downgrade_status(void) {
|
||||
/* We aren't going to implement anti-downgrade. */
|
||||
return false;
|
||||
}
|
||||
|
||||
void fuse_disable_programming(void) {
|
||||
FUSE_REGS->FUSE_DIS_PGM = 1;
|
||||
}
|
||||
|
||||
static fuse_bypass_data_t g_fuse_bypass_entries[NUM_FUSE_BYPASS_ENTRIES] = {
|
||||
/* No entries here. */
|
||||
};
|
||||
|
||||
void fuse_configure_fuse_bypass(void) {
|
||||
/* Enable fuses in CAR? This seems to affect fuse data visibility. */
|
||||
CLK_RST_CONTROLLER_MISC_CLK_ENB_0 |= 0x10000000;
|
||||
|
||||
/* Configure bypass/override, only if programming is allowed. */
|
||||
if (!(FUSE_REGS->FUSE_DIS_PGM & 1)) {
|
||||
/* Enable write access. */
|
||||
FUSE_REGS->FUSE_WRITE_ACCESS = (FUSE_REGS->FUSE_WRITE_ACCESS & ~0x1) | 0x10000;
|
||||
/* Enable fuse bypass config. */
|
||||
FUSE_REGS->FUSE_FUSEBYPASS = 1;
|
||||
|
||||
/* Override fuses. */
|
||||
for (size_t i = 0; i < NUM_FUSE_BYPASS_ENTRIES; i++) {
|
||||
MAKE_FUSE_REG(g_fuse_bypass_entries[i].offset) = g_fuse_bypass_entries[i].value;
|
||||
}
|
||||
|
||||
/* Disable fuse write access. */
|
||||
FUSE_REGS->FUSE_WRITE_ACCESS |= 1;
|
||||
|
||||
/* Enable fuse bypass config. */
|
||||
/* I think this is a bug, and Nintendo meant to write 0 here? */
|
||||
FUSE_REGS->FUSE_FUSEBYPASS = 1;
|
||||
|
||||
/* This...clears the disable programming bit(?). */
|
||||
/* I have no idea why this happens. What? */
|
||||
/* This is probably also either a bug or does nothing. */
|
||||
/* Is this bit even clearable? */
|
||||
FUSE_REGS->FUSE_DIS_PGM &= 0xFFFFFFFE;
|
||||
|
||||
/* Restore saved private key disable bit. */
|
||||
FUSE_REGS->FUSE_PRIVATEKEYDISABLE |= (APBDEV_PMC_SECURE_SCRATCH21_0 & 0x10);
|
||||
|
||||
/* Lock private key disable secure scratch. */
|
||||
APBDEV_PMC_SEC_DISABLE2_0 |= 0x4000000;
|
||||
}
|
||||
|
||||
}
|
||||
202
exosphere/lp0fw/src/fuse.h
Normal file
202
exosphere/lp0fw/src/fuse.h
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_FUSE_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_FUSE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t FUSE_CTRL;
|
||||
uint32_t FUSE_REG_ADDR;
|
||||
uint32_t FUSE_REG_READ;
|
||||
uint32_t FUSE_REG_WRITE;
|
||||
uint32_t FUSE_TIME_RD1;
|
||||
uint32_t FUSE_TIME_RD2;
|
||||
uint32_t FUSE_TIME_PGM1;
|
||||
uint32_t FUSE_TIME_PGM2;
|
||||
uint32_t FUSE_PRIV2INTFC;
|
||||
uint32_t FUSE_FUSEBYPASS;
|
||||
uint32_t FUSE_PRIVATEKEYDISABLE;
|
||||
uint32_t FUSE_DIS_PGM;
|
||||
uint32_t FUSE_WRITE_ACCESS;
|
||||
uint32_t FUSE_PWR_GOOD_SW;
|
||||
uint32_t _0x38[0x32];
|
||||
} fuse_registers_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t FUSE_PRODUCTION_MODE;
|
||||
uint32_t _0x4;
|
||||
uint32_t _0x8;
|
||||
uint32_t _0xC;
|
||||
uint32_t FUSE_SKU_INFO;
|
||||
uint32_t FUSE_CPU_SPEEDO_0;
|
||||
uint32_t FUSE_CPU_IDDQ;
|
||||
uint32_t _0x1C;
|
||||
uint32_t _0x20;
|
||||
uint32_t _0x24;
|
||||
uint32_t FUSE_FT_REV;
|
||||
uint32_t FUSE_CPU_SPEEDO_1;
|
||||
uint32_t FUSE_CPU_SPEEDO_2;
|
||||
uint32_t FUSE_SOC_SPEEDO_0;
|
||||
uint32_t FUSE_SOC_SPEEDO_1;
|
||||
uint32_t FUSE_SOC_SPEEDO_2;
|
||||
uint32_t FUSE_SOC_IDDQ;
|
||||
uint32_t _0x44;
|
||||
uint32_t FUSE_FA;
|
||||
uint32_t _0x4C;
|
||||
uint32_t _0x50;
|
||||
uint32_t _0x54;
|
||||
uint32_t _0x58;
|
||||
uint32_t _0x5C;
|
||||
uint32_t _0x60;
|
||||
uint32_t FUSE_PUBLIC_KEY[0x8];
|
||||
uint32_t FUSE_TSENSOR_1;
|
||||
uint32_t FUSE_TSENSOR_2;
|
||||
uint32_t _0x8C;
|
||||
uint32_t FUSE_CP_REV;
|
||||
uint32_t _0x94;
|
||||
uint32_t FUSE_TSENSOR_0;
|
||||
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG;
|
||||
uint32_t FUSE_SECURITY_MODE;
|
||||
uint32_t FUSE_PRIVATE_KEY[0x4];
|
||||
uint32_t FUSE_DEVICE_KEY;
|
||||
uint32_t _0xB8;
|
||||
uint32_t _0xBC;
|
||||
uint32_t FUSE_RESERVED_SW;
|
||||
uint32_t FUSE_VP8_ENABLE;
|
||||
uint32_t FUSE_RESERVED_ODM[0x8];
|
||||
uint32_t _0xE8;
|
||||
uint32_t _0xEC;
|
||||
uint32_t FUSE_SKU_USB_CALIB;
|
||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
||||
uint32_t _0xF8;
|
||||
uint32_t _0xFC;
|
||||
uint32_t FUSE_VENDOR_CODE;
|
||||
uint32_t FUSE_FAB_CODE;
|
||||
uint32_t FUSE_LOT_CODE_0;
|
||||
uint32_t FUSE_LOT_CODE_1;
|
||||
uint32_t FUSE_WAFER_ID;
|
||||
uint32_t FUSE_X_COORDINATE;
|
||||
uint32_t FUSE_Y_COORDINATE;
|
||||
uint32_t _0x11C;
|
||||
uint32_t _0x120;
|
||||
uint32_t FUSE_SATA_CALIB;
|
||||
uint32_t FUSE_GPU_IDDQ;
|
||||
uint32_t FUSE_TSENSOR_3;
|
||||
uint32_t _0x130;
|
||||
uint32_t _0x134;
|
||||
uint32_t _0x138;
|
||||
uint32_t _0x13C;
|
||||
uint32_t _0x140;
|
||||
uint32_t _0x144;
|
||||
uint32_t FUSE_OPT_SUBREVISION;
|
||||
uint32_t _0x14C;
|
||||
uint32_t _0x150;
|
||||
uint32_t FUSE_TSENSOR_4;
|
||||
uint32_t FUSE_TSENSOR_5;
|
||||
uint32_t FUSE_TSENSOR_6;
|
||||
uint32_t FUSE_TSENSOR_7;
|
||||
uint32_t FUSE_OPT_PRIV_SEC_DIS;
|
||||
uint32_t FUSE_PKC_DISABLE;
|
||||
uint32_t _0x16C;
|
||||
uint32_t _0x170;
|
||||
uint32_t _0x174;
|
||||
uint32_t _0x178;
|
||||
uint32_t _0x17C;
|
||||
uint32_t FUSE_TSENSOR_COMMON;
|
||||
uint32_t _0x184;
|
||||
uint32_t _0x188;
|
||||
uint32_t _0x18C;
|
||||
uint32_t _0x190;
|
||||
uint32_t _0x194;
|
||||
uint32_t _0x198;
|
||||
uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
|
||||
uint32_t _0x1A0;
|
||||
uint32_t _0x1A4;
|
||||
uint32_t _0x1A8;
|
||||
uint32_t _0x1AC;
|
||||
uint32_t _0x1B0;
|
||||
uint32_t _0x1B4;
|
||||
uint32_t _0x1B8;
|
||||
uint32_t _0x1BC;
|
||||
uint32_t _0x1D0;
|
||||
uint32_t FUSE_TSENSOR_8;
|
||||
uint32_t _0x1D8;
|
||||
uint32_t _0x1DC;
|
||||
uint32_t _0x1E0;
|
||||
uint32_t _0x1E4;
|
||||
uint32_t _0x1E8;
|
||||
uint32_t _0x1EC;
|
||||
uint32_t _0x1F0;
|
||||
uint32_t _0x1F4;
|
||||
uint32_t _0x1F8;
|
||||
uint32_t _0x1FC;
|
||||
uint32_t _0x200;
|
||||
uint32_t FUSE_RESERVED_CALIB;
|
||||
uint32_t _0x208;
|
||||
uint32_t _0x20C;
|
||||
uint32_t _0x210;
|
||||
uint32_t _0x214;
|
||||
uint32_t _0x218;
|
||||
uint32_t FUSE_TSENSOR_9;
|
||||
uint32_t _0x220;
|
||||
uint32_t _0x224;
|
||||
uint32_t _0x228;
|
||||
uint32_t _0x22C;
|
||||
uint32_t _0x230;
|
||||
uint32_t _0x234;
|
||||
uint32_t _0x238;
|
||||
uint32_t _0x23C;
|
||||
uint32_t _0x240;
|
||||
uint32_t _0x244;
|
||||
uint32_t _0x248;
|
||||
uint32_t _0x24C;
|
||||
uint32_t FUSE_USB_CALIB_EXT;
|
||||
uint32_t _0x254;
|
||||
uint32_t _0x258;
|
||||
uint32_t _0x25C;
|
||||
uint32_t _0x260;
|
||||
uint32_t _0x264;
|
||||
uint32_t _0x268;
|
||||
uint32_t _0x26C;
|
||||
uint32_t _0x270;
|
||||
uint32_t _0x274;
|
||||
uint32_t _0x278;
|
||||
uint32_t _0x27C;
|
||||
uint32_t FUSE_SPARE_BIT[0x20];
|
||||
} fuse_chip_registers_t;
|
||||
|
||||
#define FUSE_REGS ((volatile fuse_registers_t *)(0x7000F800))
|
||||
#define FUSE_CHIP_REGS ((volatile fuse_chip_registers_t *)(0x7000F900))
|
||||
|
||||
#define MAKE_FUSE_REG(n) MAKE_REG32(0x7000F800 + n)
|
||||
|
||||
typedef struct {
|
||||
uint32_t offset;
|
||||
uint32_t value;
|
||||
} fuse_bypass_data_t;
|
||||
|
||||
bool fuse_check_downgrade_status(void);
|
||||
|
||||
void fuse_configure_fuse_bypass(void);
|
||||
|
||||
void fuse_disable_programming(void);
|
||||
|
||||
#endif
|
||||
76
exosphere/lp0fw/src/i2c.c
Normal file
76
exosphere/lp0fw/src/i2c.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 "i2c.h"
|
||||
#include "timer.h"
|
||||
|
||||
/* Prototypes for internal commands. */
|
||||
void i2c_set_test_master_config_load(void);
|
||||
void i2c_write(unsigned int device, uint32_t val, unsigned int num_bytes);
|
||||
void i2c_send_byte_command(unsigned int device, unsigned char reg, unsigned char b);
|
||||
|
||||
/* Load hardware config for I2C5. */
|
||||
void i2c_set_test_master_config_load(void) {
|
||||
/* Set MSTR_CONFIG_LOAD. */
|
||||
I2C_I2C_CONFIG_LOAD_0 = 0x1;
|
||||
|
||||
while (I2C_I2C_CONFIG_LOAD_0 & 1) {
|
||||
/* Wait forever until it's unset. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Writes a value to an i2c device. */
|
||||
void i2c_write(unsigned int device, uint32_t val, unsigned int num_bytes) {
|
||||
if (num_bytes > 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set device for 7-bit mode. */
|
||||
I2C_I2C_CMD_ADDR0_0 = device << 1;
|
||||
|
||||
/* Load in data to write. */
|
||||
I2C_I2C_CMD_DATA1_0 = val;
|
||||
|
||||
/* Set config with LENGTH = num_bytes, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
|
||||
I2C_I2C_CNFG_0 = ((num_bytes << 1) - 2) | 0x2800;
|
||||
|
||||
i2c_set_test_master_config_load();
|
||||
|
||||
/* Config |= SEND; */
|
||||
I2C_I2C_CNFG_0 = ((num_bytes << 1) - 2) | 0x2800 | 0x200;
|
||||
|
||||
|
||||
while (I2C_I2C_STATUS_0 & 0x100) {
|
||||
/* Wait until not busy. */
|
||||
}
|
||||
|
||||
while (I2C_I2C_STATUS_0 & 0xF) {
|
||||
/* Wait until write successful. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Writes a byte val to reg for given device. */
|
||||
void i2c_send_byte_command(unsigned int device, unsigned char reg, unsigned char b) {
|
||||
uint32_t val = (reg) | (b << 8);
|
||||
/* Write 1 byte (reg) + 1 byte (value) */
|
||||
i2c_write(device, val, 2);
|
||||
}
|
||||
|
||||
/* Enable the PMIC. */
|
||||
void i2c_enable_pmic(void) {
|
||||
/* Write 00 to Device 27 Reg 00. */
|
||||
i2c_send_byte_command(27, 0, 0x80);
|
||||
}
|
||||
48
exosphere/lp0fw/src/i2c.h
Normal file
48
exosphere/lp0fw/src/i2c.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_I2C_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_I2C_H
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/* I2C_BASE = I2C5. */
|
||||
#define I2C_BASE (0x7000D000)
|
||||
|
||||
#define MAKE_I2C_REG(ofs) (MAKE_REG32(I2C_BASE + ofs))
|
||||
|
||||
#define I2C_I2C_CNFG_0 MAKE_I2C_REG(0x000)
|
||||
|
||||
#define I2C_I2C_CMD_ADDR0_0 MAKE_I2C_REG(0x004)
|
||||
|
||||
#define I2C_I2C_CMD_DATA1_0 MAKE_I2C_REG(0x00C)
|
||||
|
||||
#define I2C_I2C_STATUS_0 MAKE_I2C_REG(0x01C)
|
||||
|
||||
#define I2C_INTERRUPT_STATUS_REGISTER_0 MAKE_I2C_REG(0x068)
|
||||
|
||||
#define I2C_I2C_CLK_DIVISOR_REGISTER_0 MAKE_I2C_REG(0x06C)
|
||||
|
||||
#define I2C_I2C_BUS_CLEAR_CONFIG_0 MAKE_I2C_REG(0x084)
|
||||
|
||||
#define I2C_I2C_BUS_CLEAR_STATUS_0 MAKE_I2C_REG(0x088)
|
||||
|
||||
|
||||
#define I2C_I2C_CONFIG_LOAD_0 MAKE_I2C_REG(0x08C)
|
||||
|
||||
void i2c_enable_pmic(void);
|
||||
|
||||
#endif
|
||||
98
exosphere/lp0fw/src/lp0.c
Normal file
98
exosphere/lp0fw/src/lp0.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 "utils.h"
|
||||
#include "lp0.h"
|
||||
#include "mc.h"
|
||||
#include "pmc.h"
|
||||
#include "misc.h"
|
||||
#include "fuse.h"
|
||||
#include "car.h"
|
||||
#include "emc.h"
|
||||
#include "cluster.h"
|
||||
#include "flow.h"
|
||||
#include "timer.h"
|
||||
#include "secmon.h"
|
||||
|
||||
void reboot(void) {
|
||||
/* Write MAIN_RST */
|
||||
APBDEV_PMC_CNTRL_0 = 0x10;
|
||||
while (true) {
|
||||
/* Wait for reboot. */
|
||||
}
|
||||
}
|
||||
|
||||
void lp0_entry_main(warmboot_metadata_t *meta) {
|
||||
const uint32_t target_firmware = meta->target_firmware;
|
||||
/* Before doing anything else, ensure some sanity. */
|
||||
if (meta->magic != WARMBOOT_MAGIC || target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
/* [4.0.0+] First thing warmboot does is disable BPMP access to memory. */
|
||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
disable_bpmp_access_to_dram();
|
||||
}
|
||||
|
||||
/* Configure debugging depending on FUSE_PRODUCTION_MODE */
|
||||
misc_configure_device_dbg_settings();
|
||||
|
||||
/* Check for downgrade. */
|
||||
/* NOTE: We implemented this as "return false" */
|
||||
if (fuse_check_downgrade_status()) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_300) {
|
||||
/* Nintendo's firmware checks APBDEV_PMC_SECURE_SCRATCH32_0 against a per-warmboot binary value here. */
|
||||
/* We won't bother with that. */
|
||||
if (false /* APBDEV_PMC_SECURE_SCRATCH32_0 == WARMBOOT_MAGIC_NUMBER */) {
|
||||
reboot();
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Check that we're running at the correct physical address. */
|
||||
|
||||
/* Setup fuses, disable bypass. */
|
||||
fuse_configure_fuse_bypass();
|
||||
|
||||
/* Configure oscillators/timing in CAR. */
|
||||
car_configure_oscillators();
|
||||
|
||||
/* Restore RAM configuration. */
|
||||
misc_restore_ram_svop();
|
||||
emc_configure_pmacro_training();
|
||||
|
||||
/* Setup clock output for all devices, working around mbist bug. */
|
||||
car_mbist_workaround();
|
||||
|
||||
/* Initialize the CPU cluster. */
|
||||
cluster_initialize_cpu();
|
||||
|
||||
secmon_restore_to_tzram(target_firmware);
|
||||
|
||||
/* Power on the CPU cluster. */
|
||||
cluster_power_on_cpu();
|
||||
|
||||
/* Nintendo clears most of warmboot.bin out of IRAM here. We're not gonna bother. */
|
||||
/* memset( ... ); */
|
||||
|
||||
const uint32_t halt_val = (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_400) ? 0x40000000 : 0x50000000;
|
||||
while (true) {
|
||||
/* Halt the BPMP. */
|
||||
FLOW_CTLR_HALT_COP_EVENTS_0 = halt_val;
|
||||
}
|
||||
}
|
||||
35
exosphere/lp0fw/src/lp0.h
Normal file
35
exosphere/lp0fw/src/lp0.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_LP0_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_LP0_H
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/* WBT0 */
|
||||
#define WARMBOOT_MAGIC 0x30544257
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
uint32_t target_firmware;
|
||||
uint32_t padding[2];
|
||||
} warmboot_metadata_t;
|
||||
|
||||
void lp0_entry_main(warmboot_metadata_t *meta);
|
||||
|
||||
void __attribute__((noreturn)) reboot(void);
|
||||
|
||||
#endif
|
||||
40
exosphere/lp0fw/src/mc.c
Normal file
40
exosphere/lp0fw/src/mc.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 <stdint.h>
|
||||
|
||||
#include "mc.h"
|
||||
#include "utils.h"
|
||||
|
||||
void disable_bpmp_access_to_dram(void) {
|
||||
/* Modify carveout 4 to prevent BPMP access to dram (TZ will fix it). */
|
||||
volatile security_carveout_t *carveout = (volatile security_carveout_t *)(MC_BASE + 0xC08 + 0x50 * (4 - CARVEOUT_ID_MIN));
|
||||
carveout->paddr_low = 0;
|
||||
carveout->paddr_high = 0;
|
||||
carveout->size_big_pages = 1; /* 128 KiB */
|
||||
carveout->client_access_0 = 0;
|
||||
carveout->client_access_1 = 0;
|
||||
carveout->client_access_2 = 0;
|
||||
carveout->client_access_3 = 0;
|
||||
carveout->client_access_4 = 0;
|
||||
carveout->client_force_internal_access_0 = BIT(CSR_AVPCARM7R);
|
||||
carveout->client_force_internal_access_1 = BIT(CSW_AVPCARM7W);
|
||||
carveout->client_force_internal_access_2 = 0;
|
||||
carveout->client_force_internal_access_3 = 0;
|
||||
carveout->client_force_internal_access_4 = 0;
|
||||
/* Set config to LOCKED, TZ-SECURE, untranslated addresses only. */
|
||||
carveout->config = 0x8F;
|
||||
}
|
||||
614
exosphere/lp0fw/src/mc.h
Normal file
614
exosphere/lp0fw/src/mc.h
Normal file
@@ -0,0 +1,614 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_MC_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_MC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MC_BASE_PHYS 0x70019000
|
||||
|
||||
#define MC_BASE (MC_BASE_PHYS)
|
||||
#define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n)
|
||||
|
||||
#define MC_INTSTATUS 0x0
|
||||
#define MC_INTMASK 0x4
|
||||
#define MC_ERR_STATUS 0x8
|
||||
#define MC_ERR_ADR 0xc
|
||||
#define MC_SMMU_CONFIG 0x10
|
||||
#define MC_SMMU_TLB_CONFIG 0x14
|
||||
#define MC_SMMU_PTC_CONFIG 0x18
|
||||
#define MC_SMMU_PTB_ASID 0x1c
|
||||
#define MC_SMMU_PTB_DATA 0x20
|
||||
#define MC_SMMU_TLB_FLUSH 0x30
|
||||
#define MC_SMMU_PTC_FLUSH 0x34
|
||||
#define MC_SMMU_AFI_ASID 0x238
|
||||
#define MC_SMMU_AVPC_ASID 0x23c
|
||||
#define MC_SMMU_PPCS1_ASID 0x298
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
|
||||
#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0
|
||||
#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
|
||||
#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
|
||||
#define MC_PCFIFO_CLIENT_CONFIG3 0xddc
|
||||
#define MC_PCFIFO_CLIENT_CONFIG4 0xde0
|
||||
#define MC_EMEM_CFG 0x50
|
||||
#define MC_EMEM_ADR_CFG 0x54
|
||||
#define MC_EMEM_ADR_CFG_DEV0 0x58
|
||||
#define MC_EMEM_ADR_CFG_DEV1 0x5c
|
||||
#define MC_EMEM_ADR_CFG_CHANNEL_MASK 0x60
|
||||
#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64
|
||||
#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68
|
||||
#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c
|
||||
#define MC_SECURITY_CFG0 0x70
|
||||
#define MC_SECURITY_CFG1 0x74
|
||||
#define MC_SECURITY_CFG3 0x9bc
|
||||
#define MC_SECURITY_RSV 0x7c
|
||||
#define MC_EMEM_ARB_CFG 0x90
|
||||
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
|
||||
#define MC_EMEM_ARB_TIMING_RCD 0x98
|
||||
#define MC_EMEM_ARB_TIMING_RP 0x9c
|
||||
#define MC_EMEM_ARB_TIMING_RC 0xa0
|
||||
#define MC_EMEM_ARB_TIMING_RAS 0xa4
|
||||
#define MC_EMEM_ARB_TIMING_FAW 0xa8
|
||||
#define MC_EMEM_ARB_TIMING_RRD 0xac
|
||||
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
|
||||
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
|
||||
#define MC_EMEM_ARB_TIMING_R2R 0xb8
|
||||
#define MC_EMEM_ARB_TIMING_W2W 0xbc
|
||||
#define MC_EMEM_ARB_TIMING_R2W 0xc0
|
||||
#define MC_EMEM_ARB_TIMING_W2R 0xc4
|
||||
#define MC_EMEM_ARB_TIMING_RFCPB 0x6c0
|
||||
#define MC_EMEM_ARB_TIMING_CCDMW 0x6c4
|
||||
#define MC_EMEM_ARB_REFPB_HP_CTRL 0x6f0
|
||||
#define MC_EMEM_ARB_REFPB_BANK_CTRL 0x6f4
|
||||
#define MC_EMEM_ARB_DA_TURNS 0xd0
|
||||
#define MC_EMEM_ARB_DA_COVERS 0xd4
|
||||
#define MC_EMEM_ARB_MISC0 0xd8
|
||||
#define MC_EMEM_ARB_MISC1 0xdc
|
||||
#define MC_EMEM_ARB_MISC2 0xc8
|
||||
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
|
||||
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
|
||||
#define MC_EMEM_ARB_NISO_THROTTLE 0x6b0
|
||||
#define MC_EMEM_ARB_OVERRIDE 0xe8
|
||||
#define MC_EMEM_ARB_RSV 0xec
|
||||
#define MC_CLKEN_OVERRIDE 0xf4
|
||||
#define MC_TIMING_CONTROL_DBG 0xf8
|
||||
#define MC_TIMING_CONTROL 0xfc
|
||||
#define MC_STAT_CONTROL 0x100
|
||||
#define MC_STAT_STATUS 0x104
|
||||
#define MC_STAT_EMC_CLOCK_LIMIT 0x108
|
||||
#define MC_STAT_EMC_CLOCK_LIMIT_MSBS 0x10c
|
||||
#define MC_STAT_EMC_CLOCKS 0x110
|
||||
#define MC_STAT_EMC_CLOCKS_MSBS 0x114
|
||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 0x118
|
||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 0x158
|
||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 0x11c
|
||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 0x15c
|
||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER 0xa20
|
||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER 0xa24
|
||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 0x198
|
||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 0x1a8
|
||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 0x19c
|
||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 0x1ac
|
||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER 0xa28
|
||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER 0xa2c
|
||||
#define MC_STAT_EMC_FILTER_SET0_ASID 0x1a0
|
||||
#define MC_STAT_EMC_FILTER_SET1_ASID 0x1b0
|
||||
#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 0x120
|
||||
#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 0x160
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_0 0x128
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_0 0x168
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_1 0x12c
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_1 0x16c
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_2 0x130
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_2 0x170
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_3 0x134
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_4 0xb88
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_3 0x174
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_4 0xb8c
|
||||
#define MC_STAT_EMC_SET0_COUNT 0x138
|
||||
#define MC_STAT_EMC_SET0_COUNT_MSBS 0x13c
|
||||
#define MC_STAT_EMC_SET1_COUNT 0x178
|
||||
#define MC_STAT_EMC_SET1_COUNT_MSBS 0x17c
|
||||
#define MC_STAT_EMC_SET0_SLACK_ACCUM 0x140
|
||||
#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 0x144
|
||||
#define MC_STAT_EMC_SET1_SLACK_ACCUM 0x180
|
||||
#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 0x184
|
||||
#define MC_STAT_EMC_SET0_HISTO_COUNT 0x148
|
||||
#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 0x14c
|
||||
#define MC_STAT_EMC_SET1_HISTO_COUNT 0x188
|
||||
#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 0x18c
|
||||
#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 0x150
|
||||
#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 0x190
|
||||
#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 0x1b8
|
||||
#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 0x1bc
|
||||
#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 0x1c8
|
||||
#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 0x1cc
|
||||
#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 0x1c0
|
||||
#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 0x1d0
|
||||
#define MC_CLIENT_HOTRESET_CTRL 0x200
|
||||
#define MC_CLIENT_HOTRESET_CTRL_1 0x970
|
||||
#define MC_CLIENT_HOTRESET_STATUS 0x204
|
||||
#define MC_CLIENT_HOTRESET_STATUS_1 0x974
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_3 0x214
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_4 0xb94
|
||||
#define MC_EMEM_ARB_HYSTERESIS_0 0x218
|
||||
#define MC_EMEM_ARB_HYSTERESIS_1 0x21c
|
||||
#define MC_EMEM_ARB_HYSTERESIS_2 0x220
|
||||
#define MC_EMEM_ARB_HYSTERESIS_3 0x224
|
||||
#define MC_EMEM_ARB_HYSTERESIS_4 0xb84
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_0 0xbb0
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_1 0xbb4
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_2 0xbb8
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_3 0xbbc
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_4 0xbc0
|
||||
#define MC_EMEM_ARB_DHYST_CTRL 0xbcc
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xbd0
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xbd4
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xbd8
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xbdc
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xbe0
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xbe4
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xbe8
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xbec
|
||||
#define MC_RESERVED_RSV 0x3fc
|
||||
#define MC_DISB_EXTRA_SNAP_LEVELS 0x408
|
||||
#define MC_APB_EXTRA_SNAP_LEVELS 0x2a4
|
||||
#define MC_AHB_EXTRA_SNAP_LEVELS 0x2a0
|
||||
#define MC_USBD_EXTRA_SNAP_LEVELS 0xa18
|
||||
#define MC_ISP_EXTRA_SNAP_LEVELS 0xa08
|
||||
#define MC_AUD_EXTRA_SNAP_LEVELS 0xa10
|
||||
#define MC_MSE_EXTRA_SNAP_LEVELS 0x40c
|
||||
#define MC_GK2_EXTRA_SNAP_LEVELS 0xa40
|
||||
#define MC_A9AVPPC_EXTRA_SNAP_LEVELS 0x414
|
||||
#define MC_FTOP_EXTRA_SNAP_LEVELS 0x2bc
|
||||
#define MC_JPG_EXTRA_SNAP_LEVELS 0xa3c
|
||||
#define MC_HOST_EXTRA_SNAP_LEVELS 0xa14
|
||||
#define MC_SAX_EXTRA_SNAP_LEVELS 0x2c0
|
||||
#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac
|
||||
#define MC_VICPC_EXTRA_SNAP_LEVELS 0xa1c
|
||||
#define MC_HDAPC_EXTRA_SNAP_LEVELS 0xa48
|
||||
#define MC_AVP_EXTRA_SNAP_LEVELS 0x2a8
|
||||
#define MC_USBX_EXTRA_SNAP_LEVELS 0x404
|
||||
#define MC_PCX_EXTRA_SNAP_LEVELS 0x2b8
|
||||
#define MC_SD_EXTRA_SNAP_LEVELS 0xa04
|
||||
#define MC_DFD_EXTRA_SNAP_LEVELS 0xa4c
|
||||
#define MC_VE_EXTRA_SNAP_LEVELS 0x2d8
|
||||
#define MC_GK_EXTRA_SNAP_LEVELS 0xa00
|
||||
#define MC_VE2_EXTRA_SNAP_LEVELS 0x410
|
||||
#define MC_SDM_EXTRA_SNAP_LEVELS 0xa44
|
||||
#define MC_VIDEO_PROTECT_BOM 0x648
|
||||
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
|
||||
#define MC_VIDEO_PROTECT_BOM_ADR_HI 0x978
|
||||
#define MC_VIDEO_PROTECT_REG_CTRL 0x650
|
||||
#define MC_ERR_VPR_STATUS 0x654
|
||||
#define MC_ERR_VPR_ADR 0x658
|
||||
#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418
|
||||
#define MC_VIDEO_PROTECT_VPR_OVERRIDE1 0x590
|
||||
#define MC_IRAM_BOM 0x65c
|
||||
#define MC_IRAM_TOM 0x660
|
||||
#define MC_IRAM_ADR_HI 0x980
|
||||
#define MC_IRAM_REG_CTRL 0x964
|
||||
#define MC_EMEM_CFG_ACCESS_CTRL 0x664
|
||||
#define MC_TZ_SECURITY_CTRL 0x668
|
||||
#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c
|
||||
#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO 0x6b4
|
||||
#define MC_EMEM_ARB_RING0_THROTTLE_MASK 0x6bc
|
||||
#define MC_EMEM_ARB_NISO_THROTTLE_MASK 0x6b8
|
||||
#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1 0xb80
|
||||
#define MC_SEC_CARVEOUT_BOM 0x670
|
||||
#define MC_SEC_CARVEOUT_SIZE_MB 0x674
|
||||
#define MC_SEC_CARVEOUT_ADR_HI 0x9d4
|
||||
#define MC_SEC_CARVEOUT_REG_CTRL 0x678
|
||||
#define MC_ERR_SEC_STATUS 0x67c
|
||||
#define MC_ERR_SEC_ADR 0x680
|
||||
#define MC_PC_IDLE_CLOCK_GATE_CONFIG 0x684
|
||||
#define MC_STUTTER_CONTROL 0x688
|
||||
#define MC_RESERVED_RSV_1 0x958
|
||||
#define MC_DVFS_PIPE_SELECT 0x95c
|
||||
#define MC_AHB_PTSA_MIN 0x4e0
|
||||
#define MC_AUD_PTSA_MIN 0x54c
|
||||
#define MC_MLL_MPCORER_PTSA_RATE 0x44c
|
||||
#define MC_RING2_PTSA_RATE 0x440
|
||||
#define MC_USBD_PTSA_RATE 0x530
|
||||
#define MC_USBX_PTSA_MIN 0x528
|
||||
#define MC_USBD_PTSA_MIN 0x534
|
||||
#define MC_APB_PTSA_MAX 0x4f0
|
||||
#define MC_JPG_PTSA_RATE 0x584
|
||||
#define MC_DIS_PTSA_MIN 0x420
|
||||
#define MC_AVP_PTSA_MAX 0x4fc
|
||||
#define MC_AVP_PTSA_RATE 0x4f4
|
||||
#define MC_RING1_PTSA_MIN 0x480
|
||||
#define MC_DIS_PTSA_MAX 0x424
|
||||
#define MC_SD_PTSA_MAX 0x4d8
|
||||
#define MC_MSE_PTSA_RATE 0x4c4
|
||||
#define MC_VICPC_PTSA_MIN 0x558
|
||||
#define MC_PCX_PTSA_MAX 0x4b4
|
||||
#define MC_ISP_PTSA_RATE 0x4a0
|
||||
#define MC_A9AVPPC_PTSA_MIN 0x48c
|
||||
#define MC_RING2_PTSA_MAX 0x448
|
||||
#define MC_AUD_PTSA_RATE 0x548
|
||||
#define MC_HOST_PTSA_MIN 0x51c
|
||||
#define MC_MLL_MPCORER_PTSA_MAX 0x454
|
||||
#define MC_SD_PTSA_MIN 0x4d4
|
||||
#define MC_RING1_PTSA_RATE 0x47c
|
||||
#define MC_JPG_PTSA_MIN 0x588
|
||||
#define MC_HDAPC_PTSA_MIN 0x62c
|
||||
#define MC_AVP_PTSA_MIN 0x4f8
|
||||
#define MC_JPG_PTSA_MAX 0x58c
|
||||
#define MC_VE_PTSA_MAX 0x43c
|
||||
#define MC_DFD_PTSA_MAX 0x63c
|
||||
#define MC_VICPC_PTSA_RATE 0x554
|
||||
#define MC_GK_PTSA_MAX 0x544
|
||||
#define MC_VICPC_PTSA_MAX 0x55c
|
||||
#define MC_SDM_PTSA_MAX 0x624
|
||||
#define MC_SAX_PTSA_RATE 0x4b8
|
||||
#define MC_PCX_PTSA_MIN 0x4b0
|
||||
#define MC_APB_PTSA_MIN 0x4ec
|
||||
#define MC_GK2_PTSA_MIN 0x614
|
||||
#define MC_PCX_PTSA_RATE 0x4ac
|
||||
#define MC_RING1_PTSA_MAX 0x484
|
||||
#define MC_HDAPC_PTSA_RATE 0x628
|
||||
#define MC_MLL_MPCORER_PTSA_MIN 0x450
|
||||
#define MC_GK2_PTSA_MAX 0x618
|
||||
#define MC_AUD_PTSA_MAX 0x550
|
||||
#define MC_GK2_PTSA_RATE 0x610
|
||||
#define MC_ISP_PTSA_MAX 0x4a8
|
||||
#define MC_DISB_PTSA_RATE 0x428
|
||||
#define MC_VE2_PTSA_MAX 0x49c
|
||||
#define MC_DFD_PTSA_MIN 0x638
|
||||
#define MC_FTOP_PTSA_RATE 0x50c
|
||||
#define MC_A9AVPPC_PTSA_RATE 0x488
|
||||
#define MC_VE2_PTSA_MIN 0x498
|
||||
#define MC_USBX_PTSA_MAX 0x52c
|
||||
#define MC_DIS_PTSA_RATE 0x41c
|
||||
#define MC_USBD_PTSA_MAX 0x538
|
||||
#define MC_A9AVPPC_PTSA_MAX 0x490
|
||||
#define MC_USBX_PTSA_RATE 0x524
|
||||
#define MC_FTOP_PTSA_MAX 0x514
|
||||
#define MC_HDAPC_PTSA_MAX 0x630
|
||||
#define MC_SD_PTSA_RATE 0x4d0
|
||||
#define MC_DFD_PTSA_RATE 0x634
|
||||
#define MC_FTOP_PTSA_MIN 0x510
|
||||
#define MC_SDM_PTSA_RATE 0x61c
|
||||
#define MC_AHB_PTSA_RATE 0x4dc
|
||||
#define MC_SMMU_SMMU_PTSA_MAX 0x460
|
||||
#define MC_RING2_PTSA_MIN 0x444
|
||||
#define MC_SDM_PTSA_MIN 0x620
|
||||
#define MC_APB_PTSA_RATE 0x4e8
|
||||
#define MC_MSE_PTSA_MIN 0x4c8
|
||||
#define MC_HOST_PTSA_RATE 0x518
|
||||
#define MC_VE_PTSA_RATE 0x434
|
||||
#define MC_AHB_PTSA_MAX 0x4e4
|
||||
#define MC_SAX_PTSA_MIN 0x4bc
|
||||
#define MC_SMMU_SMMU_PTSA_MIN 0x45c
|
||||
#define MC_ISP_PTSA_MIN 0x4a4
|
||||
#define MC_HOST_PTSA_MAX 0x520
|
||||
#define MC_SAX_PTSA_MAX 0x4c0
|
||||
#define MC_VE_PTSA_MIN 0x438
|
||||
#define MC_GK_PTSA_MIN 0x540
|
||||
#define MC_MSE_PTSA_MAX 0x4cc
|
||||
#define MC_DISB_PTSA_MAX 0x430
|
||||
#define MC_DISB_PTSA_MIN 0x42c
|
||||
#define MC_SMMU_SMMU_PTSA_RATE 0x458
|
||||
#define MC_VE2_PTSA_RATE 0x494
|
||||
#define MC_GK_PTSA_RATE 0x53c
|
||||
#define MC_PTSA_GRANT_DECREMENT 0x960
|
||||
#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
|
||||
#define MC_LATENCY_ALLOWANCE_AXIAP_0 0x3a0
|
||||
#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
|
||||
#define MC_LATENCY_ALLOWANCE_SE_0 0x3e0
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
|
||||
#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
|
||||
#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
|
||||
#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
|
||||
#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3d8
|
||||
#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
|
||||
#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
|
||||
#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 0x694
|
||||
#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
|
||||
#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
|
||||
#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
|
||||
#define MC_LATENCY_ALLOWANCE_TSECB_0 0x3f0
|
||||
#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 0x698
|
||||
#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
|
||||
#define MC_LATENCY_ALLOWANCE_APE_0 0x3dc
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 0x6a0
|
||||
#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4
|
||||
#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3e8
|
||||
#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
|
||||
#define MC_LATENCY_ALLOWANCE_HC_1 0x314
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0
|
||||
#define MC_LATENCY_ALLOWANCE_NVJPG_0 0x3e4
|
||||
#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
|
||||
#define MC_LATENCY_ALLOWANCE_ETR_0 0x3ec
|
||||
#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
|
||||
#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 0x69c
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 0x6a4
|
||||
#define MC_LATENCY_ALLOWANCE_SATA_0 0x350
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 0x690
|
||||
#define MC_LATENCY_ALLOWANCE_HC_0 0x310
|
||||
#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8
|
||||
#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388
|
||||
#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328
|
||||
#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
|
||||
#define MC_MIN_LENGTH_APE_0 0xb34
|
||||
#define MC_MIN_LENGTH_DCB_2 0x8a8
|
||||
#define MC_MIN_LENGTH_A9AVP_0 0x950
|
||||
#define MC_MIN_LENGTH_TSEC_0 0x93c
|
||||
#define MC_MIN_LENGTH_DC_1 0x898
|
||||
#define MC_MIN_LENGTH_AXIAP_0 0x94c
|
||||
#define MC_MIN_LENGTH_ISP2B_0 0x930
|
||||
#define MC_MIN_LENGTH_VI2_0 0x944
|
||||
#define MC_MIN_LENGTH_DCB_0 0x8a0
|
||||
#define MC_MIN_LENGTH_DCB_1 0x8a4
|
||||
#define MC_MIN_LENGTH_PPCS_1 0x8f4
|
||||
#define MC_MIN_LENGTH_NVJPG_0 0xb3c
|
||||
#define MC_MIN_LENGTH_HDA_0 0x8c4
|
||||
#define MC_MIN_LENGTH_NVENC_0 0x8d4
|
||||
#define MC_MIN_LENGTH_SDMMC_0 0xb18
|
||||
#define MC_MIN_LENGTH_ISP2B_1 0x934
|
||||
#define MC_MIN_LENGTH_HC_1 0x8c0
|
||||
#define MC_MIN_LENGTH_DC_3 0xb20
|
||||
#define MC_MIN_LENGTH_AVPC_0 0x890
|
||||
#define MC_MIN_LENGTH_VIC_0 0x940
|
||||
#define MC_MIN_LENGTH_ISP2_0 0x91c
|
||||
#define MC_MIN_LENGTH_HC_0 0x8bc
|
||||
#define MC_MIN_LENGTH_SE_0 0xb38
|
||||
#define MC_MIN_LENGTH_NVDEC_0 0xb30
|
||||
#define MC_MIN_LENGTH_SATA_0 0x8fc
|
||||
#define MC_MIN_LENGTH_DC_0 0x894
|
||||
#define MC_MIN_LENGTH_XUSB_1 0x92c
|
||||
#define MC_MIN_LENGTH_DC_2 0x89c
|
||||
#define MC_MIN_LENGTH_SDMMCAA_0 0xb14
|
||||
#define MC_MIN_LENGTH_GPU_0 0xb04
|
||||
#define MC_MIN_LENGTH_ETR_0 0xb44
|
||||
#define MC_MIN_LENGTH_AFI_0 0x88c
|
||||
#define MC_MIN_LENGTH_PPCS_0 0x8f0
|
||||
#define MC_MIN_LENGTH_ISP2_1 0x920
|
||||
#define MC_MIN_LENGTH_XUSB_0 0x928
|
||||
#define MC_MIN_LENGTH_MPCORE_0 0x8cc
|
||||
#define MC_MIN_LENGTH_TSECB_0 0xb48
|
||||
#define MC_MIN_LENGTH_SDMMCA_0 0xb10
|
||||
#define MC_MIN_LENGTH_GPU2_0 0xb40
|
||||
#define MC_MIN_LENGTH_SDMMCAB_0 0xb1c
|
||||
#define MC_MIN_LENGTH_PTC_0 0x8f8
|
||||
#define MC_EMEM_ARB_OVERRIDE_1 0x968
|
||||
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0 0x984
|
||||
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1 0x988
|
||||
#define MC_EMEM_ARB_STATS_0 0x990
|
||||
#define MC_EMEM_ARB_STATS_1 0x994
|
||||
#define MC_MTS_CARVEOUT_BOM 0x9a0
|
||||
#define MC_MTS_CARVEOUT_SIZE_MB 0x9a4
|
||||
#define MC_MTS_CARVEOUT_ADR_HI 0x9a8
|
||||
#define MC_MTS_CARVEOUT_REG_CTRL 0x9ac
|
||||
#define MC_ERR_MTS_STATUS 0x9b0
|
||||
#define MC_ERR_MTS_ADR 0x9b4
|
||||
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
|
||||
#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 0xd74
|
||||
#define MC_SECURITY_CARVEOUT4_CFG0 0xcf8
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 0xd10
|
||||
#define MC_SECURITY_CARVEOUT4_SIZE_128KB 0xd04
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 0xc28
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 0xc30
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 0xc8c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 0xd1c
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 0xd70
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 0xc2c
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 0xd7c
|
||||
#define MC_SECURITY_CARVEOUT3_SIZE_128KB 0xcb4
|
||||
#define MC_SECURITY_CARVEOUT2_CFG0 0xc58
|
||||
#define MC_SECURITY_CARVEOUT1_CFG0 0xc08
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 0xc84
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 0xc68
|
||||
#define MC_SECURITY_CARVEOUT3_BOM 0xcac
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 0xc70
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 0xd78
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 0xc7c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 0xd18
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 0xcbc
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 0xc38
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 0xc34
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 0xcc0
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 0xd60
|
||||
#define MC_SECURITY_CARVEOUT3_CFG0 0xca8
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 0xcb8
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 0xc88
|
||||
#define MC_SECURITY_CARVEOUT2_SIZE_128KB 0xc64
|
||||
#define MC_SECURITY_CARVEOUT5_BOM_HI 0xd50
|
||||
#define MC_SECURITY_CARVEOUT1_SIZE_128KB 0xc14
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 0xd14
|
||||
#define MC_SECURITY_CARVEOUT1_BOM 0xc0c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 0xd2c
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 0xd68
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 0xcc8
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 0xd58
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 0xd24
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 0xcc4
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 0xc78
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 0xc1c
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 0xc18
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 0xd28
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 0xd5c
|
||||
#define MC_SECURITY_CARVEOUT3_BOM_HI 0xcb0
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 0xcd8
|
||||
#define MC_SECURITY_CARVEOUT2_BOM_HI 0xc60
|
||||
#define MC_SECURITY_CARVEOUT4_BOM_HI 0xd00
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 0xd64
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 0xcdc
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 0xc80
|
||||
#define MC_SECURITY_CARVEOUT5_SIZE_128KB 0xd54
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 0xd20
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 0xcd4
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 0xd0c
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 0xc74
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 0xccc
|
||||
#define MC_SECURITY_CARVEOUT4_BOM 0xcfc
|
||||
#define MC_SECURITY_CARVEOUT5_CFG0 0xd48
|
||||
#define MC_SECURITY_CARVEOUT2_BOM 0xc5c
|
||||
#define MC_SECURITY_CARVEOUT5_BOM 0xd4c
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 0xc24
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 0xd6c
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 0xcd0
|
||||
#define MC_SECURITY_CARVEOUT1_BOM_HI 0xc10
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 0xc20
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 0xc3c
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08
|
||||
#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
|
||||
#define MC_DA_CONFIG0 0x9dc
|
||||
|
||||
/* Virtual aliases */
|
||||
#define VIRT_MC_SECURITY_CFG3 MAKE_MC_REG(MC_SECURITY_CFG3)
|
||||
|
||||
/* Memory Controller clients */
|
||||
#define CLIENT_ACCESS_NUM_CLIENTS 32
|
||||
typedef enum {
|
||||
/* _ACCESS0 */
|
||||
CSR_PTCR = (0 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0A = (1 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0AB = (2 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0B = (3 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0BB = (4 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0C = (5 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0CB = (6 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_AFIR = (14 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_AVPCARM7R = (15 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAYHC = (16 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAYHCB = (17 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_HDAR = (21 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_HOST1XDMAR = (22 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_HOST1XR = (23 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_NVENCSRD = (28 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_PPCSAHBDMAR = (29 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_PPCSAHBSLVR = (30 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_SATAR = (31 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
|
||||
/* _ACCESS1 */
|
||||
CSR_VDEBSEVR = (34 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_VDEMBER = (35 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_VDEMCER = (36 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_VDETPER = (37 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_MPCORELPR = (38 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_MPCORER = (39 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_NVENCSWR = (43 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_AFIW = (49 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_AVPCARM7W = (50 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_HDAW = (53 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_HOST1XW = (54 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_MPCORELPW = (56 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_MPCOREW = (57 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_PPCSAHBDMAW = (59 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_PPCSAHBSLVW = (60 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_SATAW = (61 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_VDEBSEVW = (62 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_VDEDBGW = (63 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
|
||||
/* _ACCESS2 */
|
||||
CSW_VDEMBEW = (64 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_VDETPMW = (65 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_ISPRA = (68 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWA = (70 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWB = (71 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_XUSB_HOSTR = (74 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_XUSB_HOSTW = (75 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_XUSB_DEVR = (76 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_XUSB_DEVW = (77 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_ISPRAB = (78 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWAB = (80 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWBB = (81 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_TSECSRD = (84 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_TSECSWR = (85 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_A9AVPSCR = (86 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_A9AVPSCW = (87 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_GPUSRD = (88 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_GPUSWR = (89 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_DISPLAYT = (90 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
|
||||
/* _ACCESS3 */
|
||||
CSR_SDMMCRA = (96 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_SDMMCRAA = (97 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_SDMMCR = (98 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_SDMMCRAB = (99 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCWA = (100 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCWAA = (101 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCW = (102 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCWAB = (103 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_VICSRD = (108 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_VICSWR = (109 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_VIW = (114 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_DISPLAYD = (115 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_NVDECSRD = (120 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_NVDECSWR = (121 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_APER = (122 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_APEW = (123 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_NVJPGSRD = (126 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_NVJPGSWR = (127 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
|
||||
/* _ACCESS4 */
|
||||
CSR_SESRD = (128 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_SESWR = (129 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_AXIAPR = (130 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_AXIAPW = (131 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_ETRR = (132 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_ETRW = (133 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_TSECSRDB = (134 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_TSECSWRB = (135 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_GPUSRD2 = (136 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_GPUSWR2 = (137 - (CLIENT_ACCESS_NUM_CLIENTS * 4))
|
||||
} McClient;
|
||||
|
||||
/* Memory Controller carveouts */
|
||||
#define CARVEOUT_ID_MIN 1
|
||||
#define CARVEOUT_ID_MAX 5
|
||||
typedef struct {
|
||||
uint32_t config;
|
||||
uint32_t paddr_low;
|
||||
uint32_t paddr_high;
|
||||
uint32_t size_big_pages;
|
||||
uint32_t client_access_0;
|
||||
uint32_t client_access_1;
|
||||
uint32_t client_access_2;
|
||||
uint32_t client_access_3;
|
||||
uint32_t client_access_4;
|
||||
uint32_t client_force_internal_access_0;
|
||||
uint32_t client_force_internal_access_1;
|
||||
uint32_t client_force_internal_access_2;
|
||||
uint32_t client_force_internal_access_3;
|
||||
uint32_t client_force_internal_access_4;
|
||||
uint8_t padding[0x18];
|
||||
} security_carveout_t;
|
||||
|
||||
void disable_bpmp_access_to_dram(void);
|
||||
|
||||
#endif
|
||||
52
exosphere/lp0fw/src/misc.c
Normal file
52
exosphere/lp0fw/src/misc.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "misc.h"
|
||||
#include "fuse.h"
|
||||
#include "sysreg.h"
|
||||
#include "pmc.h"
|
||||
|
||||
void misc_configure_device_dbg_settings(void) {
|
||||
/* Enable RTCK daisychaining by setting TBE bit. */
|
||||
APB_MISC_PP_CONFIG_CTL_0 = 0x80;
|
||||
|
||||
/* Literally none of this is documented in the TRM, lol. */
|
||||
if (FUSE_CHIP_REGS->FUSE_SECURITY_MODE == 1) {
|
||||
uint32_t secure_boot_val = 0b0100; /* Sets NIDEN for aarch64. */
|
||||
uint32_t misc_val = 0x40;
|
||||
if (APBDEV_PMC_STICKY_BITS_0 & 0x40) {
|
||||
misc_val = 0x0;
|
||||
} else {
|
||||
secure_boot_val = 0b1101; /* Sets SPNIDEN, NIDEN, DBGEN for aarch64. */
|
||||
}
|
||||
SB_PFCFG_0 = (SB_PFCFG_0 & ~0b1111) | secure_boot_val; /* Configures debug bits. */
|
||||
APB_MISC_PP_CONFIG_CTL_0 |= misc_val; /* Undocumented, seems to control invasive debugging/JTAG. */
|
||||
}
|
||||
|
||||
/* Set sticky bits based SECURITY_MODE. */
|
||||
APBDEV_PMC_STICKY_BITS_0 |= FUSE_CHIP_REGS->FUSE_SECURITY_MODE;
|
||||
|
||||
/* Set E_INPUT in PINMUX_AUX_GPIO_PA6_0 */
|
||||
PINMUX_AUX_GPIO_PA6_0 |= 0x40;
|
||||
}
|
||||
|
||||
void misc_restore_ram_svop(void) {
|
||||
/* This sets CFG2TMC_RAM_SVOP_PDP to 0x2. */
|
||||
APB_MISC_GP_ASDBGREG_0 = (APB_MISC_GP_ASDBGREG_0 & 0xFCFFFFFF) | 0x02000000;
|
||||
}
|
||||
42
exosphere/lp0fw/src/misc.h
Normal file
42
exosphere/lp0fw/src/misc.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_MISC_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_MISC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define MISC_BASE (0x70000000)
|
||||
|
||||
#define MAKE_MISC_REG(n) MAKE_REG32(MISC_BASE + n)
|
||||
|
||||
#define APB_MISC_PP_CONFIG_CTL_0 MAKE_MISC_REG(0x024)
|
||||
|
||||
#define APB_MISC_GP_ASDBGREG_0 MAKE_MISC_REG(0x810)
|
||||
|
||||
#define PINMUX_AUX_PWR_I2C_SCL_0 MAKE_MISC_REG(0x30DC)
|
||||
#define PINMUX_AUX_PWR_I2C_SDA_0 MAKE_MISC_REG(0x30E0)
|
||||
#define PINMUX_AUX_DVFS_PWM_0 MAKE_MISC_REG(0x3184)
|
||||
|
||||
#define PINMUX_AUX_GPIO_PA6_0 MAKE_MISC_REG(0x3244)
|
||||
|
||||
void misc_configure_device_dbg_settings(void);
|
||||
|
||||
void misc_restore_ram_svop(void);
|
||||
|
||||
#endif
|
||||
69
exosphere/lp0fw/src/pmc.h
Normal file
69
exosphere/lp0fw/src/pmc.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_PMC_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_PMC_H
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define PMC_BASE (0x7000E400)
|
||||
|
||||
#define MAKE_PMC_REG(ofs) (MAKE_REG32(PMC_BASE + ofs))
|
||||
|
||||
#define APBDEV_PMC_CNTRL_0 MAKE_PMC_REG(0x000)
|
||||
|
||||
#define APBDEV_PMC_DPD_SAMPLE_0 MAKE_PMC_REG(0x020)
|
||||
|
||||
#define APBDEV_PMC_DPD_ENABLE_0 MAKE_PMC_REG(0x024)
|
||||
|
||||
#define APBDEV_PMC_CLAMP_STATUS_0 MAKE_PMC_REG(0x02C)
|
||||
|
||||
#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x030)
|
||||
#define APBDEV_PMC_REMOVE_CLAMPING_CMD_0 MAKE_PMC_REG(0x034)
|
||||
#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x038)
|
||||
|
||||
#define APBDEV_PMC_SCRATCH12_0 MAKE_PMC_REG(0x080)
|
||||
#define APBDEV_PMC_SCRATCH13_0 MAKE_PMC_REG(0x084)
|
||||
#define APBDEV_PMC_SCRATCH18_0 MAKE_PMC_REG(0x098)
|
||||
#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818)
|
||||
|
||||
#define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4)
|
||||
|
||||
#define APBDEV_PMC_STICKY_BITS_0 MAKE_PMC_REG(0x2C0)
|
||||
#define APBDEV_PMC_SEC_DISABLE2_0 MAKE_PMC_REG(0x2C4)
|
||||
#define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8)
|
||||
|
||||
#define APBDEV_PMC_SECURE_SCRATCH21_0 MAKE_PMC_REG(0x334)
|
||||
#define APBDEV_PMC_SECURE_SCRATCH32_0 MAKE_PMC_REG(0x360)
|
||||
#define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_PMC_REG(0x368)
|
||||
#define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_PMC_REG(0x36C)
|
||||
|
||||
#define APBDEV_PMC_SECURE_SCRATCH112_0 MAKE_PMC_REG(0xB18)
|
||||
#define APBDEV_PMC_SECURE_SCRATCH113_0 MAKE_PMC_REG(0xB1C)
|
||||
#define APBDEV_PMC_SECURE_SCRATCH114_0 MAKE_PMC_REG(0xB20)
|
||||
#define APBDEV_PMC_SECURE_SCRATCH115_0 MAKE_PMC_REG(0xB24)
|
||||
|
||||
#define APBDEV_PMC_IO_DPD3_REQ_0 MAKE_PMC_REG(0x45C)
|
||||
#define APBDEV_PMC_IO_DPD3_STATUS_0 MAKE_PMC_REG(0x460)
|
||||
|
||||
#define APBDEV_PMC_IO_DPD4_REQ_0 MAKE_PMC_REG(0x464)
|
||||
#define APBDEV_PMC_IO_DPD4_STATUS_0 MAKE_PMC_REG(0x468)
|
||||
|
||||
#define APBDEV_PMC_SET_SW_CLAMP_0 MAKE_PMC_REG(0x47C)
|
||||
|
||||
#define APBDEV_PMC_DDR_CNTRL_0 MAKE_PMC_REG(0x4E4)
|
||||
|
||||
#endif
|
||||
252
exosphere/lp0fw/src/se.c
Normal file
252
exosphere/lp0fw/src/se.c
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "lp0.h"
|
||||
#include "se.h"
|
||||
|
||||
static void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||
|
||||
/* Initialize a SE linked list. */
|
||||
static void __attribute__((__noinline__)) ll_init(volatile se_ll_t *ll, void *buffer, size_t size) {
|
||||
ll->num_entries = 0; /* 1 Entry. */
|
||||
|
||||
if (buffer != NULL) {
|
||||
ll->addr_info.address = (uint32_t) buffer;
|
||||
ll->addr_info.size = (uint32_t) size;
|
||||
} else {
|
||||
ll->addr_info.address = 0;
|
||||
ll->addr_info.size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void se_check_error_status_reg(void) {
|
||||
if (se_get_regs()->ERR_STATUS_REG) {
|
||||
reboot();
|
||||
}
|
||||
}
|
||||
|
||||
void se_check_for_error(void) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) {
|
||||
reboot();
|
||||
}
|
||||
}
|
||||
|
||||
void se_verify_flags_cleared(void) {
|
||||
if (se_get_regs()->FLAGS_REG & 3) {
|
||||
reboot();
|
||||
}
|
||||
}
|
||||
|
||||
void clear_aes_keyslot(unsigned int keyslot) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
/* Zero out the whole keyslot and IV. */
|
||||
for (unsigned int i = 0; i < 0x10; i++) {
|
||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
|
||||
se->AES_KEYTABLE_DATA = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void clear_rsa_keyslot(unsigned int keyslot) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
if (keyslot >= KEYSLOT_RSA_MAX) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
/* Zero out the whole keyslot. */
|
||||
for (unsigned int i = 0; i < 0x40; i++) {
|
||||
/* Select Keyslot Modulus[i] */
|
||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
|
||||
se->RSA_KEYTABLE_DATA = 0;
|
||||
}
|
||||
for (unsigned int i = 0; i < 0x40; i++) {
|
||||
/* Select Keyslot Expontent[i] */
|
||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
||||
se->RSA_KEYTABLE_DATA = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void clear_aes_keyslot_iv(unsigned int keyslot) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < (0x10 >> 2); i++) {
|
||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
||||
se->AES_KEYTABLE_DATA = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
se_ll_t in_ll;
|
||||
se_ll_t out_ll;
|
||||
|
||||
ll_init(&in_ll, (void *)src, src_size);
|
||||
ll_init(&out_ll, dst, dst_size);
|
||||
|
||||
/* Set the LLs. */
|
||||
se->IN_LL_ADDR_REG = (uint32_t)(&in_ll);
|
||||
se->OUT_LL_ADDR_REG = (uint32_t) (&out_ll);
|
||||
|
||||
/* Set registers for operation. */
|
||||
se->ERR_STATUS_REG = se->ERR_STATUS_REG;
|
||||
se->INT_STATUS_REG = se->INT_STATUS_REG;
|
||||
se->OPERATION_REG = op;
|
||||
|
||||
while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
|
||||
se_check_for_error();
|
||||
}
|
||||
|
||||
/* Secure AES Functionality. */
|
||||
void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, size_t src_size) {
|
||||
uint8_t block[0x10] = {0};
|
||||
|
||||
if (src_size > sizeof(block) || dst_size > sizeof(block)) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
/* Load src data into block. */
|
||||
if (src_size != 0) {
|
||||
memcpy(block, src, src_size);
|
||||
}
|
||||
|
||||
/* Trigger AES operation. */
|
||||
se_get_regs()->BLOCK_COUNT_REG = 0;
|
||||
trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
|
||||
|
||||
/* Copy output data into dst. */
|
||||
if (dst_size != 0) {
|
||||
memcpy(dst, block, dst_size);
|
||||
}
|
||||
}
|
||||
|
||||
void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
|
||||
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
|
||||
se->CRYPTO_REG = keyslot << 24 | 0x100;
|
||||
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
||||
}
|
||||
|
||||
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
|
||||
se->CRYPTO_REG = keyslot << 24;
|
||||
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
||||
}
|
||||
|
||||
void shift_left_xor_rb(uint8_t *key) {
|
||||
uint8_t prev_high_bit = 0;
|
||||
for (unsigned int i = 0; i < 0x10; i++) {
|
||||
uint8_t cur_byte = key[0xF - i];
|
||||
key[0xF - i] = (cur_byte << 1) | (prev_high_bit);
|
||||
prev_high_bit = cur_byte >> 7;
|
||||
}
|
||||
if (prev_high_bit) {
|
||||
key[0xF] ^= 0x87;
|
||||
}
|
||||
}
|
||||
|
||||
void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
/* Generate the derived key, to be XOR'd with final output block. */
|
||||
uint8_t ALIGN(16) derived_key[0x10] = {0};
|
||||
se_aes_ecb_encrypt_block(keyslot, derived_key, sizeof(derived_key), derived_key, sizeof(derived_key), config_high);
|
||||
shift_left_xor_rb(derived_key);
|
||||
if (data_size & 0xF) {
|
||||
shift_left_xor_rb(derived_key);
|
||||
}
|
||||
|
||||
se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
|
||||
se->CRYPTO_REG = (keyslot << 24) | (0x145);
|
||||
clear_aes_keyslot_iv(keyslot);
|
||||
|
||||
unsigned int num_blocks = (data_size + 0xF) >> 4;
|
||||
/* Handle aligned blocks. */
|
||||
if (num_blocks > 1) {
|
||||
se->BLOCK_COUNT_REG = num_blocks - 2;
|
||||
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
|
||||
se->CRYPTO_REG |= 0x80;
|
||||
}
|
||||
|
||||
/* Create final block. */
|
||||
uint8_t ALIGN(16) last_block[0x10] = {0};
|
||||
if (data_size & 0xF) {
|
||||
memcpy(last_block, data + (data_size & ~0xF), data_size & 0xF);
|
||||
last_block[data_size & 0xF] = 0x80; /* Last block = data || 100...0 */
|
||||
} else if (data_size >= 0x10) {
|
||||
memcpy(last_block, data + data_size - 0x10, 0x10);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < 0x10; i++) {
|
||||
last_block[i] ^= derived_key[i];
|
||||
}
|
||||
|
||||
/* Perform last operation. */
|
||||
se->BLOCK_COUNT_REG = 0;
|
||||
trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
|
||||
|
||||
/* Copy output CMAC. */
|
||||
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
|
||||
((uint32_t *)cmac)[i] = ((volatile uint32_t *)se->HASH_RESULT_REG)[i];
|
||||
}
|
||||
}
|
||||
|
||||
void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size) {
|
||||
se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0x202);
|
||||
}
|
||||
|
||||
void se_aes_256_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
||||
volatile tegra_se_t *se = se_get_regs();
|
||||
|
||||
if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY) | (0x202 << 16);
|
||||
se->CRYPTO_REG = (keyslot << 24) | 0x66;
|
||||
clear_aes_keyslot_iv(keyslot);
|
||||
se->BLOCK_COUNT_REG = (src_size >> 4) - 1;
|
||||
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
|
||||
}
|
||||
188
exosphere/lp0fw/src/se.h
Normal file
188
exosphere/lp0fw/src/se.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_SE_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_SE_H
|
||||
|
||||
#define SE_BASE 0x70012000
|
||||
#define MAKE_SE_REG(n) MAKE_REG32(SE_BASE + n)
|
||||
|
||||
#define KEYSLOT_SWITCH_LP0TZRAMKEY 0x2
|
||||
#define KEYSLOT_SWITCH_SRKGENKEY 0x8
|
||||
#define KEYSLOT_SWITCH_PACKAGE2KEY 0x8
|
||||
#define KEYSLOT_SWITCH_TEMPKEY 0x9
|
||||
#define KEYSLOT_SWITCH_SESSIONKEY 0xA
|
||||
#define KEYSLOT_SWITCH_RNGKEY 0xB
|
||||
#define KEYSLOT_SWITCH_MASTERKEY 0xC
|
||||
#define KEYSLOT_SWITCH_DEVICEKEY 0xD
|
||||
|
||||
/* This keyslot was added in 4.0.0. */
|
||||
#define KEYSLOT_SWITCH_4XNEWDEVICEKEYGENKEY 0xD
|
||||
#define KEYSLOT_SWITCH_4XNEWCONSOLEKEYGENKEY 0xE
|
||||
#define KEYSLOT_SWITCH_4XOLDDEVICEKEY 0xF
|
||||
|
||||
/* This keyslot was added in 5.0.0. */
|
||||
#define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA
|
||||
|
||||
#define KEYSLOT_AES_MAX 0x10
|
||||
#define KEYSLOT_RSA_MAX 0x2
|
||||
|
||||
#define KEYSIZE_AES_MAX 0x20
|
||||
#define KEYSIZE_RSA_MAX 0x100
|
||||
|
||||
#define ALG_SHIFT (12)
|
||||
#define ALG_DEC_SHIFT (8)
|
||||
#define ALG_NOP (0 << ALG_SHIFT)
|
||||
#define ALG_AES_ENC (1 << ALG_SHIFT)
|
||||
#define ALG_AES_DEC ((1 << ALG_DEC_SHIFT) | ALG_NOP)
|
||||
#define ALG_RNG (2 << ALG_SHIFT)
|
||||
#define ALG_SHA (3 << ALG_SHIFT)
|
||||
#define ALG_RSA (4 << ALG_SHIFT)
|
||||
|
||||
#define DST_SHIFT (2)
|
||||
#define DST_MEMORY (0 << DST_SHIFT)
|
||||
#define DST_HASHREG (1 << DST_SHIFT)
|
||||
#define DST_KEYTAB (2 << DST_SHIFT)
|
||||
#define DST_SRK (3 << DST_SHIFT)
|
||||
#define DST_RSAREG (4 << DST_SHIFT)
|
||||
|
||||
#define ENCMODE_SHIFT (24)
|
||||
#define DECMODE_SHIFT (16)
|
||||
#define ENCMODE_SHA256 (5 << ENCMODE_SHIFT)
|
||||
|
||||
#define HASH_DISABLE (0x0)
|
||||
#define HASH_ENABLE (0x1)
|
||||
|
||||
#define OP_ABORT 0
|
||||
#define OP_START 1
|
||||
#define OP_RESTART 2
|
||||
#define OP_CTX_SAVE 3
|
||||
#define OP_RESTART_IN 4
|
||||
|
||||
#define CTX_SAVE_SRC_SHIFT 29
|
||||
#define CTX_SAVE_SRC_STICKY_BITS (0 << CTX_SAVE_SRC_SHIFT)
|
||||
#define CTX_SAVE_SRC_KEYTABLE_AES (2 << CTX_SAVE_SRC_SHIFT)
|
||||
#define CTX_SAVE_SRC_KEYTABLE_RSA (1 << CTX_SAVE_SRC_SHIFT)
|
||||
#define CTX_SAVE_SRC_MEM (4 << CTX_SAVE_SRC_SHIFT)
|
||||
#define CTX_SAVE_SRC_SRK (6 << CTX_SAVE_SRC_SHIFT)
|
||||
|
||||
#define CTX_SAVE_KEY_LOW_BITS 0
|
||||
#define CTX_SAVE_KEY_HIGH_BITS 1
|
||||
#define CTX_SAVE_KEY_ORIGINAL_IV 2
|
||||
#define CTX_SAVE_KEY_UPDATED_IV 3
|
||||
|
||||
#define CTX_SAVE_STICKY_BIT_INDEX_SHIFT 24
|
||||
#define CTX_SAVE_KEY_INDEX_SHIFT 8
|
||||
#define CTX_SAVE_RSA_KEY_INDEX_SHIFT 16
|
||||
#define CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT 12
|
||||
|
||||
#define RSA_2048_BYTES 0x100
|
||||
|
||||
typedef struct {
|
||||
uint32_t _0x0;
|
||||
uint32_t _0x4;
|
||||
uint32_t OPERATION_REG;
|
||||
uint32_t INT_ENABLE_REG;
|
||||
uint32_t INT_STATUS_REG;
|
||||
uint32_t CONFIG_REG;
|
||||
uint32_t IN_LL_ADDR_REG;
|
||||
uint32_t _0x1C;
|
||||
uint32_t _0x20;
|
||||
uint32_t OUT_LL_ADDR_REG;
|
||||
uint32_t _0x28;
|
||||
uint32_t _0x2C;
|
||||
uint8_t HASH_RESULT_REG[0x20];
|
||||
uint8_t _0x50[0x20];
|
||||
uint32_t CONTEXT_SAVE_CONFIG_REG;
|
||||
uint8_t _0x74[0x18C];
|
||||
uint32_t SHA_CONFIG_REG;
|
||||
uint32_t SHA_MSG_LENGTH_REG;
|
||||
uint32_t _0x208;
|
||||
uint32_t _0x20C;
|
||||
uint32_t _0x210;
|
||||
uint32_t SHA_MSG_LEFT_REG;
|
||||
uint32_t _0x218;
|
||||
uint32_t _0x21C;
|
||||
uint32_t _0x220;
|
||||
uint32_t _0x224;
|
||||
uint8_t _0x228[0x58];
|
||||
uint32_t AES_KEY_READ_DISABLE_REG;
|
||||
uint32_t AES_KEYSLOT_FLAGS[0x10];
|
||||
uint8_t _0x2C4[0x3C];
|
||||
uint32_t _0x300;
|
||||
uint32_t CRYPTO_REG;
|
||||
uint32_t CRYPTO_CTR_REG[4];
|
||||
uint32_t BLOCK_COUNT_REG;
|
||||
uint32_t AES_KEYTABLE_ADDR;
|
||||
uint32_t AES_KEYTABLE_DATA;
|
||||
uint32_t _0x324;
|
||||
uint32_t _0x328;
|
||||
uint32_t _0x32C;
|
||||
uint32_t CRYPTO_KEYTABLE_DST_REG;
|
||||
uint8_t _0x334[0xC];
|
||||
uint32_t RNG_CONFIG_REG;
|
||||
uint32_t RNG_SRC_CONFIG_REG;
|
||||
uint32_t RNG_RESEED_INTERVAL_REG;
|
||||
uint8_t _0x34C[0xB4];
|
||||
uint32_t RSA_CONFIG;
|
||||
uint32_t RSA_KEY_SIZE_REG;
|
||||
uint32_t RSA_EXP_SIZE_REG;
|
||||
uint32_t RSA_KEY_READ_DISABLE_REG;
|
||||
uint32_t RSA_KEYSLOT_FLAGS[2];
|
||||
uint32_t _0x418;
|
||||
uint32_t _0x41C;
|
||||
uint32_t RSA_KEYTABLE_ADDR;
|
||||
uint32_t RSA_KEYTABLE_DATA;
|
||||
uint8_t RSA_OUTPUT[0x100];
|
||||
uint8_t _0x528[0x2D8];
|
||||
uint32_t FLAGS_REG;
|
||||
uint32_t ERR_STATUS_REG;
|
||||
uint32_t _0x808;
|
||||
uint32_t SPARE_0;
|
||||
uint32_t _0x810;
|
||||
uint32_t _0x814;
|
||||
uint32_t _0x818;
|
||||
uint32_t _0x81C;
|
||||
uint8_t _0x820[0x17E0];
|
||||
} tegra_se_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
uint32_t size;
|
||||
} se_addr_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t num_entries; /* Set to total entries - 1 */
|
||||
se_addr_info_t addr_info; /* This should really be an array...but for our use case it works. */
|
||||
} se_ll_t;
|
||||
|
||||
static inline volatile tegra_se_t *se_get_regs(void) {
|
||||
return (volatile tegra_se_t *)SE_BASE;
|
||||
}
|
||||
|
||||
void se_check_error_status_reg(void);
|
||||
void se_check_for_error(void);
|
||||
|
||||
void se_verify_flags_cleared(void);
|
||||
|
||||
void clear_aes_keyslot(unsigned int keyslot);
|
||||
void clear_rsa_keyslot(unsigned int keyslot);
|
||||
void clear_aes_keyslot_iv(unsigned int keyslot);
|
||||
|
||||
void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size);
|
||||
void se_aes_256_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||
|
||||
#endif
|
||||
115
exosphere/lp0fw/src/secmon.c
Normal file
115
exosphere/lp0fw/src/secmon.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "lp0.h"
|
||||
#include "secmon.h"
|
||||
#include "se.h"
|
||||
#include "fuse.h"
|
||||
#include "pmc.h"
|
||||
|
||||
/* "private" functions. */
|
||||
static bool secmon_should_clear_aes_keyslot(unsigned int keyslot);
|
||||
static void secmon_clear_unused_keyslots(void);
|
||||
static void secmon_decrypt_saved_image(void *dst, const void *src, size_t size);
|
||||
|
||||
void secmon_restore_to_tzram(const uint32_t target_firmware) {
|
||||
/* Newer warmboot binaries clear the untouched keyslots for safety. */
|
||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
secmon_clear_unused_keyslots();
|
||||
}
|
||||
|
||||
/* Decrypt Secure Monitor from DRAM into TZRAM. */
|
||||
void *tzram_src = (void *)(0x80010000);
|
||||
void *tzram_dst = (void *)(target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_500 ? 0x7C012000 : 0x7C010000);
|
||||
const size_t tzram_size = 0xE000;
|
||||
secmon_decrypt_saved_image(tzram_dst, tzram_src, tzram_size);
|
||||
|
||||
/* Nintendo clears DRAM, but I'm not sure why, given they lock out BPMP access to DRAM. */
|
||||
for (size_t i = 0; i < tzram_size/sizeof(uint32_t); i++) {
|
||||
((volatile uint32_t *)tzram_src)[i] = 0;
|
||||
}
|
||||
|
||||
/* Make security engine require secure busmaster. */
|
||||
se_get_regs()->_0x4 = 0;
|
||||
|
||||
/* TODO: se_verify_keys_unreadable(); */
|
||||
|
||||
/* TODO: pmc_lockout_wb_scratch_registers(); */
|
||||
|
||||
/* Disable fuse programming. */
|
||||
fuse_disable_programming();
|
||||
}
|
||||
|
||||
void secmon_decrypt_saved_image(void *dst, const void *src, size_t size) {
|
||||
/* First, AES-256-CBC decrypt the image into TZRAM. */
|
||||
se_aes_256_cbc_decrypt(KEYSLOT_SWITCH_LP0TZRAMKEY, dst, size, src, size);
|
||||
|
||||
/* Next, calculate CMAC. */
|
||||
uint32_t tzram_cmac[4] = {0, 0, 0, 0};
|
||||
se_compute_aes_256_cmac(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_cmac, sizeof(tzram_cmac), dst, size);
|
||||
|
||||
/* Validate the MAC against saved one in PMC scratch. */
|
||||
if (tzram_cmac[0] != APBDEV_PMC_SECURE_SCRATCH112_0 ||
|
||||
tzram_cmac[1] != APBDEV_PMC_SECURE_SCRATCH113_0 ||
|
||||
tzram_cmac[2] != APBDEV_PMC_SECURE_SCRATCH114_0 ||
|
||||
tzram_cmac[3] != APBDEV_PMC_SECURE_SCRATCH115_0) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
/* Clear the PMC scratch registers that hold the CMAC. */
|
||||
APBDEV_PMC_SECURE_SCRATCH112_0 = 0;
|
||||
APBDEV_PMC_SECURE_SCRATCH113_0 = 0;
|
||||
APBDEV_PMC_SECURE_SCRATCH114_0 = 0;
|
||||
APBDEV_PMC_SECURE_SCRATCH115_0 = 0;
|
||||
|
||||
/* Clear keyslot now that we're done with it. */
|
||||
clear_aes_keyslot(KEYSLOT_SWITCH_LP0TZRAMKEY);
|
||||
}
|
||||
|
||||
bool secmon_should_clear_aes_keyslot(unsigned int keyslot) {
|
||||
/* We'll just compare keyslot against a hardcoded list of keys. */
|
||||
static const uint8_t saved_keyslots[6] = {
|
||||
KEYSLOT_SWITCH_LP0TZRAMKEY,
|
||||
KEYSLOT_SWITCH_SESSIONKEY,
|
||||
KEYSLOT_SWITCH_RNGKEY,
|
||||
KEYSLOT_SWITCH_MASTERKEY,
|
||||
KEYSLOT_SWITCH_DEVICEKEY,
|
||||
KEYSLOT_SWITCH_4XOLDDEVICEKEY
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(saved_keyslots)/sizeof(saved_keyslots[0]); i++) {
|
||||
if (keyslot == saved_keyslots[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void secmon_clear_unused_keyslots(void) {
|
||||
/* Clear unused keyslots. */
|
||||
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
|
||||
if (secmon_should_clear_aes_keyslot(i)) {
|
||||
clear_aes_keyslot(i);
|
||||
}
|
||||
clear_aes_keyslot_iv(i);
|
||||
}
|
||||
for (unsigned int i = 0; i < KEYSLOT_RSA_MAX; i++) {
|
||||
clear_rsa_keyslot(i);
|
||||
}
|
||||
}
|
||||
26
exosphere/lp0fw/src/secmon.h
Normal file
26
exosphere/lp0fw/src/secmon.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_SECMON_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_SECMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
void secmon_restore_to_tzram(const uint32_t target_firmware);
|
||||
|
||||
#endif
|
||||
65
exosphere/lp0fw/src/start.s
Normal file
65
exosphere/lp0fw/src/start.s
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.start
|
||||
|
||||
/* Warmboot header. */
|
||||
/* Binary size */
|
||||
.word __total_size__
|
||||
.rept 3
|
||||
.word 0x00000000
|
||||
.endr
|
||||
/* RSA modulus */
|
||||
.rept 0x40
|
||||
.word 0xFFFFFFFF
|
||||
.endr
|
||||
/* Padding */
|
||||
.rept 4
|
||||
.word 0x00000000
|
||||
.endr
|
||||
/* RSA signature */
|
||||
.rept 0x40
|
||||
.word 0xFFFFFFFF
|
||||
.endr
|
||||
/* Padding */
|
||||
.rept 4
|
||||
.word 0x00000000
|
||||
.endr
|
||||
/* Relocation meta */
|
||||
.word __total_size__
|
||||
.word _start
|
||||
.word _start
|
||||
.word __executable_size__
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
b crt0
|
||||
|
||||
.global _metadata
|
||||
_metadata:
|
||||
.ascii "WBT0" /* Magic number */
|
||||
.word 0x00000000 /* Target firmware. */
|
||||
.word 0x00000000 /* Reserved */
|
||||
.word 0x00000000 /* Reserved */
|
||||
|
||||
.global crt0
|
||||
.type crt0, %function
|
||||
crt0:
|
||||
@ setup to call lp0_entry_main
|
||||
ldr sp, =__stack_top__
|
||||
ldr lr, =reboot
|
||||
ldr r0, =_metadata
|
||||
b lp0_entry_main
|
||||
46
exosphere/lp0fw/src/sysreg.h
Normal file
46
exosphere/lp0fw/src/sysreg.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_SYSREG_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_SYSREG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define SYSREG_BASE (0x6000C000)
|
||||
|
||||
#define SB_BASE (SYSREG_BASE + 0x200)
|
||||
|
||||
#define MAKE_SYSREG(n) MAKE_REG32(SYSREG_BASE + n)
|
||||
#define MAKE_SB_REG(n) MAKE_REG32(SB_BASE + n)
|
||||
|
||||
#define AHB_ARBITRATION_DISABLE_0 MAKE_SYSREG(0x004)
|
||||
|
||||
#define SB_CSR_0 MAKE_SB_REG(0x00)
|
||||
#define SB_PIROM_START_0 MAKE_SB_REG(0x04)
|
||||
#define SB_PFCFG_0 MAKE_SB_REG(0x08)
|
||||
#define SB_SECURE_SPAREREG_0_0 MAKE_SB_REG(0x0C)
|
||||
#define SB_SECURE_SPAREREG_1_0 MAKE_SB_REG(0x10)
|
||||
#define SB_SECURE_SPAREREG_2_0 MAKE_SB_REG(0x14)
|
||||
#define SB_SECURE_SPAREREG_3_0 MAKE_SB_REG(0x18)
|
||||
#define SB_SECURE_SPAREREG_4_0 MAKE_SB_REG(0x1C)
|
||||
#define SB_SECURE_SPAREREG_5_0 MAKE_SB_REG(0x20)
|
||||
#define SB_SECURE_SPAREREG_6_0 MAKE_SB_REG(0x24)
|
||||
#define SB_SECURE_SPAREREG_7_0 MAKE_SB_REG(0x28)
|
||||
#define SB_AA64_RESET_LOW_0 MAKE_SB_REG(0x30)
|
||||
#define SB_AA64_RESET_HIGH_0 MAKE_SB_REG(0x34)
|
||||
|
||||
#endif
|
||||
34
exosphere/lp0fw/src/timer.h
Normal file
34
exosphere/lp0fw/src/timer.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_TIMER_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_TIMER_H
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define TIMERUS_CNTR_1US_0 MAKE_REG32(0x60005010)
|
||||
#define TIMERUS_USEC_CFG_0 MAKE_REG32(0x60005014)
|
||||
|
||||
static inline void timer_wait(uint32_t microseconds) {
|
||||
const uint32_t old_time = TIMERUS_CNTR_1US_0;
|
||||
while (TIMERUS_CNTR_1US_0 - old_time <= microseconds) {
|
||||
/* Spin-lock. */
|
||||
}
|
||||
}
|
||||
|
||||
void spinlock_wait(uint32_t count);
|
||||
|
||||
#endif
|
||||
39
exosphere/lp0fw/src/utils.h
Normal file
39
exosphere/lp0fw/src/utils.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_WARMBOOT_BIN_UTILS_H
|
||||
#define EXOSPHERE_WARMBOOT_BIN_UTILS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <atmosphere.h>
|
||||
|
||||
#define BIT(n) (1u << (n))
|
||||
#define BITL(n) (1ull << (n))
|
||||
#define MASK(n) (BIT(n) - 1)
|
||||
#define MASKL(n) (BITL(n) - 1)
|
||||
#define MASK2(a,b) (MASK(a) & ~MASK(b))
|
||||
#define MASK2L(a,b) (MASKL(a) & ~MASKL(b))
|
||||
|
||||
#define MAKE_REG32(a) (*(volatile uint32_t *)(a))
|
||||
|
||||
#define ALIGN(m) __attribute__((aligned(m)))
|
||||
#define PACKED __attribute__((packed))
|
||||
|
||||
#define ALINLINE __attribute__((always_inline))
|
||||
|
||||
#endif
|
||||
18
exosphere/rebootstub/linker.ld
Normal file
18
exosphere/rebootstub/linker.ld
Normal file
@@ -0,0 +1,18 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x4003F000;
|
||||
|
||||
__start__ = ABSOLUTE(.);
|
||||
|
||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||
.bss : ALIGN(8) { __bss_start__ = .; *(.bss* COMMON); . = ALIGN(8); __bss_end__ = .; }
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
__end__ = ABSOLUTE(.);
|
||||
}
|
||||
7
exosphere/rebootstub/linker.specs
Normal file
7
exosphere/rebootstub/linker.specs
Normal file
@@ -0,0 +1,7 @@
|
||||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T %:getenv(TOPDIR /linker.ld) --nmagic --gc-sections
|
||||
|
||||
*startfile:
|
||||
crti%O%s crtbegin%O%s
|
||||
45
exosphere/rebootstub/src/start.s
Normal file
45
exosphere/rebootstub/src/start.s
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.start
|
||||
.align 4
|
||||
.global _start
|
||||
_start:
|
||||
b crt0
|
||||
|
||||
.global crt0
|
||||
.type crt0, %function
|
||||
crt0:
|
||||
@ clear all registers
|
||||
ldr r0, =0x52425430 @ RBT0
|
||||
mov r1, #0x0
|
||||
mov r2, #0x0
|
||||
mov r3, #0x0
|
||||
mov r4, #0x0
|
||||
mov r5, #0x0
|
||||
mov r6, #0x0
|
||||
mov r7, #0x0
|
||||
mov r8, #0x0
|
||||
mov r9, #0x0
|
||||
mov r10, #0x0
|
||||
mov r11, #0x0
|
||||
mov r12, #0x0
|
||||
mov lr, #0x0
|
||||
ldr sp, =0x40010000
|
||||
ldr pc, =0x40010000
|
||||
|
||||
|
||||
|
||||
154
exosphere/sc7fw/Makefile
Normal file
154
exosphere/sc7fw/Makefile
Normal file
@@ -0,0 +1,154 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITARM)/base_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := src
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
||||
|
||||
CFLAGS := \
|
||||
-g \
|
||||
-O2 \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-fomit-frame-pointer \
|
||||
-fno-inline \
|
||||
-std=gnu11 \
|
||||
-Werror \
|
||||
-Wall \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__BPMP__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS :=
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
all : $(OUTPUT).bin
|
||||
|
||||
$(OUTPUT).bin : $(OUTPUT).elf
|
||||
$(OBJCOPY) -S -O binary $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
%.elf: $(OFILES)
|
||||
@echo linking $(notdir $@)
|
||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
@$(NM) -CSn $@ > $(notdir $*.lst)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
7
exosphere/sc7fw/linker.specs
Normal file
7
exosphere/sc7fw/linker.specs
Normal file
@@ -0,0 +1,7 @@
|
||||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T %:getenv(TOPDIR /linker.ld) --nmagic --gc-sections
|
||||
|
||||
*startfile:
|
||||
crti%O%s crtbegin%O%s
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include "lp0.h"
|
||||
#include "sc7.h"
|
||||
#include "emc.h"
|
||||
#include "pmc.h"
|
||||
#include "timer.h"
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include "lp0.h"
|
||||
#include "sc7.h"
|
||||
#include "i2c.h"
|
||||
#include "pmc.h"
|
||||
#include "emc.h"
|
||||
@@ -55,7 +55,7 @@ static void set_pmc_dpd_io_pads(void) {
|
||||
spinlock_wait(32);
|
||||
}
|
||||
|
||||
void lp0_entry_main(void) {
|
||||
void sc7_entry_main(void) {
|
||||
/* Disable the BPMP Cache. */
|
||||
CACHE_CTRL |= 0xC00;
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef EXOSPHERE_BPMPFW_LP0_H
|
||||
#define EXOSPHERE_BPMPFW_LP0_H
|
||||
#ifndef EXOSPHERE_BPMPFW_SC7_H
|
||||
#define EXOSPHERE_BPMPFW_SC7_H
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
void lp0_entry_main(void);
|
||||
void sc7_entry_main(void);
|
||||
|
||||
void reboot(void);
|
||||
|
||||
@@ -25,11 +25,11 @@ _start:
|
||||
.global crt0
|
||||
.type crt0, %function
|
||||
crt0:
|
||||
@ setup to call lp0_entry_main
|
||||
@ setup to call sc7_entry_main
|
||||
msr cpsr_cxsf, #0xD3
|
||||
ldr sp, =__stack_top__
|
||||
ldr lr, =reboot
|
||||
b lp0_entry_main
|
||||
b sc7_entry_main
|
||||
|
||||
|
||||
.global spinlock_wait
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "configitem.h"
|
||||
#include "timers.h"
|
||||
#include "misc.h"
|
||||
#include "uart.h"
|
||||
#include "bpmp.h"
|
||||
#include "sysreg.h"
|
||||
#include "interrupt.h"
|
||||
@@ -46,19 +47,16 @@
|
||||
|
||||
static bool g_has_booted_up = false;
|
||||
|
||||
|
||||
void setup_dram_magic_numbers(void) {
|
||||
/* TODO: Why does these DRAM write occur? */
|
||||
/* These DRAM writes test and set values for the GPU UCODE carveout. */
|
||||
unsigned int target_fw = exosphere_get_target_firmware();
|
||||
if (EXOSPHERE_TARGET_FIRMWARE_400 <= target_fw) {
|
||||
(*(volatile uint32_t *)(0x8005FFFC)) = 0xC0EDBBCC;
|
||||
flush_dcache_range((void *)0x8005FFFC, (void *)0x80060000);
|
||||
if (EXOSPHERE_TARGET_FIRMWARE_600 <= target_fw) {
|
||||
(*(volatile uint32_t *)(0x8005FF00)) = 0x00000083;
|
||||
(*(volatile uint32_t *)(0x8005FF04)) = 0x00000002;
|
||||
(*(volatile uint32_t *)(0x8005FF08)) = 0x00000210;
|
||||
flush_dcache_range((void *)0x8005FF00, (void *)0x8005FF0C);
|
||||
}
|
||||
(*(volatile uint32_t *)(0x8005FFFC)) = 0xC0EDBBCC; /* Access test value. */
|
||||
flush_dcache_range((void *)0x8005FFFC, (void *)0x80060000);
|
||||
if (ATMOSPHERE_TARGET_FIRMWARE_600 <= target_fw) {
|
||||
(*(volatile uint32_t *)(0x8005FF00)) = 0x00000083; /* SKU code. */
|
||||
(*(volatile uint32_t *)(0x8005FF04)) = 0x00000002;
|
||||
(*(volatile uint32_t *)(0x8005FF08)) = 0x00000210; /* Tegra210 code. */
|
||||
flush_dcache_range((void *)0x8005FF00, (void *)0x8005FF0C);
|
||||
}
|
||||
__dsb_sy();
|
||||
}
|
||||
@@ -83,39 +81,39 @@ void bootup_misc_mmio(void) {
|
||||
se_generate_random_key(KEYSLOT_SWITCH_SRKGENKEY, KEYSLOT_SWITCH_RNGKEY);
|
||||
se_generate_srk(KEYSLOT_SWITCH_SRKGENKEY);
|
||||
|
||||
if (!g_has_booted_up && EXOSPHERE_TARGET_FIRMWARE_600 > exosphere_get_target_firmware() && exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (!g_has_booted_up && (ATMOSPHERE_TARGET_FIRMWARE_600 > exosphere_get_target_firmware())) {
|
||||
setup_dram_magic_numbers();
|
||||
}
|
||||
|
||||
/* Todo: What? */
|
||||
MAKE_TIMERS_REG(0x1A4) = 0xF1E0;
|
||||
/* Mark TMR5, TMR6, TMR7, TMR8, WDT0, WDT1, WDT2 and WDT3 as secure. */
|
||||
SHARED_TIMER_SECURE_CFG_0 = 0xF1E0;
|
||||
|
||||
FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 = 4; /* ACTIVE_CLUSTER_LOCK. */
|
||||
FLOW_CTLR_FLOW_DBG_QUAL_0 = 0x10000000; /* Enable FIQ2CCPLEX */
|
||||
FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 = 4; /* ACTIVE_CLUSTER_LOCK. */
|
||||
FLOW_CTLR_FLOW_DBG_QUAL_0 = 0x10000000; /* Enable FIQ2CCPLEX */
|
||||
|
||||
/* Disable Deep Power Down. */
|
||||
APBDEV_PMC_DPD_ENABLE_0 = 0;
|
||||
|
||||
/* Setup MC. */
|
||||
/* TODO: What are these MC reg writes? */
|
||||
MAKE_MC_REG(0x984) = 1;
|
||||
MAKE_MC_REG(0x648) = 0;
|
||||
MAKE_MC_REG(0x64C) = 0;
|
||||
MAKE_MC_REG(0x650) = 1;
|
||||
MAKE_MC_REG(0x670) = 0;
|
||||
MAKE_MC_REG(0x674) = 0;
|
||||
MAKE_MC_REG(0x678) = 1;
|
||||
MAKE_MC_REG(0x9A0) = 0;
|
||||
MAKE_MC_REG(0x9A4) = 0;
|
||||
MAKE_MC_REG(0x9A8) = 0;
|
||||
MAKE_MC_REG(0x9AC) = 1;
|
||||
MC_SECURITY_CFG0_0 = 0;
|
||||
MC_SECURITY_CFG1_0 = 0;
|
||||
MC_SECURITY_CFG3_0 = 3;
|
||||
/* Setup MC carveouts. */
|
||||
MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
|
||||
MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
|
||||
MAKE_MC_REG(MC_VIDEO_PROTECT_BOM) = 0;
|
||||
MAKE_MC_REG(MC_VIDEO_PROTECT_SIZE_MB) = 0;
|
||||
MAKE_MC_REG(MC_VIDEO_PROTECT_REG_CTRL) = 1;
|
||||
MAKE_MC_REG(MC_SEC_CARVEOUT_BOM) = 0;
|
||||
MAKE_MC_REG(MC_SEC_CARVEOUT_SIZE_MB) = 0;
|
||||
MAKE_MC_REG(MC_SEC_CARVEOUT_REG_CTRL) = 1;
|
||||
MAKE_MC_REG(MC_MTS_CARVEOUT_BOM) = 0;
|
||||
MAKE_MC_REG(MC_MTS_CARVEOUT_SIZE_MB) = 0;
|
||||
MAKE_MC_REG(MC_MTS_CARVEOUT_ADR_HI) = 0;
|
||||
MAKE_MC_REG(MC_MTS_CARVEOUT_REG_CTRL) = 1;
|
||||
MAKE_MC_REG(MC_SECURITY_CFG0) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CFG1) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CFG3) = 3;
|
||||
configure_default_carveouts();
|
||||
|
||||
/* Mark registers secure world only. */
|
||||
if (exosphere_get_target_firmware() == EXOSPHERE_TARGET_FIRMWARE_100) {
|
||||
if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_100) {
|
||||
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 = APB_SSER0_SATA_AUX | APB_SSER0_DTV | APB_SSER0_QSPI | APB_SSER0_SATA | APB_SSER0_LA;
|
||||
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 = APB_SSER1_SPI1 | APB_SSER1_SPI2 | APB_SSER1_SPI3 | APB_SSER1_SPI5 | APB_SSER1_SPI6 | APB_SSER1_I2C4 | APB_SSER1_I2C6;
|
||||
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = 1 << 4 | 1 << 5 | APB_SSER2_DDS; /* bits 4 and 5 are not labeled in 21.1.7.3 */
|
||||
@@ -132,7 +130,7 @@ void bootup_misc_mmio(void) {
|
||||
/* Also mark I2C4 secure only, */
|
||||
sec_disable_1 |= APB_SSER1_I2C4;
|
||||
}
|
||||
if (hardware_type != 0 && exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (hardware_type != 0 && exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
/* Starting on 4.x on non-dev units, mark UARTB, UARTC, SPI4, I2C3 secure only. */
|
||||
sec_disable_1 |= APB_SSER1_UART_B | APB_SSER1_UART_C | APB_SSER1_SPI4 | APB_SSER1_I2C3;
|
||||
/* Starting on 4.x on non-dev units, mark SDMMC1 secure only. */
|
||||
@@ -142,22 +140,22 @@ void bootup_misc_mmio(void) {
|
||||
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = sec_disable_2;
|
||||
}
|
||||
|
||||
/* reset Translation Enable Registers */
|
||||
MC_SMMU_TRANSLATION_ENABLE_0_0 = 0xFFFFFFFF;
|
||||
MC_SMMU_TRANSLATION_ENABLE_1_0 = 0xFFFFFFFF;
|
||||
MC_SMMU_TRANSLATION_ENABLE_2_0 = 0xFFFFFFFF;
|
||||
MC_SMMU_TRANSLATION_ENABLE_3_0 = 0xFFFFFFFF;
|
||||
MC_SMMU_TRANSLATION_ENABLE_4_0 = 0xFFFFFFFF;
|
||||
/* 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;
|
||||
|
||||
/* TODO: What are these MC reg writes? */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
MAKE_MC_REG(0x038) = 0xE;
|
||||
} else {
|
||||
MAKE_MC_REG(0x038) = 0x0;
|
||||
}
|
||||
MAKE_MC_REG(0x03C) = 0;
|
||||
|
||||
/* MISC registers*/
|
||||
/* MISC registers. */
|
||||
MAKE_MC_REG(0x9E0) = 0;
|
||||
MAKE_MC_REG(0x9E4) = 0;
|
||||
MAKE_MC_REG(0x9E8) = 0;
|
||||
@@ -165,23 +163,23 @@ void bootup_misc_mmio(void) {
|
||||
MAKE_MC_REG(0x9F0) = 0;
|
||||
MAKE_MC_REG(0x9F4) = 0;
|
||||
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
MC_SMMU_PTB_ASID_0 = 0;
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
MAKE_MC_REG(MC_SMMU_PTB_ASID) = 0;
|
||||
}
|
||||
MC_SMMU_PTB_DATA_0 = 0;
|
||||
MC_SMMU_TLB_CONFIG_0 = 0x30000030;
|
||||
MC_SMMU_PTC_CONFIG_0 = 0x2800003F;
|
||||
(void)MC_SMMU_TLB_CONFIG_0;
|
||||
MC_SMMU_PTC_FLUSH_0 = 0;
|
||||
(void)MC_SMMU_TLB_CONFIG_0;
|
||||
MC_SMMU_TLB_FLUSH_0 = 0;
|
||||
(void)MC_SMMU_TLB_CONFIG_0;
|
||||
MC_SMMU_CONFIG_0 = 1; /* enable SMMU */
|
||||
(void)MC_SMMU_TLB_CONFIG_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;
|
||||
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
||||
MAKE_MC_REG(MC_SMMU_PTC_FLUSH) = 0;
|
||||
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
||||
MAKE_MC_REG(MC_SMMU_TLB_FLUSH) = 0;
|
||||
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
||||
MAKE_MC_REG(MC_SMMU_CONFIG) = 1; /* Enable SMMU. */
|
||||
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
||||
|
||||
/* Clear RESET Vector, setup CPU Secure Boot RESET Vectors. */
|
||||
uint32_t reset_vec;
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
reset_vec = TZRAM_GET_SEGMENT_5X_PA(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN);
|
||||
} else {
|
||||
reset_vec = TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN);
|
||||
@@ -200,14 +198,14 @@ void bootup_misc_mmio(void) {
|
||||
|
||||
/* Setup FIQs. */
|
||||
|
||||
|
||||
/* And assign "se_operation_completed" to Interrupt 0x5A. */
|
||||
intr_set_priority(INTERRUPT_ID_SECURITY_ENGINE, 0);
|
||||
intr_set_group(INTERRUPT_ID_SECURITY_ENGINE, 0);
|
||||
intr_set_enabled(INTERRUPT_ID_SECURITY_ENGINE, 1);
|
||||
intr_set_cpu_mask(INTERRUPT_ID_SECURITY_ENGINE, 8);
|
||||
intr_set_edge_level(INTERRUPT_ID_SECURITY_ENGINE, 0);
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
intr_set_priority(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
|
||||
intr_set_group(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
|
||||
intr_set_enabled(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 1);
|
||||
@@ -216,31 +214,37 @@ void bootup_misc_mmio(void) {
|
||||
}
|
||||
|
||||
if (!g_has_booted_up) {
|
||||
/* N doesn't do this, but we should for compatibility. */
|
||||
uart_select(UART_A);
|
||||
clkrst_reboot(CARDEVICE_UARTA);
|
||||
uart_init(UART_A, 115200);
|
||||
|
||||
intr_register_handler(INTERRUPT_ID_SECURITY_ENGINE, se_operation_completed);
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
intr_register_handler(INTERRUPT_ID_ACTIVITY_MONITOR_4X, actmon_interrupt_handler);
|
||||
}
|
||||
for (unsigned int core = 1; core < NUM_CPU_CORES; core++) {
|
||||
set_core_is_active(core, false);
|
||||
}
|
||||
g_has_booted_up = true;
|
||||
} else if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
/* TODO: What are these MC reg writes? */
|
||||
MAKE_MC_REG(0x65C) = 0xFFFFF000;
|
||||
MAKE_MC_REG(0x660) = 0;
|
||||
MAKE_MC_REG(0x964) |= 1;
|
||||
} else if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
/* Disable AHB redirect. */
|
||||
MAKE_MC_REG(MC_IRAM_BOM) = 0xFFFFF000;
|
||||
MAKE_MC_REG(MC_IRAM_TOM) = 0;
|
||||
MAKE_MC_REG(MC_IRAM_REG_CTRL) |= 1;
|
||||
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 &= 0xFFF7FFFF;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_4x_mmio(void) {
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_600) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
|
||||
configure_gpu_ucode_carveout();
|
||||
}
|
||||
/* TODO: What are these MC reg writes? */
|
||||
MAKE_MC_REG(0x65C) = 0xFFFFF000;
|
||||
MAKE_MC_REG(0x660) = 0;
|
||||
MAKE_MC_REG(0x964) |= 1;
|
||||
|
||||
/* Disable AHB redirect. */
|
||||
MAKE_MC_REG(MC_IRAM_BOM) = 0xFFFFF000;
|
||||
MAKE_MC_REG(MC_IRAM_TOM) = 0;
|
||||
MAKE_MC_REG(MC_IRAM_REG_CTRL) |= 1;
|
||||
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 &= 0xFFF7FFFF;
|
||||
|
||||
/* TODO: What are these PMC scratch writes? */
|
||||
@@ -275,16 +279,16 @@ void setup_4x_mmio(void) {
|
||||
AHB_ARBITRATION_DISABLE_0 |= 2;
|
||||
|
||||
/* Set SMMU for BPMP/APB-DMA to point to TZRAM. */
|
||||
MC_SMMU_PTB_ASID_0 = 1;
|
||||
(void)MC_SMMU_TLB_CONFIG_0;
|
||||
MC_SMMU_PTB_DATA_0 = 0x70012;
|
||||
MC_SMMU_AVPC_ASID_0 = 0x80000001;
|
||||
MC_SMMU_PPCS1_ASID_0 = 0x80000001;
|
||||
(void)MC_SMMU_TLB_CONFIG_0;
|
||||
MC_SMMU_PTC_FLUSH_0 = 0;
|
||||
(void)MC_SMMU_TLB_CONFIG_0;
|
||||
MC_SMMU_TLB_FLUSH_0 = 0;
|
||||
(void)MC_SMMU_TLB_CONFIG_0;
|
||||
MAKE_MC_REG(MC_SMMU_PTB_ASID) = 1;
|
||||
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
||||
MAKE_MC_REG(MC_SMMU_PTB_DATA) = 0x70012;
|
||||
MAKE_MC_REG(MC_SMMU_AVPC_ASID) = 0x80000001;
|
||||
MAKE_MC_REG(MC_SMMU_PPCS1_ASID) = 0x80000001;
|
||||
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
||||
MAKE_MC_REG(MC_SMMU_PTC_FLUSH) = 0;
|
||||
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
||||
MAKE_MC_REG(MC_SMMU_TLB_FLUSH) = 0;
|
||||
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
||||
|
||||
/* Wait for the BPMP to halt. */
|
||||
while ((FLOW_CTLR_HALT_COP_EVENTS_0 >> 29) != 2) {
|
||||
@@ -321,7 +325,7 @@ void setup_current_core_state(void) {
|
||||
|
||||
__isb();
|
||||
|
||||
SET_SYSREG(cntfrq_el0, MAKE_SYSCTR0_REG(0x20)); /* TODO: Reg name. */
|
||||
SET_SYSREG(cntfrq_el0, SYSCTR0_CNTFID0_0);
|
||||
SET_SYSREG(cnthctl_el2, 3ull);
|
||||
|
||||
__isb();
|
||||
@@ -356,9 +360,9 @@ void identity_unmap_iram_cd_tzram(void) {
|
||||
}
|
||||
|
||||
void secure_additional_devices(void) {
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_200) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
|
||||
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 |= APB_SSER0_PMC; /* make PMC secure-only (2.x+) */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 |= APB_SSER1_MC0 | APB_SSER1_MC1 | APB_SSER1_MCB; /* make MC0, MC1, MCB secure-only (4.x+) */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ static void tzram_map_all_segments(uintptr_t *mmu_l3_tbl, unsigned int target_fi
|
||||
static const uintptr_t offs_5x[] = { TUPLE_FOLD_LEFT_0(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZ5XS, COMMA) };
|
||||
|
||||
for(size_t i = 0, offset = 0; i < TZRAM_SEGMENT_ID_MAX; i++) {
|
||||
uintptr_t off = (target_firmware < EXOSPHERE_TARGET_FIRMWARE_500) ? offs[i] : offs_5x[i];
|
||||
uintptr_t off = (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_500) ? offs[i] : offs_5x[i];
|
||||
tzram_map_segment(mmu_l3_tbl, TZRAM_SEGMENT_BASE + offset, 0x7C010000ull + off, sizes[i], is_executable[i]);
|
||||
offset += increments[i];
|
||||
}
|
||||
@@ -101,7 +101,7 @@ static void configure_ttbls(unsigned int target_firmware) {
|
||||
uintptr_t *mmu_l1_tbl;
|
||||
uintptr_t *mmu_l2_tbl;
|
||||
uintptr_t *mmu_l3_tbl;
|
||||
if (target_firmware < EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
mmu_l1_tbl = (uintptr_t *)(TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
|
||||
mmu_l2_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE);
|
||||
mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
|
||||
@@ -151,7 +151,7 @@ uintptr_t get_coldboot_crt0_temp_stack_address(void) {
|
||||
}
|
||||
|
||||
uintptr_t get_coldboot_crt0_stack_address(void) {
|
||||
if (exosphere_get_target_firmware_for_init() < EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware_for_init() < ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
return TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
|
||||
} else {
|
||||
return TZRAM_GET_SEGMENT_5X_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
|
||||
@@ -193,7 +193,7 @@ void coldboot_init(coldboot_crt0_reloc_list_t *reloc_list, uintptr_t start_cold)
|
||||
init_dma_controllers(g_exosphere_target_firmware_for_init);
|
||||
|
||||
configure_ttbls(g_exosphere_target_firmware_for_init);
|
||||
if (g_exosphere_target_firmware_for_init < EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
set_memory_registers_enable_mmu_1x_ttbr0();
|
||||
} else {
|
||||
set_memory_registers_enable_mmu_5x_ttbr0();
|
||||
|
||||
@@ -26,21 +26,70 @@
|
||||
#include "utils.h"
|
||||
#include "masterkey.h"
|
||||
#include "exocfg.h"
|
||||
#include "smc_ams.h"
|
||||
#include "arm.h"
|
||||
|
||||
#define u8 uint8_t
|
||||
#define u32 uint32_t
|
||||
#include "rebootstub_bin.h"
|
||||
#undef u8
|
||||
#undef u32
|
||||
|
||||
static bool g_battery_profile = false;
|
||||
static bool g_debugmode_override_user = false, g_debugmode_override_priv = false;
|
||||
|
||||
uint32_t configitem_set(ConfigItem item, uint64_t value) {
|
||||
if (item != CONFIGITEM_BATTERYPROFILE) {
|
||||
return 2;
|
||||
uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
|
||||
switch (item) {
|
||||
case CONFIGITEM_BATTERYPROFILE:
|
||||
g_battery_profile = (value != 0);
|
||||
break;
|
||||
case CONFIGITEM_NEEDS_REBOOT:
|
||||
/* Force a reboot, if requested. */
|
||||
{
|
||||
switch (value) {
|
||||
case REBOOT_KIND_NO_REBOOT:
|
||||
return 0;
|
||||
case REBOOT_KIND_TO_RCM:
|
||||
/* Set reboot kind = rcm. */
|
||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x450ull) = 0x2;
|
||||
break;
|
||||
case REBOOT_KIND_TO_WB_PAYLOAD:
|
||||
/* Set reboot kind = warmboot. */
|
||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x450ull) = 0x1;
|
||||
/* Patch SDRAM init to perform an SVC immediately after second write */
|
||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x634ull) = 0x2E38DFFF;
|
||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x638ull) = 0x6001DC28;
|
||||
/* Set SVC handler to jump to reboot stub in IRAM. */
|
||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x520ull) = 0x4003F000;
|
||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x53Cull) = 0x6000F208;
|
||||
|
||||
/* Copy reboot stub payload. */
|
||||
ams_map_irampage(0x4003F000);
|
||||
for (unsigned int i = 0; i < rebootstub_bin_size; i += 4) {
|
||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE) + i) = read32le(rebootstub_bin, i);
|
||||
}
|
||||
ams_unmap_irampage();
|
||||
|
||||
/* Ensure stub is flushed. */
|
||||
flush_dcache_all();
|
||||
break;
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10;
|
||||
while (1) { }
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
|
||||
g_battery_profile = (value != 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool configitem_is_recovery_boot(void) {
|
||||
uint64_t is_recovery_boot;
|
||||
if (configitem_get(CONFIGITEM_ISRECOVERYBOOT, &is_recovery_boot) != 0) {
|
||||
if (configitem_get(true, CONFIGITEM_ISRECOVERYBOOT, &is_recovery_boot) != 0) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
@@ -49,7 +98,7 @@ bool configitem_is_recovery_boot(void) {
|
||||
|
||||
bool configitem_is_retail(void) {
|
||||
uint64_t is_retail;
|
||||
if (configitem_get(CONFIGITEM_ISRETAIL, &is_retail) != 0) {
|
||||
if (configitem_get(true, CONFIGITEM_ISRETAIL, &is_retail) != 0) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
@@ -60,15 +109,29 @@ bool configitem_should_profile_battery(void) {
|
||||
return g_battery_profile;
|
||||
}
|
||||
|
||||
bool configitem_is_debugmode_priv(void) {
|
||||
uint64_t debugmode = 0;
|
||||
if (configitem_get(true, CONFIGITEM_ISDEBUGMODE, &debugmode) != 0) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
return debugmode != 0;
|
||||
}
|
||||
|
||||
uint64_t configitem_get_hardware_type(void) {
|
||||
uint64_t hardware_type;
|
||||
if (configitem_get(CONFIGITEM_HARDWARETYPE, &hardware_type) != 0) {
|
||||
if (configitem_get(true, CONFIGITEM_HARDWARETYPE, &hardware_type) != 0) {
|
||||
generic_panic();
|
||||
}
|
||||
return hardware_type;
|
||||
}
|
||||
|
||||
uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
|
||||
void configitem_set_debugmode_override(bool user, bool priv) {
|
||||
g_debugmode_override_user = user;
|
||||
g_debugmode_override_priv = priv;
|
||||
}
|
||||
|
||||
uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue) {
|
||||
uint32_t result = 0;
|
||||
switch (item) {
|
||||
case CONFIGITEM_DISABLEPROGRAMVERIFICATION:
|
||||
@@ -99,7 +162,7 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
|
||||
break;
|
||||
case CONFIGITEM_BOOTREASON:
|
||||
/* For some reason, Nintendo removed it on 4.0 */
|
||||
if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
*p_outvalue = bootconfig_get_boot_reason();
|
||||
} else {
|
||||
result = 2;
|
||||
@@ -109,7 +172,11 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
|
||||
*p_outvalue = bootconfig_get_memory_arrangement();
|
||||
break;
|
||||
case CONFIGITEM_ISDEBUGMODE:
|
||||
*p_outvalue = (int)(bootconfig_is_debug_mode());
|
||||
if ((privileged && g_debugmode_override_priv) || (!privileged && g_debugmode_override_user)) {
|
||||
*p_outvalue = 1;
|
||||
} else {
|
||||
*p_outvalue = (int)(bootconfig_is_debug_mode());
|
||||
}
|
||||
break;
|
||||
case CONFIGITEM_KERNELMEMORYCONFIGURATION:
|
||||
*p_outvalue = bootconfig_get_kernel_memory_configuration();
|
||||
@@ -119,7 +186,7 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
|
||||
break;
|
||||
case CONFIGITEM_ISQUESTUNIT:
|
||||
/* Added on 3.0, used to determine whether console is a kiosk unit. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_300) {
|
||||
*p_outvalue = (fuse_get_reserved_odm(4) >> 10) & 1;
|
||||
} else {
|
||||
result = 2;
|
||||
@@ -127,7 +194,7 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
|
||||
break;
|
||||
case CONFIGITEM_NEWHARDWARETYPE_5X:
|
||||
/* Added in 5.x, currently hardcoded to 0. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
*p_outvalue = 0;
|
||||
} else {
|
||||
result = 2;
|
||||
@@ -135,7 +202,7 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
|
||||
break;
|
||||
case CONFIGITEM_NEWKEYGENERATION_5X:
|
||||
/* Added in 5.x. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
*p_outvalue = fuse_get_5x_key_generation();
|
||||
} else {
|
||||
result = 2;
|
||||
@@ -143,7 +210,7 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
|
||||
break;
|
||||
case CONFIGITEM_PACKAGE2HASH_5X:
|
||||
/* Added in 5.x. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500 && bootconfig_is_recovery_boot()) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500 && bootconfig_is_recovery_boot()) {
|
||||
bootconfig_get_package2_hash_for_recovery(p_outvalue);
|
||||
} else {
|
||||
result = 2;
|
||||
@@ -157,6 +224,10 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
|
||||
((uint64_t)(exosphere_get_target_firmware() & 0xFF) << 8ull) |
|
||||
((uint64_t)(mkey_get_revision() & 0xFF) << 0ull);
|
||||
break;
|
||||
case CONFIGITEM_NEEDS_REBOOT:
|
||||
/* UNOFFICIAL: The fact that we are executing means we aren't in the process of rebooting. */
|
||||
*p_outvalue = 0;
|
||||
break;
|
||||
default:
|
||||
result = 2;
|
||||
break;
|
||||
|
||||
@@ -40,15 +40,23 @@ typedef enum {
|
||||
CONFIGITEM_PACKAGE2HASH_5X = 17,
|
||||
|
||||
/* These are unofficial, for usage by Exosphere. */
|
||||
CONFIGITEM_EXOSPHERE_VERSION = 65000
|
||||
CONFIGITEM_EXOSPHERE_VERSION = 65000,
|
||||
CONFIGITEM_NEEDS_REBOOT = 65001,
|
||||
} ConfigItem;
|
||||
|
||||
uint32_t configitem_set(ConfigItem item, uint64_t value);
|
||||
uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue);
|
||||
#define REBOOT_KIND_NO_REBOOT 0
|
||||
#define REBOOT_KIND_TO_RCM 1
|
||||
#define REBOOT_KIND_TO_WB_PAYLOAD 2
|
||||
|
||||
uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value);
|
||||
uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue);
|
||||
|
||||
bool configitem_is_recovery_boot(void);
|
||||
bool configitem_is_retail(void);
|
||||
bool configitem_should_profile_battery(void);
|
||||
bool configitem_is_debugmode_priv(void);
|
||||
|
||||
void configitem_set_debugmode_override(bool user, bool priv);
|
||||
|
||||
uint64_t configitem_get_hardware_type(void);
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ uint32_t cpu_on(uint32_t core, uintptr_t entrypoint_addr, uint64_t argument) {
|
||||
static const uint32_t status_masks[NUM_CPU_CORES] = {0x4000, 0x200, 0x400, 0x800};
|
||||
static const uint32_t toggle_vals[NUM_CPU_CORES] = {0xE, 0x9, 0xA, 0xB};
|
||||
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
/* Reset the core */
|
||||
CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET_0 = (1 << (core + 0x10)) | (1 << core);
|
||||
}
|
||||
@@ -133,7 +133,7 @@ uint32_t cpu_on(uint32_t core, uintptr_t entrypoint_addr, uint64_t argument) {
|
||||
}
|
||||
|
||||
CPU_ON_SUCCESS:
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
/* Start the core */
|
||||
CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR_0 = (1 << (core + 0x10)) | (1 << core);
|
||||
}
|
||||
|
||||
@@ -27,9 +27,12 @@
|
||||
/* TODO: Should this be at a non-static location? */
|
||||
#define MAILBOX_EXOSPHERE_CONFIG (*((volatile exosphere_config_t *)(MAILBOX_BASE + 0xE40ULL)))
|
||||
|
||||
static exosphere_config_t g_exosphere_cfg = {MAGIC_EXOSPHERE_BOOTCONFIG, EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG};
|
||||
static exosphere_config_t g_exosphere_cfg = {MAGIC_EXOSPHERE_BOOTCONFIG, ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG, EXOSPHERE_FLAGS_DEFAULT};
|
||||
static bool g_has_loaded_config = false;
|
||||
|
||||
#define EXOSPHERE_CHECK_FLAG(flag) ((g_exosphere_cfg.flags & flag) != 0)
|
||||
|
||||
|
||||
/* Read config out of IRAM, return target firmware version. */
|
||||
unsigned int exosphere_load_config(void) {
|
||||
if (g_has_loaded_config) {
|
||||
@@ -37,8 +40,13 @@ unsigned int exosphere_load_config(void) {
|
||||
}
|
||||
g_has_loaded_config = true;
|
||||
|
||||
if (MAILBOX_EXOSPHERE_CONFIG.magic == MAGIC_EXOSPHERE_BOOTCONFIG) {
|
||||
const unsigned int magic = MAILBOX_EXOSPHERE_CONFIG.magic;
|
||||
|
||||
if (magic == MAGIC_EXOSPHERE_BOOTCONFIG) {
|
||||
g_exosphere_cfg = MAILBOX_EXOSPHERE_CONFIG;
|
||||
} else if (magic == MAGIC_EXOSPHERE_BOOTCONFIG_0) {
|
||||
g_exosphere_cfg = MAILBOX_EXOSPHERE_CONFIG;
|
||||
g_exosphere_cfg.flags = EXOSPHERE_FLAGS_DEFAULT;
|
||||
}
|
||||
|
||||
return g_exosphere_cfg.target_firmware;
|
||||
@@ -50,4 +58,28 @@ unsigned int exosphere_get_target_firmware(void) {
|
||||
}
|
||||
|
||||
return g_exosphere_cfg.target_firmware;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int exosphere_should_perform_620_keygen(void) {
|
||||
if (!g_has_loaded_config) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
return g_exosphere_cfg.target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_620 && EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_PERFORM_620_KEYGEN);
|
||||
}
|
||||
|
||||
unsigned int exosphere_should_override_debugmode_priv(void) {
|
||||
if (!g_has_loaded_config) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV);
|
||||
}
|
||||
|
||||
unsigned int exosphere_should_override_debugmode_user(void) {
|
||||
if (!g_has_loaded_config) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_IS_DEBUGMODE_USER);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define EXOSPHERE_EXOSPHERE_CONFIG_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <atmosphere.h>
|
||||
#include "utils.h"
|
||||
|
||||
#include "memory_map.h"
|
||||
@@ -25,17 +26,10 @@
|
||||
/* This serves to set configuration for *exosphere itself*, separate from the SecMon Exosphere mimics. */
|
||||
|
||||
/* "XBC0" */
|
||||
#define MAGIC_EXOSPHERE_BOOTCONFIG (0x30434258)
|
||||
#define MAGIC_EXOSPHERE_BOOTCONFIG_0 (0x30434258)
|
||||
/* "XBC1" */
|
||||
#define MAGIC_EXOSPHERE_BOOTCONFIG (0x31434258)
|
||||
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_100 1
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_200 2
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_300 3
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_400 4
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_500 5
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_600 6
|
||||
|
||||
/* TODO: What should this be, for release? */
|
||||
#define EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG EXOSPHERE_TARGET_FIRMWARE_600
|
||||
#define EXOSPHERE_LOOSEN_PACKAGE2_RESTRICTIONS_FOR_DEBUG 1
|
||||
|
||||
#define MAILBOX_BASE_PHYS (MMIO_GET_DEVICE_PA(MMIO_DEVID_NXBOOTLOADER_MAILBOX))
|
||||
@@ -43,17 +37,30 @@
|
||||
/* TODO: Should this be at a non-static location? */
|
||||
#define MAILBOX_EXOSPHERE_CONFIG_PHYS (*((volatile exosphere_config_t *)(MAILBOX_BASE_PHYS + 0xE40ULL)))
|
||||
|
||||
#define EXOSPHERE_FLAGS_DEFAULT 0x00000000
|
||||
#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u)
|
||||
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
|
||||
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
|
||||
|
||||
typedef struct {
|
||||
unsigned int magic;
|
||||
unsigned int target_firmware;
|
||||
unsigned int flags;
|
||||
} exosphere_config_t;
|
||||
|
||||
unsigned int exosphere_load_config(void);
|
||||
unsigned int exosphere_get_target_firmware(void);
|
||||
unsigned int exosphere_should_perform_620_keygen(void);
|
||||
unsigned int exosphere_should_override_debugmode_priv(void);
|
||||
unsigned int exosphere_should_override_debugmode_user(void);
|
||||
|
||||
static inline unsigned int exosphere_get_target_firmware_for_init(void) {
|
||||
return MAILBOX_EXOSPHERE_CONFIG_PHYS.magic == MAGIC_EXOSPHERE_BOOTCONFIG ? MAILBOX_EXOSPHERE_CONFIG_PHYS.target_firmware : EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG;
|
||||
const unsigned int magic = MAILBOX_EXOSPHERE_CONFIG_PHYS.magic;
|
||||
if (magic == MAGIC_EXOSPHERE_BOOTCONFIG || magic == MAGIC_EXOSPHERE_BOOTCONFIG_0) {
|
||||
return MAILBOX_EXOSPHERE_CONFIG_PHYS.target_firmware;
|
||||
} else {
|
||||
return ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -207,7 +207,7 @@ uint32_t fuse_get_hardware_type(void) {
|
||||
/* This function is very different between 4.x and < 4.x */
|
||||
uint32_t hardware_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 2) & 1);
|
||||
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
static const uint32_t types[] = {0,1,4,3};
|
||||
|
||||
hardware_type |= (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 14) & 0x3C;
|
||||
|
||||
@@ -40,6 +40,7 @@ static const uint8_t mkey_vectors_dev[MASTERKEY_REVISION_MAX][0x10] =
|
||||
{0x2C, 0xCA, 0x9C, 0x31, 0x1E, 0x07, 0xB0, 0x02, 0x97, 0x0A, 0xD8, 0x03, 0xA2, 0x76, 0x3F, 0xA3}, /* Master key 02 encrypted with Master key 03. */
|
||||
{0x9B, 0x84, 0x76, 0x14, 0x72, 0x94, 0x52, 0xCB, 0x54, 0x92, 0x9B, 0xC4, 0x8C, 0x5B, 0x0F, 0xBA}, /* Master key 03 encrypted with Master key 04. */
|
||||
{0x78, 0xD5, 0xF1, 0x20, 0x3D, 0x16, 0xE9, 0x30, 0x32, 0x27, 0x34, 0x6F, 0xCF, 0xE0, 0x27, 0xDC}, /* Master key 04 encrypted with Master key 05. */
|
||||
{0x6F, 0xD2, 0x84, 0x1D, 0x05, 0xEC, 0x40, 0x94, 0x5F, 0x18, 0xB3, 0x81, 0x09, 0x98, 0x8D, 0x4E}, /* Master key 05 encrypted with Master key 06. */
|
||||
};
|
||||
|
||||
/* Retail unit keys. */
|
||||
@@ -51,6 +52,7 @@ static const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] =
|
||||
{0x0A, 0x0D, 0xDF, 0x34, 0x22, 0x06, 0x6C, 0xA4, 0xE6, 0xB1, 0xEC, 0x71, 0x85, 0xCA, 0x4E, 0x07}, /* Master key 02 encrypted with Master key 03. */
|
||||
{0x6E, 0x7D, 0x2D, 0xC3, 0x0F, 0x59, 0xC8, 0xFA, 0x87, 0xA8, 0x2E, 0xD5, 0x89, 0x5E, 0xF3, 0xE9}, /* Master key 03 encrypted with Master key 04. */
|
||||
{0xEB, 0xF5, 0x6F, 0x83, 0x61, 0x9E, 0xF8, 0xFA, 0xE0, 0x87, 0xD7, 0xA1, 0x4E, 0x25, 0x36, 0xEE}, /* Master key 04 encrypted with Master key 05. */
|
||||
{0x1E, 0x1E, 0x22, 0xC0, 0x5A, 0x33, 0x3C, 0xB9, 0x0B, 0xA9, 0x03, 0x04, 0xBA, 0xDB, 0x07, 0x57}, /* Master key 05 encrypted with Master key 06. */
|
||||
};
|
||||
|
||||
bool check_mkey_revision(unsigned int revision, bool is_retail) {
|
||||
@@ -123,7 +125,7 @@ unsigned int mkey_get_keyslot(unsigned int revision) {
|
||||
|
||||
|
||||
void set_old_devkey(unsigned int revision, const uint8_t *key) {
|
||||
if (revision < MASTERKEY_REVISION_400_410 || MASTERKEY_REVISION_600_CURRENT <= revision) {
|
||||
if (revision < MASTERKEY_REVISION_400_410 || MASTERKEY_REVISION_MAX <= revision) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
@@ -140,7 +142,7 @@ unsigned int devkey_get_keyslot(unsigned int revision) {
|
||||
}
|
||||
|
||||
if (revision >= 1) {
|
||||
if (revision == MASTERKEY_REVISION_600_CURRENT) {
|
||||
if (revision == MASTERKEY_REVISION_MAX) {
|
||||
return KEYSLOT_SWITCH_DEVICEKEY;
|
||||
} else {
|
||||
/* Load into a temp keyslot. */
|
||||
|
||||
@@ -19,15 +19,16 @@
|
||||
|
||||
/* This is glue code to enable master key support across versions. */
|
||||
|
||||
/* TODO: Update to 0x7 on release of new master key. */
|
||||
#define MASTERKEY_REVISION_MAX 0x6
|
||||
/* TODO: Update to 0x8 on release of new master key. */
|
||||
#define MASTERKEY_REVISION_MAX 0x7
|
||||
|
||||
#define MASTERKEY_REVISION_100_230 0x00
|
||||
#define MASTERKEY_REVISION_300 0x01
|
||||
#define MASTERKEY_REVISION_301_302 0x02
|
||||
#define MASTERKEY_REVISION_400_410 0x03
|
||||
#define MASTERKEY_REVISION_500_510 0x04
|
||||
#define MASTERKEY_REVISION_600_CURRENT 0x05
|
||||
#define MASTERKEY_REVISION_600_610 0x05
|
||||
#define MASTERKEY_REVISION_620_CURRENT 0x06
|
||||
|
||||
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)
|
||||
|
||||
|
||||
@@ -39,23 +39,23 @@ volatile security_carveout_t *get_carveout_by_id(unsigned int carveout) {
|
||||
}
|
||||
|
||||
void configure_gpu_ucode_carveout(void) {
|
||||
/* Starting in 6.0.0, Carveout 2 is configured later on. */
|
||||
/* Starting in 6.0.0, Carveout 2 is configured later on and adds read permission to TSEC. */
|
||||
/* This is a helper function to make this easier... */
|
||||
volatile security_carveout_t *carveout = get_carveout_by_id(2);
|
||||
carveout->paddr_low = 0x80020000;
|
||||
carveout->paddr_high = 0;
|
||||
carveout->size_big_pages = 2; /* 0x40000 */
|
||||
carveout->flags_0 = 0;
|
||||
carveout->flags_1 = 0;
|
||||
carveout->flags_2 = 0x3000000;
|
||||
carveout->flags_3 = 0;
|
||||
carveout->flags_4 = 0x300;
|
||||
carveout->flags_5 = 0;
|
||||
carveout->flags_6 = 0;
|
||||
carveout->flags_7 = 0;
|
||||
carveout->flags_8 = 0;
|
||||
carveout->flags_9 = 0;
|
||||
carveout->allowed_clients = 0x440167E;
|
||||
carveout->size_big_pages = 2; /* 0x40000 */
|
||||
carveout->client_access_0 = 0;
|
||||
carveout->client_access_1 = 0;
|
||||
carveout->client_access_2 = (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) ? (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR) | BIT(CSR_TSECSRD)) : (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
|
||||
carveout->client_access_3 = 0;
|
||||
carveout->client_access_4 = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
|
||||
carveout->client_force_internal_access_0 = 0;
|
||||
carveout->client_force_internal_access_1 = 0;
|
||||
carveout->client_force_internal_access_2 = 0;
|
||||
carveout->client_force_internal_access_3 = 0;
|
||||
carveout->client_force_internal_access_4 = 0;
|
||||
carveout->config = 0x440167E;
|
||||
}
|
||||
|
||||
void configure_default_carveouts(void) {
|
||||
@@ -64,20 +64,20 @@ void configure_default_carveouts(void) {
|
||||
carveout->paddr_low = 0;
|
||||
carveout->paddr_high = 0;
|
||||
carveout->size_big_pages = 0;
|
||||
carveout->flags_0 = 0;
|
||||
carveout->flags_1 = 0;
|
||||
carveout->flags_2 = 0;
|
||||
carveout->flags_3 = 0;
|
||||
carveout->flags_4 = 0;
|
||||
carveout->flags_5 = 0;
|
||||
carveout->flags_6 = 0;
|
||||
carveout->flags_7 = 0;
|
||||
carveout->flags_8 = 0;
|
||||
carveout->flags_9 = 0;
|
||||
carveout->allowed_clients = 0x04000006;
|
||||
carveout->client_access_0 = 0;
|
||||
carveout->client_access_1 = 0;
|
||||
carveout->client_access_2 = 0;
|
||||
carveout->client_access_3 = 0;
|
||||
carveout->client_access_4 = 0;
|
||||
carveout->client_force_internal_access_0 = 0;
|
||||
carveout->client_force_internal_access_1 = 0;
|
||||
carveout->client_force_internal_access_2 = 0;
|
||||
carveout->client_force_internal_access_3 = 0;
|
||||
carveout->client_force_internal_access_4 = 0;
|
||||
carveout->config = 0x4000006;
|
||||
|
||||
/* Configure Carveout 2 (GPU UCODE) */
|
||||
if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_600) {
|
||||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_600) {
|
||||
configure_gpu_ucode_carveout();
|
||||
}
|
||||
|
||||
@@ -86,20 +86,20 @@ void configure_default_carveouts(void) {
|
||||
carveout->paddr_low = 0;
|
||||
carveout->paddr_high = 0;
|
||||
carveout->size_big_pages = 0;
|
||||
carveout->flags_0 = 0;
|
||||
carveout->flags_1 = 0;
|
||||
carveout->flags_2 = 0x3000000;
|
||||
carveout->flags_3 = 0;
|
||||
carveout->flags_4 = 0x300;
|
||||
carveout->flags_5 = 0;
|
||||
carveout->flags_6 = 0;
|
||||
carveout->flags_7 = 0;
|
||||
carveout->flags_8 = 0;
|
||||
carveout->flags_9 = 0;
|
||||
carveout->allowed_clients = 0x4401E7E;
|
||||
carveout->client_access_0 = 0;
|
||||
carveout->client_access_1 = 0;
|
||||
carveout->client_access_2 = (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
|
||||
carveout->client_access_3 = 0;
|
||||
carveout->client_access_4 = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
|
||||
carveout->client_force_internal_access_0 = 0;
|
||||
carveout->client_force_internal_access_1 = 0;
|
||||
carveout->client_force_internal_access_2 = 0;
|
||||
carveout->client_force_internal_access_3 = 0;
|
||||
carveout->client_force_internal_access_4 = 0;
|
||||
carveout->config = 0x4401E7E;
|
||||
|
||||
/* Configure default Kernel carveouts based on 2.0.0+. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_200) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
|
||||
/* Configure Carveout 4 (KERNEL_BUILTINS) */
|
||||
configure_kernel_carveout(4, g_saved_carveouts[0].address, g_saved_carveouts[0].size);
|
||||
|
||||
@@ -111,17 +111,17 @@ void configure_default_carveouts(void) {
|
||||
carveout->paddr_low = 0;
|
||||
carveout->paddr_high = 0;
|
||||
carveout->size_big_pages = 0;
|
||||
carveout->flags_0 = 0;
|
||||
carveout->flags_1 = 0;
|
||||
carveout->flags_2 = 0;
|
||||
carveout->flags_3 = 0;
|
||||
carveout->flags_4 = 0;
|
||||
carveout->flags_5 = 0;
|
||||
carveout->flags_6 = 0;
|
||||
carveout->flags_7 = 0;
|
||||
carveout->flags_8 = 0;
|
||||
carveout->flags_9 = 0;
|
||||
carveout->allowed_clients = 0x4000006;
|
||||
carveout->client_access_0 = 0;
|
||||
carveout->client_access_1 = 0;
|
||||
carveout->client_access_2 = 0;
|
||||
carveout->client_access_3 = 0;
|
||||
carveout->client_access_4 = 0;
|
||||
carveout->client_force_internal_access_0 = 0;
|
||||
carveout->client_force_internal_access_1 = 0;
|
||||
carveout->client_force_internal_access_2 = 0;
|
||||
carveout->client_force_internal_access_3 = 0;
|
||||
carveout->client_force_internal_access_4 = 0;
|
||||
carveout->config = 0x4000006;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,15 +138,15 @@ void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint6
|
||||
carveout->paddr_low = (uint32_t)(address & 0xFFFFFFFF);
|
||||
carveout->paddr_high = (uint32_t)(address >> 32);
|
||||
carveout->size_big_pages = (uint32_t)(size >> 17);
|
||||
carveout->flags_0 = 0x70E3407F;
|
||||
carveout->flags_1 = 0x1A620880;
|
||||
carveout->flags_2 = 0x303C00;
|
||||
carveout->flags_3 = 0xCF0830BB;
|
||||
carveout->flags_4 = 0x3;
|
||||
carveout->flags_5 = exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400 && carveout_id == 4 ? 0x8000 : 0;
|
||||
carveout->flags_6 = exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400 && carveout_id == 4 ? 0x40000 : 0;
|
||||
carveout->flags_7 = 0;
|
||||
carveout->flags_8 = 0;
|
||||
carveout->flags_9 = 0;
|
||||
carveout->allowed_clients = 0x8B;
|
||||
carveout->client_access_0 = (BIT(CSR_PTCR) | BIT(CSR_DISPLAY0A) | BIT(CSR_DISPLAY0AB) | BIT(CSR_DISPLAY0B) | BIT(CSR_DISPLAY0BB) | BIT(CSR_DISPLAY0C) | BIT(CSR_DISPLAY0CB) | BIT(CSR_AFIR) | BIT(CSR_DISPLAYHC) | BIT(CSR_DISPLAYHCB) | BIT(CSR_HDAR) | BIT(CSR_HOST1XDMAR) | BIT(CSR_HOST1XR) | BIT(CSR_NVENCSRD) | BIT(CSR_PPCSAHBDMAR) | BIT(CSR_PPCSAHBSLVR));
|
||||
carveout->client_access_1 = (BIT(CSR_MPCORER) | BIT(CSW_NVENCSWR) | BIT(CSW_AFIW) | BIT(CSW_HDAW) | BIT(CSW_HOST1XW) | BIT(CSW_MPCOREW) | BIT(CSW_PPCSAHBDMAW) | BIT(CSW_PPCSAHBSLVW));
|
||||
carveout->client_access_2 = (BIT(CSR_XUSB_HOSTR) | BIT(CSW_XUSB_HOSTW) | BIT(CSR_XUSB_DEVR) | BIT(CSW_XUSB_DEVW) | BIT(CSR_TSECSRD) | BIT(CSW_TSECSWR));
|
||||
carveout->client_access_3 = (BIT(CSR_SDMMCRA) | BIT(CSR_SDMMCRAA) | BIT(CSR_SDMMCRAB) | BIT(CSW_SDMMCWA) | BIT(CSW_SDMMCWAA) | BIT(CSW_SDMMCWAB) | BIT(CSR_VICSRD) | BIT(CSW_VICSWR) | BIT(CSR_DISPLAYD) | BIT(CSR_NVDECSRD) | BIT(CSW_NVDECSWR) | BIT(CSR_APER) | BIT(CSW_APEW) | BIT(CSR_NVJPGSRD) | BIT(CSW_NVJPGSWR));
|
||||
carveout->client_access_4 = (BIT(CSR_SESRD) | BIT(CSW_SESWR));
|
||||
carveout->client_force_internal_access_0 = ((exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) && (carveout_id == 4)) ? BIT(CSR_AVPCARM7R) : 0;
|
||||
carveout->client_force_internal_access_1 = ((exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) && (carveout_id == 4)) ? BIT(CSW_AVPCARM7W) : 0;
|
||||
carveout->client_force_internal_access_2 = 0;
|
||||
carveout->client_force_internal_access_3 = 0;
|
||||
carveout->client_force_internal_access_4 = 0;
|
||||
carveout->config = 0x8B;
|
||||
}
|
||||
|
||||
@@ -27,60 +27,597 @@ static inline uintptr_t get_mc_base(void) {
|
||||
}
|
||||
|
||||
#define MC_BASE (get_mc_base())
|
||||
|
||||
#define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n)
|
||||
|
||||
#define MC_SMMU_CONFIG_0 MAKE_MC_REG(0x010)
|
||||
#define MC_SMMU_TLB_CONFIG_0 MAKE_MC_REG(0x014)
|
||||
#define MC_SMMU_PTC_CONFIG_0 MAKE_MC_REG(0x018)
|
||||
#define MC_SMMU_PTB_ASID_0 MAKE_MC_REG(0x01C)
|
||||
#define MC_SMMU_PTB_DATA_0 MAKE_MC_REG(0x020)
|
||||
#define MC_SMMU_TLB_FLUSH_0 MAKE_MC_REG(0x030)
|
||||
#define MC_SMMU_PTC_FLUSH_0 MAKE_MC_REG(0x034)
|
||||
#define MC_SMMU_AFI_ASID_0 MAKE_MC_REG(0x238)
|
||||
#define MC_SMMU_AVPC_ASID_0 MAKE_MC_REG(0x23C)
|
||||
#define MC_INTSTATUS 0x0
|
||||
#define MC_INTMASK 0x4
|
||||
#define MC_ERR_STATUS 0x8
|
||||
#define MC_ERR_ADR 0xc
|
||||
#define MC_SMMU_CONFIG 0x10
|
||||
#define MC_SMMU_TLB_CONFIG 0x14
|
||||
#define MC_SMMU_PTC_CONFIG 0x18
|
||||
#define MC_SMMU_PTB_ASID 0x1c
|
||||
#define MC_SMMU_PTB_DATA 0x20
|
||||
#define MC_SMMU_TLB_FLUSH 0x30
|
||||
#define MC_SMMU_PTC_FLUSH 0x34
|
||||
#define MC_SMMU_AFI_ASID 0x238
|
||||
#define MC_SMMU_AVPC_ASID 0x23c
|
||||
#define MC_SMMU_PPCS1_ASID 0x298
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
|
||||
#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0
|
||||
#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
|
||||
#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
|
||||
#define MC_PCFIFO_CLIENT_CONFIG3 0xddc
|
||||
#define MC_PCFIFO_CLIENT_CONFIG4 0xde0
|
||||
#define MC_EMEM_CFG 0x50
|
||||
#define MC_EMEM_ADR_CFG 0x54
|
||||
#define MC_EMEM_ADR_CFG_DEV0 0x58
|
||||
#define MC_EMEM_ADR_CFG_DEV1 0x5c
|
||||
#define MC_EMEM_ADR_CFG_CHANNEL_MASK 0x60
|
||||
#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64
|
||||
#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68
|
||||
#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c
|
||||
#define MC_SECURITY_CFG0 0x70
|
||||
#define MC_SECURITY_CFG1 0x74
|
||||
#define MC_SECURITY_CFG3 0x9bc
|
||||
#define MC_SECURITY_RSV 0x7c
|
||||
#define MC_EMEM_ARB_CFG 0x90
|
||||
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
|
||||
#define MC_EMEM_ARB_TIMING_RCD 0x98
|
||||
#define MC_EMEM_ARB_TIMING_RP 0x9c
|
||||
#define MC_EMEM_ARB_TIMING_RC 0xa0
|
||||
#define MC_EMEM_ARB_TIMING_RAS 0xa4
|
||||
#define MC_EMEM_ARB_TIMING_FAW 0xa8
|
||||
#define MC_EMEM_ARB_TIMING_RRD 0xac
|
||||
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
|
||||
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
|
||||
#define MC_EMEM_ARB_TIMING_R2R 0xb8
|
||||
#define MC_EMEM_ARB_TIMING_W2W 0xbc
|
||||
#define MC_EMEM_ARB_TIMING_R2W 0xc0
|
||||
#define MC_EMEM_ARB_TIMING_W2R 0xc4
|
||||
#define MC_EMEM_ARB_TIMING_RFCPB 0x6c0
|
||||
#define MC_EMEM_ARB_TIMING_CCDMW 0x6c4
|
||||
#define MC_EMEM_ARB_REFPB_HP_CTRL 0x6f0
|
||||
#define MC_EMEM_ARB_REFPB_BANK_CTRL 0x6f4
|
||||
#define MC_EMEM_ARB_DA_TURNS 0xd0
|
||||
#define MC_EMEM_ARB_DA_COVERS 0xd4
|
||||
#define MC_EMEM_ARB_MISC0 0xd8
|
||||
#define MC_EMEM_ARB_MISC1 0xdc
|
||||
#define MC_EMEM_ARB_MISC2 0xc8
|
||||
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
|
||||
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
|
||||
#define MC_EMEM_ARB_NISO_THROTTLE 0x6b0
|
||||
#define MC_EMEM_ARB_OVERRIDE 0xe8
|
||||
#define MC_EMEM_ARB_RSV 0xec
|
||||
#define MC_CLKEN_OVERRIDE 0xf4
|
||||
#define MC_TIMING_CONTROL_DBG 0xf8
|
||||
#define MC_TIMING_CONTROL 0xfc
|
||||
#define MC_STAT_CONTROL 0x100
|
||||
#define MC_STAT_STATUS 0x104
|
||||
#define MC_STAT_EMC_CLOCK_LIMIT 0x108
|
||||
#define MC_STAT_EMC_CLOCK_LIMIT_MSBS 0x10c
|
||||
#define MC_STAT_EMC_CLOCKS 0x110
|
||||
#define MC_STAT_EMC_CLOCKS_MSBS 0x114
|
||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 0x118
|
||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 0x158
|
||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 0x11c
|
||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 0x15c
|
||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER 0xa20
|
||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER 0xa24
|
||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 0x198
|
||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 0x1a8
|
||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 0x19c
|
||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 0x1ac
|
||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER 0xa28
|
||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER 0xa2c
|
||||
#define MC_STAT_EMC_FILTER_SET0_ASID 0x1a0
|
||||
#define MC_STAT_EMC_FILTER_SET1_ASID 0x1b0
|
||||
#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 0x120
|
||||
#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 0x160
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_0 0x128
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_0 0x168
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_1 0x12c
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_1 0x16c
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_2 0x130
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_2 0x170
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_3 0x134
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_4 0xb88
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_3 0x174
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_4 0xb8c
|
||||
#define MC_STAT_EMC_SET0_COUNT 0x138
|
||||
#define MC_STAT_EMC_SET0_COUNT_MSBS 0x13c
|
||||
#define MC_STAT_EMC_SET1_COUNT 0x178
|
||||
#define MC_STAT_EMC_SET1_COUNT_MSBS 0x17c
|
||||
#define MC_STAT_EMC_SET0_SLACK_ACCUM 0x140
|
||||
#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 0x144
|
||||
#define MC_STAT_EMC_SET1_SLACK_ACCUM 0x180
|
||||
#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 0x184
|
||||
#define MC_STAT_EMC_SET0_HISTO_COUNT 0x148
|
||||
#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 0x14c
|
||||
#define MC_STAT_EMC_SET1_HISTO_COUNT 0x188
|
||||
#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 0x18c
|
||||
#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 0x150
|
||||
#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 0x190
|
||||
#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 0x1b8
|
||||
#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 0x1bc
|
||||
#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 0x1c8
|
||||
#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 0x1cc
|
||||
#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 0x1c0
|
||||
#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 0x1d0
|
||||
#define MC_CLIENT_HOTRESET_CTRL 0x200
|
||||
#define MC_CLIENT_HOTRESET_CTRL_1 0x970
|
||||
#define MC_CLIENT_HOTRESET_STATUS 0x204
|
||||
#define MC_CLIENT_HOTRESET_STATUS_1 0x974
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_3 0x214
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_4 0xb94
|
||||
#define MC_EMEM_ARB_HYSTERESIS_0 0x218
|
||||
#define MC_EMEM_ARB_HYSTERESIS_1 0x21c
|
||||
#define MC_EMEM_ARB_HYSTERESIS_2 0x220
|
||||
#define MC_EMEM_ARB_HYSTERESIS_3 0x224
|
||||
#define MC_EMEM_ARB_HYSTERESIS_4 0xb84
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_0 0xbb0
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_1 0xbb4
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_2 0xbb8
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_3 0xbbc
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_4 0xbc0
|
||||
#define MC_EMEM_ARB_DHYST_CTRL 0xbcc
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xbd0
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xbd4
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xbd8
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xbdc
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xbe0
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xbe4
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xbe8
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xbec
|
||||
#define MC_RESERVED_RSV 0x3fc
|
||||
#define MC_DISB_EXTRA_SNAP_LEVELS 0x408
|
||||
#define MC_APB_EXTRA_SNAP_LEVELS 0x2a4
|
||||
#define MC_AHB_EXTRA_SNAP_LEVELS 0x2a0
|
||||
#define MC_USBD_EXTRA_SNAP_LEVELS 0xa18
|
||||
#define MC_ISP_EXTRA_SNAP_LEVELS 0xa08
|
||||
#define MC_AUD_EXTRA_SNAP_LEVELS 0xa10
|
||||
#define MC_MSE_EXTRA_SNAP_LEVELS 0x40c
|
||||
#define MC_GK2_EXTRA_SNAP_LEVELS 0xa40
|
||||
#define MC_A9AVPPC_EXTRA_SNAP_LEVELS 0x414
|
||||
#define MC_FTOP_EXTRA_SNAP_LEVELS 0x2bc
|
||||
#define MC_JPG_EXTRA_SNAP_LEVELS 0xa3c
|
||||
#define MC_HOST_EXTRA_SNAP_LEVELS 0xa14
|
||||
#define MC_SAX_EXTRA_SNAP_LEVELS 0x2c0
|
||||
#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac
|
||||
#define MC_VICPC_EXTRA_SNAP_LEVELS 0xa1c
|
||||
#define MC_HDAPC_EXTRA_SNAP_LEVELS 0xa48
|
||||
#define MC_AVP_EXTRA_SNAP_LEVELS 0x2a8
|
||||
#define MC_USBX_EXTRA_SNAP_LEVELS 0x404
|
||||
#define MC_PCX_EXTRA_SNAP_LEVELS 0x2b8
|
||||
#define MC_SD_EXTRA_SNAP_LEVELS 0xa04
|
||||
#define MC_DFD_EXTRA_SNAP_LEVELS 0xa4c
|
||||
#define MC_VE_EXTRA_SNAP_LEVELS 0x2d8
|
||||
#define MC_GK_EXTRA_SNAP_LEVELS 0xa00
|
||||
#define MC_VE2_EXTRA_SNAP_LEVELS 0x410
|
||||
#define MC_SDM_EXTRA_SNAP_LEVELS 0xa44
|
||||
#define MC_VIDEO_PROTECT_BOM 0x648
|
||||
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
|
||||
#define MC_VIDEO_PROTECT_BOM_ADR_HI 0x978
|
||||
#define MC_VIDEO_PROTECT_REG_CTRL 0x650
|
||||
#define MC_ERR_VPR_STATUS 0x654
|
||||
#define MC_ERR_VPR_ADR 0x658
|
||||
#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418
|
||||
#define MC_VIDEO_PROTECT_VPR_OVERRIDE1 0x590
|
||||
#define MC_IRAM_BOM 0x65c
|
||||
#define MC_IRAM_TOM 0x660
|
||||
#define MC_IRAM_ADR_HI 0x980
|
||||
#define MC_IRAM_REG_CTRL 0x964
|
||||
#define MC_EMEM_CFG_ACCESS_CTRL 0x664
|
||||
#define MC_TZ_SECURITY_CTRL 0x668
|
||||
#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c
|
||||
#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO 0x6b4
|
||||
#define MC_EMEM_ARB_RING0_THROTTLE_MASK 0x6bc
|
||||
#define MC_EMEM_ARB_NISO_THROTTLE_MASK 0x6b8
|
||||
#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1 0xb80
|
||||
#define MC_SEC_CARVEOUT_BOM 0x670
|
||||
#define MC_SEC_CARVEOUT_SIZE_MB 0x674
|
||||
#define MC_SEC_CARVEOUT_ADR_HI 0x9d4
|
||||
#define MC_SEC_CARVEOUT_REG_CTRL 0x678
|
||||
#define MC_ERR_SEC_STATUS 0x67c
|
||||
#define MC_ERR_SEC_ADR 0x680
|
||||
#define MC_PC_IDLE_CLOCK_GATE_CONFIG 0x684
|
||||
#define MC_STUTTER_CONTROL 0x688
|
||||
#define MC_RESERVED_RSV_1 0x958
|
||||
#define MC_DVFS_PIPE_SELECT 0x95c
|
||||
#define MC_AHB_PTSA_MIN 0x4e0
|
||||
#define MC_AUD_PTSA_MIN 0x54c
|
||||
#define MC_MLL_MPCORER_PTSA_RATE 0x44c
|
||||
#define MC_RING2_PTSA_RATE 0x440
|
||||
#define MC_USBD_PTSA_RATE 0x530
|
||||
#define MC_USBX_PTSA_MIN 0x528
|
||||
#define MC_USBD_PTSA_MIN 0x534
|
||||
#define MC_APB_PTSA_MAX 0x4f0
|
||||
#define MC_JPG_PTSA_RATE 0x584
|
||||
#define MC_DIS_PTSA_MIN 0x420
|
||||
#define MC_AVP_PTSA_MAX 0x4fc
|
||||
#define MC_AVP_PTSA_RATE 0x4f4
|
||||
#define MC_RING1_PTSA_MIN 0x480
|
||||
#define MC_DIS_PTSA_MAX 0x424
|
||||
#define MC_SD_PTSA_MAX 0x4d8
|
||||
#define MC_MSE_PTSA_RATE 0x4c4
|
||||
#define MC_VICPC_PTSA_MIN 0x558
|
||||
#define MC_PCX_PTSA_MAX 0x4b4
|
||||
#define MC_ISP_PTSA_RATE 0x4a0
|
||||
#define MC_A9AVPPC_PTSA_MIN 0x48c
|
||||
#define MC_RING2_PTSA_MAX 0x448
|
||||
#define MC_AUD_PTSA_RATE 0x548
|
||||
#define MC_HOST_PTSA_MIN 0x51c
|
||||
#define MC_MLL_MPCORER_PTSA_MAX 0x454
|
||||
#define MC_SD_PTSA_MIN 0x4d4
|
||||
#define MC_RING1_PTSA_RATE 0x47c
|
||||
#define MC_JPG_PTSA_MIN 0x588
|
||||
#define MC_HDAPC_PTSA_MIN 0x62c
|
||||
#define MC_AVP_PTSA_MIN 0x4f8
|
||||
#define MC_JPG_PTSA_MAX 0x58c
|
||||
#define MC_VE_PTSA_MAX 0x43c
|
||||
#define MC_DFD_PTSA_MAX 0x63c
|
||||
#define MC_VICPC_PTSA_RATE 0x554
|
||||
#define MC_GK_PTSA_MAX 0x544
|
||||
#define MC_VICPC_PTSA_MAX 0x55c
|
||||
#define MC_SDM_PTSA_MAX 0x624
|
||||
#define MC_SAX_PTSA_RATE 0x4b8
|
||||
#define MC_PCX_PTSA_MIN 0x4b0
|
||||
#define MC_APB_PTSA_MIN 0x4ec
|
||||
#define MC_GK2_PTSA_MIN 0x614
|
||||
#define MC_PCX_PTSA_RATE 0x4ac
|
||||
#define MC_RING1_PTSA_MAX 0x484
|
||||
#define MC_HDAPC_PTSA_RATE 0x628
|
||||
#define MC_MLL_MPCORER_PTSA_MIN 0x450
|
||||
#define MC_GK2_PTSA_MAX 0x618
|
||||
#define MC_AUD_PTSA_MAX 0x550
|
||||
#define MC_GK2_PTSA_RATE 0x610
|
||||
#define MC_ISP_PTSA_MAX 0x4a8
|
||||
#define MC_DISB_PTSA_RATE 0x428
|
||||
#define MC_VE2_PTSA_MAX 0x49c
|
||||
#define MC_DFD_PTSA_MIN 0x638
|
||||
#define MC_FTOP_PTSA_RATE 0x50c
|
||||
#define MC_A9AVPPC_PTSA_RATE 0x488
|
||||
#define MC_VE2_PTSA_MIN 0x498
|
||||
#define MC_USBX_PTSA_MAX 0x52c
|
||||
#define MC_DIS_PTSA_RATE 0x41c
|
||||
#define MC_USBD_PTSA_MAX 0x538
|
||||
#define MC_A9AVPPC_PTSA_MAX 0x490
|
||||
#define MC_USBX_PTSA_RATE 0x524
|
||||
#define MC_FTOP_PTSA_MAX 0x514
|
||||
#define MC_HDAPC_PTSA_MAX 0x630
|
||||
#define MC_SD_PTSA_RATE 0x4d0
|
||||
#define MC_DFD_PTSA_RATE 0x634
|
||||
#define MC_FTOP_PTSA_MIN 0x510
|
||||
#define MC_SDM_PTSA_RATE 0x61c
|
||||
#define MC_AHB_PTSA_RATE 0x4dc
|
||||
#define MC_SMMU_SMMU_PTSA_MAX 0x460
|
||||
#define MC_RING2_PTSA_MIN 0x444
|
||||
#define MC_SDM_PTSA_MIN 0x620
|
||||
#define MC_APB_PTSA_RATE 0x4e8
|
||||
#define MC_MSE_PTSA_MIN 0x4c8
|
||||
#define MC_HOST_PTSA_RATE 0x518
|
||||
#define MC_VE_PTSA_RATE 0x434
|
||||
#define MC_AHB_PTSA_MAX 0x4e4
|
||||
#define MC_SAX_PTSA_MIN 0x4bc
|
||||
#define MC_SMMU_SMMU_PTSA_MIN 0x45c
|
||||
#define MC_ISP_PTSA_MIN 0x4a4
|
||||
#define MC_HOST_PTSA_MAX 0x520
|
||||
#define MC_SAX_PTSA_MAX 0x4c0
|
||||
#define MC_VE_PTSA_MIN 0x438
|
||||
#define MC_GK_PTSA_MIN 0x540
|
||||
#define MC_MSE_PTSA_MAX 0x4cc
|
||||
#define MC_DISB_PTSA_MAX 0x430
|
||||
#define MC_DISB_PTSA_MIN 0x42c
|
||||
#define MC_SMMU_SMMU_PTSA_RATE 0x458
|
||||
#define MC_VE2_PTSA_RATE 0x494
|
||||
#define MC_GK_PTSA_RATE 0x53c
|
||||
#define MC_PTSA_GRANT_DECREMENT 0x960
|
||||
#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
|
||||
#define MC_LATENCY_ALLOWANCE_AXIAP_0 0x3a0
|
||||
#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
|
||||
#define MC_LATENCY_ALLOWANCE_SE_0 0x3e0
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
|
||||
#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
|
||||
#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
|
||||
#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
|
||||
#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3d8
|
||||
#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
|
||||
#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
|
||||
#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 0x694
|
||||
#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
|
||||
#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
|
||||
#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
|
||||
#define MC_LATENCY_ALLOWANCE_TSECB_0 0x3f0
|
||||
#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 0x698
|
||||
#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
|
||||
#define MC_LATENCY_ALLOWANCE_APE_0 0x3dc
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 0x6a0
|
||||
#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4
|
||||
#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3e8
|
||||
#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
|
||||
#define MC_LATENCY_ALLOWANCE_HC_1 0x314
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0
|
||||
#define MC_LATENCY_ALLOWANCE_NVJPG_0 0x3e4
|
||||
#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
|
||||
#define MC_LATENCY_ALLOWANCE_ETR_0 0x3ec
|
||||
#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
|
||||
#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 0x69c
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 0x6a4
|
||||
#define MC_LATENCY_ALLOWANCE_SATA_0 0x350
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 0x690
|
||||
#define MC_LATENCY_ALLOWANCE_HC_0 0x310
|
||||
#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8
|
||||
#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388
|
||||
#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328
|
||||
#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
|
||||
#define MC_MIN_LENGTH_APE_0 0xb34
|
||||
#define MC_MIN_LENGTH_DCB_2 0x8a8
|
||||
#define MC_MIN_LENGTH_A9AVP_0 0x950
|
||||
#define MC_MIN_LENGTH_TSEC_0 0x93c
|
||||
#define MC_MIN_LENGTH_DC_1 0x898
|
||||
#define MC_MIN_LENGTH_AXIAP_0 0x94c
|
||||
#define MC_MIN_LENGTH_ISP2B_0 0x930
|
||||
#define MC_MIN_LENGTH_VI2_0 0x944
|
||||
#define MC_MIN_LENGTH_DCB_0 0x8a0
|
||||
#define MC_MIN_LENGTH_DCB_1 0x8a4
|
||||
#define MC_MIN_LENGTH_PPCS_1 0x8f4
|
||||
#define MC_MIN_LENGTH_NVJPG_0 0xb3c
|
||||
#define MC_MIN_LENGTH_HDA_0 0x8c4
|
||||
#define MC_MIN_LENGTH_NVENC_0 0x8d4
|
||||
#define MC_MIN_LENGTH_SDMMC_0 0xb18
|
||||
#define MC_MIN_LENGTH_ISP2B_1 0x934
|
||||
#define MC_MIN_LENGTH_HC_1 0x8c0
|
||||
#define MC_MIN_LENGTH_DC_3 0xb20
|
||||
#define MC_MIN_LENGTH_AVPC_0 0x890
|
||||
#define MC_MIN_LENGTH_VIC_0 0x940
|
||||
#define MC_MIN_LENGTH_ISP2_0 0x91c
|
||||
#define MC_MIN_LENGTH_HC_0 0x8bc
|
||||
#define MC_MIN_LENGTH_SE_0 0xb38
|
||||
#define MC_MIN_LENGTH_NVDEC_0 0xb30
|
||||
#define MC_MIN_LENGTH_SATA_0 0x8fc
|
||||
#define MC_MIN_LENGTH_DC_0 0x894
|
||||
#define MC_MIN_LENGTH_XUSB_1 0x92c
|
||||
#define MC_MIN_LENGTH_DC_2 0x89c
|
||||
#define MC_MIN_LENGTH_SDMMCAA_0 0xb14
|
||||
#define MC_MIN_LENGTH_GPU_0 0xb04
|
||||
#define MC_MIN_LENGTH_ETR_0 0xb44
|
||||
#define MC_MIN_LENGTH_AFI_0 0x88c
|
||||
#define MC_MIN_LENGTH_PPCS_0 0x8f0
|
||||
#define MC_MIN_LENGTH_ISP2_1 0x920
|
||||
#define MC_MIN_LENGTH_XUSB_0 0x928
|
||||
#define MC_MIN_LENGTH_MPCORE_0 0x8cc
|
||||
#define MC_MIN_LENGTH_TSECB_0 0xb48
|
||||
#define MC_MIN_LENGTH_SDMMCA_0 0xb10
|
||||
#define MC_MIN_LENGTH_GPU2_0 0xb40
|
||||
#define MC_MIN_LENGTH_SDMMCAB_0 0xb1c
|
||||
#define MC_MIN_LENGTH_PTC_0 0x8f8
|
||||
#define MC_EMEM_ARB_OVERRIDE_1 0x968
|
||||
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0 0x984
|
||||
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1 0x988
|
||||
#define MC_EMEM_ARB_STATS_0 0x990
|
||||
#define MC_EMEM_ARB_STATS_1 0x994
|
||||
#define MC_MTS_CARVEOUT_BOM 0x9a0
|
||||
#define MC_MTS_CARVEOUT_SIZE_MB 0x9a4
|
||||
#define MC_MTS_CARVEOUT_ADR_HI 0x9a8
|
||||
#define MC_MTS_CARVEOUT_REG_CTRL 0x9ac
|
||||
#define MC_ERR_MTS_STATUS 0x9b0
|
||||
#define MC_ERR_MTS_ADR 0x9b4
|
||||
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
|
||||
#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 0xd74
|
||||
#define MC_SECURITY_CARVEOUT4_CFG0 0xcf8
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 0xd10
|
||||
#define MC_SECURITY_CARVEOUT4_SIZE_128KB 0xd04
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 0xc28
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 0xc30
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 0xc8c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 0xd1c
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 0xd70
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 0xc2c
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 0xd7c
|
||||
#define MC_SECURITY_CARVEOUT3_SIZE_128KB 0xcb4
|
||||
#define MC_SECURITY_CARVEOUT2_CFG0 0xc58
|
||||
#define MC_SECURITY_CARVEOUT1_CFG0 0xc08
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 0xc84
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 0xc68
|
||||
#define MC_SECURITY_CARVEOUT3_BOM 0xcac
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 0xc70
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 0xd78
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 0xc7c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 0xd18
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 0xcbc
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 0xc38
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 0xc34
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 0xcc0
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 0xd60
|
||||
#define MC_SECURITY_CARVEOUT3_CFG0 0xca8
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 0xcb8
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 0xc88
|
||||
#define MC_SECURITY_CARVEOUT2_SIZE_128KB 0xc64
|
||||
#define MC_SECURITY_CARVEOUT5_BOM_HI 0xd50
|
||||
#define MC_SECURITY_CARVEOUT1_SIZE_128KB 0xc14
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 0xd14
|
||||
#define MC_SECURITY_CARVEOUT1_BOM 0xc0c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 0xd2c
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 0xd68
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 0xcc8
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 0xd58
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 0xd24
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 0xcc4
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 0xc78
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 0xc1c
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 0xc18
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 0xd28
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 0xd5c
|
||||
#define MC_SECURITY_CARVEOUT3_BOM_HI 0xcb0
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 0xcd8
|
||||
#define MC_SECURITY_CARVEOUT2_BOM_HI 0xc60
|
||||
#define MC_SECURITY_CARVEOUT4_BOM_HI 0xd00
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 0xd64
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 0xcdc
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 0xc80
|
||||
#define MC_SECURITY_CARVEOUT5_SIZE_128KB 0xd54
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 0xd20
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 0xcd4
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 0xd0c
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 0xc74
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 0xccc
|
||||
#define MC_SECURITY_CARVEOUT4_BOM 0xcfc
|
||||
#define MC_SECURITY_CARVEOUT5_CFG0 0xd48
|
||||
#define MC_SECURITY_CARVEOUT2_BOM 0xc5c
|
||||
#define MC_SECURITY_CARVEOUT5_BOM 0xd4c
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 0xc24
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 0xd6c
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 0xcd0
|
||||
#define MC_SECURITY_CARVEOUT1_BOM_HI 0xc10
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 0xc20
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 0xc3c
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08
|
||||
#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
|
||||
#define MC_DA_CONFIG0 0x9dc
|
||||
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_0_0 MAKE_MC_REG(0x228)
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_1_0 MAKE_MC_REG(0x22C)
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_2_0 MAKE_MC_REG(0x230)
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_3_0 MAKE_MC_REG(0x234)
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_4_0 MAKE_MC_REG(0xB98)
|
||||
|
||||
#define MC_SMMU_PPCS1_ASID_0 MAKE_MC_REG(0x298)
|
||||
|
||||
#define MC_SECURITY_CFG0_0 MAKE_MC_REG(0x070)
|
||||
#define MC_SECURITY_CFG1_0 MAKE_MC_REG(0x074)
|
||||
#define MC_SECURITY_CFG3_0 MAKE_MC_REG(0x9BC)
|
||||
/* Virtual aliases */
|
||||
#define VIRT_MC_SECURITY_CFG3 MAKE_MC_REG(MC_SECURITY_CFG3)
|
||||
|
||||
/* Memory Controller clients */
|
||||
#define CLIENT_ACCESS_NUM_CLIENTS 32
|
||||
typedef enum {
|
||||
/* _ACCESS0 */
|
||||
CSR_PTCR = (0 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0A = (1 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0AB = (2 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0B = (3 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0BB = (4 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0C = (5 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0CB = (6 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_AFIR = (14 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_AVPCARM7R = (15 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAYHC = (16 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAYHCB = (17 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_HDAR = (21 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_HOST1XDMAR = (22 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_HOST1XR = (23 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_NVENCSRD = (28 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_PPCSAHBDMAR = (29 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_PPCSAHBSLVR = (30 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_SATAR = (31 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
|
||||
/* _ACCESS1 */
|
||||
CSR_VDEBSEVR = (34 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_VDEMBER = (35 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_VDEMCER = (36 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_VDETPER = (37 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_MPCORELPR = (38 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_MPCORER = (39 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_NVENCSWR = (43 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_AFIW = (49 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_AVPCARM7W = (50 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_HDAW = (53 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_HOST1XW = (54 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_MPCORELPW = (56 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_MPCOREW = (57 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_PPCSAHBDMAW = (59 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_PPCSAHBSLVW = (60 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_SATAW = (61 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_VDEBSEVW = (62 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_VDEDBGW = (63 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
|
||||
/* _ACCESS2 */
|
||||
CSW_VDEMBEW = (64 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_VDETPMW = (65 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_ISPRA = (68 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWA = (70 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWB = (71 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_XUSB_HOSTR = (74 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_XUSB_HOSTW = (75 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_XUSB_DEVR = (76 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_XUSB_DEVW = (77 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_ISPRAB = (78 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWAB = (80 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWBB = (81 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_TSECSRD = (84 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_TSECSWR = (85 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_A9AVPSCR = (86 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_A9AVPSCW = (87 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_GPUSRD = (88 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_GPUSWR = (89 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_DISPLAYT = (90 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
|
||||
/* _ACCESS3 */
|
||||
CSR_SDMMCRA = (96 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_SDMMCRAA = (97 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_SDMMCR = (98 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_SDMMCRAB = (99 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCWA = (100 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCWAA = (101 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCW = (102 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCWAB = (103 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_VICSRD = (108 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_VICSWR = (109 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_VIW = (114 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_DISPLAYD = (115 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_NVDECSRD = (120 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_NVDECSWR = (121 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_APER = (122 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_APEW = (123 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_NVJPGSRD = (126 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_NVJPGSWR = (127 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
|
||||
/* _ACCESS4 */
|
||||
CSR_SESRD = (128 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_SESWR = (129 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_AXIAPR = (130 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_AXIAPW = (131 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_ETRR = (132 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_ETRW = (133 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_TSECSRDB = (134 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_TSECSWRB = (135 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_GPUSRD2 = (136 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_GPUSWR2 = (137 - (CLIENT_ACCESS_NUM_CLIENTS * 4))
|
||||
} McClient;
|
||||
|
||||
/* Memory Controller carveouts */
|
||||
#define CARVEOUT_ID_MIN 1
|
||||
#define CARVEOUT_ID_MAX 5
|
||||
|
||||
#define KERNEL_CARVEOUT_SIZE_MAX 0x1FFE0000
|
||||
|
||||
typedef struct {
|
||||
uint32_t allowed_clients;
|
||||
uint32_t config;
|
||||
uint32_t paddr_low;
|
||||
uint32_t paddr_high;
|
||||
uint32_t size_big_pages;
|
||||
uint32_t flags_0;
|
||||
uint32_t flags_1;
|
||||
uint32_t flags_2;
|
||||
uint32_t flags_3;
|
||||
uint32_t flags_4;
|
||||
uint32_t flags_5;
|
||||
uint32_t flags_6;
|
||||
uint32_t flags_7;
|
||||
uint32_t flags_8;
|
||||
uint32_t flags_9;
|
||||
uint32_t client_access_0;
|
||||
uint32_t client_access_1;
|
||||
uint32_t client_access_2;
|
||||
uint32_t client_access_3;
|
||||
uint32_t client_access_4;
|
||||
uint32_t client_force_internal_access_0;
|
||||
uint32_t client_force_internal_access_1;
|
||||
uint32_t client_force_internal_access_2;
|
||||
uint32_t client_force_internal_access_3;
|
||||
uint32_t client_force_internal_access_4;
|
||||
uint8_t padding[0x18];
|
||||
} security_carveout_t;
|
||||
|
||||
|
||||
volatile security_carveout_t *get_carveout_by_id(unsigned int carveout);
|
||||
void configure_default_carveouts(void);
|
||||
void configure_gpu_ucode_carveout(void);
|
||||
void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint64_t size);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -48,7 +48,9 @@
|
||||
#define _MMAPDEV15 ( 0x6000D000ull, 0x1000ull, true ) /* GPIO-1 - GPIO-8 */
|
||||
#define _MMAPDEV16 ( 0x7000C000ull, 0x1000ull, true ) /* I2C-I2C4 */
|
||||
#define _MMAPDEV17 ( 0x6000F000ull, 0x1000ull, true ) /* Exception vectors */
|
||||
#define _MMAPDEV18 ( 0x40038000ull, 0x8000ull, true ) /* DEBUG: IRAM */
|
||||
#define _MMAPDEV18 ( 0x00000000ull, 0x1000ull, true ) /* AMS irampage, NOT mapped at startup */
|
||||
#define _MMAPDEV19 ( 0x00000000ull, 0x1000ull, true ) /* AMS userpage, NOT mapped at startup */
|
||||
#define _MMAPDEV20 ( 0x40038000ull, 0x5000ull, true ) /* DEBUG: IRAM */
|
||||
|
||||
/* LP0 entry ram segments (addr, size, additional attributes) */
|
||||
#define _MMAPLP0ES0 ( 0x40020000ull, 0x10000ull, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE ) /* Encrypted TZRAM */
|
||||
@@ -108,8 +110,10 @@
|
||||
#define MMIO_DEVID_GPIO 15
|
||||
#define MMIO_DEVID_DTV_I2C234 16
|
||||
#define MMIO_DEVID_EXCEPTION_VECTORS 17
|
||||
#define MMIO_DEVID_DEBUG_IRAM 18
|
||||
#define MMIO_DEVID_MAX 19
|
||||
#define MMIO_DEVID_AMS_IRAM_PAGE 18
|
||||
#define MMIO_DEVID_AMS_USER_PAGE 19
|
||||
#define MMIO_DEVID_DEBUG_IRAM 20
|
||||
#define MMIO_DEVID_MAX 21
|
||||
|
||||
#define LP0_ENTRY_RAM_SEGMENT_ID_ENCRYPTED_TZRAM 0
|
||||
#define LP0_ENTRY_RAM_SEGMENT_ID_LP0_ENTRY_CODE 1
|
||||
|
||||
@@ -165,6 +165,10 @@ static inline void mmu_unmap(unsigned int level, uintptr_t *tbl, uintptr_t base_
|
||||
tbl[mmu_compute_index(level, base_addr)] = MMU_PTE_TYPE_FAULT;
|
||||
}
|
||||
|
||||
static inline void mmu_unmap_page(uintptr_t *tbl, uintptr_t base_addr) {
|
||||
tbl[mmu_compute_index(3, base_addr)] = MMU_PTE_TYPE_FAULT;
|
||||
}
|
||||
|
||||
static inline void mmu_map_block_range(unsigned int level, uintptr_t *tbl, uintptr_t base_addr, uintptr_t phys_addr, size_t size, uint64_t attrs) {
|
||||
size = ((size + (BITL(MMU_Lx_SHIFT(level)) - 1)) >> MMU_Lx_SHIFT(level)) << MMU_Lx_SHIFT(level);
|
||||
for(size_t offset = 0; offset < size; offset += BITL(MMU_Lx_SHIFT(level))) {
|
||||
|
||||
@@ -38,21 +38,48 @@ extern void *__start_cold_addr;
|
||||
extern size_t __bin_size;
|
||||
|
||||
static const uint8_t new_device_key_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
|
||||
{0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */
|
||||
{0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.x New Device Key Source. */
|
||||
{0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4} /* 6.x New Device Key Source. */
|
||||
{0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */
|
||||
{0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.x New Device Key Source. */
|
||||
{0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */
|
||||
{0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17} /* 6.2.0 New Device Key Source. */
|
||||
};
|
||||
|
||||
static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
|
||||
{0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D}, /* 4.x New Device Keygen Source. */
|
||||
{0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E}, /* 5.x New Device Keygen Source. */
|
||||
{0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF} /* 6.x New Device Keygen Source. */
|
||||
{0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D}, /* 4.x New Device Keygen Source. */
|
||||
{0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E}, /* 5.x New Device Keygen Source. */
|
||||
{0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF}, /* 6.x New Device Keygen Source. */
|
||||
{0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB} /* 6.2.0 New Device Keygen Source. */
|
||||
};
|
||||
|
||||
static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
|
||||
{0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34}, /* 4.x New Device Keygen Source. */
|
||||
{0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8}, /* 5.x New Device Keygen Source. */
|
||||
{0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5} /* 6.x New Device Keygen Source. */
|
||||
{0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34}, /* 4.x New Device Keygen Source. */
|
||||
{0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8}, /* 5.x New Device Keygen Source. */
|
||||
{0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5}, /* 6.x New Device Keygen Source. */
|
||||
{0x20, 0xAB, 0xF2, 0x0F, 0x05, 0xE3, 0xDE, 0x2E, 0xA1, 0xFB, 0x37, 0x5E, 0x8B, 0x22, 0x1A, 0x38} /* 6.2.0 New Device Keygen Source. */
|
||||
};
|
||||
|
||||
static const uint8_t new_master_kek_sources[1][0x10] = {
|
||||
{0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, /* 6.2.0 Master Kek Source. */
|
||||
};
|
||||
|
||||
static const uint8_t keyblob_key_seed_00[0x10] = {
|
||||
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3
|
||||
};
|
||||
|
||||
static const uint8_t devicekey_seed[0x10] = {
|
||||
0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78
|
||||
};
|
||||
|
||||
static const uint8_t devicekey_4x_seed[0x10] = {
|
||||
0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28
|
||||
};
|
||||
|
||||
static const uint8_t masterkey_seed[0x10] = {
|
||||
0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C
|
||||
};
|
||||
|
||||
static const uint8_t devicekek_4x_seed[0x10] = {
|
||||
0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66
|
||||
};
|
||||
|
||||
static void derive_new_device_keys(unsigned int keygen_keyslot) {
|
||||
@@ -105,21 +132,36 @@ static void setup_se(void) {
|
||||
for (unsigned int i = 0; i < KEYSLOT_RSA_MAX; i++) {
|
||||
set_rsa_keyslot_flags(i, 0x41);
|
||||
}
|
||||
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_620 && exosphere_should_perform_620_keygen()) {
|
||||
/* Start by generating device keys. */
|
||||
se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_6XTSECKEY, work_buffer, 0x10, keyblob_key_seed_00, 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XOLDDEVICEKEY, KEYSLOT_SWITCH_6XSBK, work_buffer, 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XNEWCONSOLEKEYGENKEY, KEYSLOT_SWITCH_4XOLDDEVICEKEY, devicekey_4x_seed, 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XOLDDEVICEKEY, KEYSLOT_SWITCH_4XOLDDEVICEKEY, devicekey_seed, 0x10);
|
||||
|
||||
/* Next, generate the master kek, and from there master key/device kek. We use different keyslots than Nintendo, here. */
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_6XTSECROOTKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, new_master_kek_sources[0], 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_MASTERKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, masterkey_seed, 0x10);
|
||||
decrypt_data_into_keyslot(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, devicekek_4x_seed, 0x10);
|
||||
clear_aes_keyslot(KEYSLOT_SWITCH_6XTSECROOTKEY);
|
||||
}
|
||||
|
||||
/* Detect Master Key revision. */
|
||||
mkey_detect_revision();
|
||||
|
||||
/* Derive new device keys. */
|
||||
switch (exosphere_get_target_firmware()) {
|
||||
case EXOSPHERE_TARGET_FIRMWARE_100:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_200:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_300:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_100:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_200:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_300:
|
||||
break;
|
||||
case EXOSPHERE_TARGET_FIRMWARE_400:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_400:
|
||||
derive_new_device_keys(KEYSLOT_SWITCH_4XNEWDEVICEKEYGENKEY);
|
||||
break;
|
||||
case EXOSPHERE_TARGET_FIRMWARE_500:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_600:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_500:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_600:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_620:
|
||||
derive_new_device_keys(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY);
|
||||
break;
|
||||
}
|
||||
@@ -146,7 +188,7 @@ static void setup_boot_config(void) {
|
||||
bootconfig_clear();
|
||||
} else {
|
||||
void *bootconfig_ptr = NX_BOOTLOADER_BOOTCONFIG_POINTER;
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_600) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
|
||||
bootconfig_ptr = NX_BOOTLOADER_BOOTCONFIG_POINTER_6X;
|
||||
}
|
||||
flush_dcache_range((uint8_t *)bootconfig_ptr, (uint8_t *)bootconfig_ptr + sizeof(bootconfig_t));
|
||||
@@ -304,7 +346,7 @@ static bool validate_package2_metadata(package2_meta_t *metadata) {
|
||||
|
||||
/* Perform version checks. */
|
||||
/* We will be compatible with all package2s released before current, but not newer ones. */
|
||||
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_600_CURRENT) {
|
||||
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_620_CURRENT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -413,17 +455,18 @@ static void load_package2_sections(package2_meta_t *metadata, uint32_t master_ke
|
||||
static void copy_warmboot_bin_to_dram() {
|
||||
uint8_t *warmboot_src;
|
||||
switch (exosphere_get_target_firmware()) {
|
||||
case EXOSPHERE_TARGET_FIRMWARE_100:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_200:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_300:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_100:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_200:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_300:
|
||||
default:
|
||||
generic_panic();
|
||||
break;
|
||||
case EXOSPHERE_TARGET_FIRMWARE_400:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_500:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_400:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_500:
|
||||
warmboot_src = (uint8_t *)0x4003B000;
|
||||
break;
|
||||
case EXOSPHERE_TARGET_FIRMWARE_600:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_600:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_620:
|
||||
warmboot_src = (uint8_t *)0x4003D800;
|
||||
break;
|
||||
}
|
||||
@@ -466,26 +509,30 @@ uintptr_t get_pk2ldr_stack_address(void) {
|
||||
void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
/* Load Exosphere-specific config. */
|
||||
exosphere_load_config();
|
||||
configitem_set_debugmode_override(exosphere_should_override_debugmode_user() != 0, exosphere_should_override_debugmode_priv() != 0);
|
||||
|
||||
/* Setup the Security Engine. */
|
||||
setup_se();
|
||||
|
||||
/* Perform initial PMC register writes, if relevant. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
MAKE_REG32(PMC_BASE + 0x054) = 0x8000D000;
|
||||
MAKE_REG32(PMC_BASE + 0x0A0) &= 0xFFF3FFFF;
|
||||
MAKE_REG32(PMC_BASE + 0x818) &= 0xFFFFFFFE;
|
||||
MAKE_REG32(PMC_BASE + 0x334) |= 0x10;
|
||||
switch (exosphere_get_target_firmware()) {
|
||||
case EXOSPHERE_TARGET_FIRMWARE_400:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_400:
|
||||
MAKE_REG32(PMC_BASE + 0x360) = 0x105;
|
||||
break;
|
||||
case EXOSPHERE_TARGET_FIRMWARE_500:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_500:
|
||||
MAKE_REG32(PMC_BASE + 0x360) = 6;
|
||||
break;
|
||||
case EXOSPHERE_TARGET_FIRMWARE_600:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_600:
|
||||
MAKE_REG32(PMC_BASE + 0x360) = 0x87;
|
||||
break;
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_620:
|
||||
MAKE_REG32(PMC_BASE + 0x360) = 0xA8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,7 +564,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
setup_boot_config();
|
||||
|
||||
/* Set sysctr0 registers based on bootconfig. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
uint64_t sysctr0_val = bootconfig_get_value_for_sysctr0();
|
||||
MAKE_SYSCTR0_REG(0x8) = (uint32_t)((sysctr0_val >> 0) & 0xFFFFFFFFULL);
|
||||
MAKE_SYSCTR0_REG(0xC) = (uint32_t)((sysctr0_val >> 32) & 0xFFFFFFFFULL);
|
||||
@@ -525,10 +572,10 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
}
|
||||
|
||||
/* Synchronize with NX BOOTLOADER. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X);
|
||||
copy_warmboot_bin_to_dram();
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_600) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
|
||||
setup_dram_magic_numbers();
|
||||
}
|
||||
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_LOADED_PACKAGE2_4X);
|
||||
@@ -581,7 +628,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
||||
}
|
||||
|
||||
/* Synchronize with NX BOOTLOADER. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_FINISHED_4X);
|
||||
setup_4x_mmio();
|
||||
} else {
|
||||
|
||||
@@ -67,7 +67,8 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(void) {
|
||||
#define PACKAGE2_MAXVER_302 0x5
|
||||
#define PACKAGE2_MAXVER_400_410 0x6
|
||||
#define PACKAGE2_MAXVER_500_510 0x7
|
||||
#define PACKAGE2_MAXVER_600_CURRENT 0x8
|
||||
#define PACKAGE2_MAXVER_600_610 0x8
|
||||
#define PACKAGE2_MAXVER_620_CURRENT 0x9
|
||||
|
||||
#define PACKAGE2_MINVER_100 0x3
|
||||
#define PACKAGE2_MINVER_200 0x4
|
||||
@@ -75,7 +76,8 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(void) {
|
||||
#define PACKAGE2_MINVER_302 0x6
|
||||
#define PACKAGE2_MINVER_400_410 0x7
|
||||
#define PACKAGE2_MINVER_500_510 0x8
|
||||
#define PACKAGE2_MINVER_600_CURRENT 0x9
|
||||
#define PACKAGE2_MINVER_600_610 0x9
|
||||
#define PACKAGE2_MINVER_620_CURRENT 0xA
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
|
||||
@@ -28,18 +28,19 @@
|
||||
#include "flow.h"
|
||||
#include "fuse.h"
|
||||
#include "i2c.h"
|
||||
#include "lp0.h"
|
||||
#include "sc7.h"
|
||||
#include "masterkey.h"
|
||||
#include "pmc.h"
|
||||
#include "se.h"
|
||||
#include "smc_api.h"
|
||||
#include "timers.h"
|
||||
#include "misc.h"
|
||||
#include "uart.h"
|
||||
#include "exocfg.h"
|
||||
|
||||
#define u8 uint8_t
|
||||
#define u32 uint32_t
|
||||
#include "bpmpfw_bin.h"
|
||||
#include "sc7fw_bin.h"
|
||||
#undef u8
|
||||
#undef u32
|
||||
|
||||
@@ -88,14 +89,14 @@ static void mitigate_jamais_vu(void) {
|
||||
}
|
||||
|
||||
/* For debugging, make this check always pass. */
|
||||
if ((exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400 || (get_debug_authentication_status() & 3) == 3)) {
|
||||
if ((exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400 || (get_debug_authentication_status() & 3) == 3)) {
|
||||
FLOW_CTLR_HALT_COP_EVENTS_0 = 0x50000000;
|
||||
} else {
|
||||
FLOW_CTLR_HALT_COP_EVENTS_0 = 0x40000000;
|
||||
}
|
||||
|
||||
/* Jamais Vu mitigation #2: Ensure the BPMP is halted. */
|
||||
if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400 || (get_debug_authentication_status() & 3) == 3) {
|
||||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400 || (get_debug_authentication_status() & 3) == 3) {
|
||||
/* BPMP should just be plainly halted, in debugging conditions. */
|
||||
if (FLOW_CTLR_HALT_COP_EVENTS_0 != 0x50000000) {
|
||||
generic_panic();
|
||||
@@ -137,11 +138,11 @@ static void setup_bpmp_sc7_firmware(void) {
|
||||
|
||||
/* Copy BPMP firmware. */
|
||||
uint8_t *lp0_entry_code = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_LP0_ENTRY_CODE));
|
||||
for (unsigned int i = 0; i < bpmpfw_bin_size; i += 4) {
|
||||
write32le(lp0_entry_code, i, read32le(bpmpfw_bin, i));
|
||||
for (unsigned int i = 0; i < sc7fw_bin_size; i += 4) {
|
||||
write32le(lp0_entry_code, i, read32le(sc7fw_bin, i));
|
||||
}
|
||||
|
||||
flush_dcache_range(lp0_entry_code, lp0_entry_code + bpmpfw_bin_size);
|
||||
flush_dcache_range(lp0_entry_code, lp0_entry_code + sc7fw_bin_size);
|
||||
|
||||
/* Take the BPMP out of reset. */
|
||||
MAKE_CAR_REG(0x304) = 2;
|
||||
@@ -165,7 +166,7 @@ static void save_tzram_state(void) {
|
||||
|
||||
uint8_t *tzram_encryption_dst = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_ENCRYPTED_TZRAM));
|
||||
uint8_t *tzram_encryption_src = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_CURRENT_TZRAM));
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
tzram_encryption_src += 0x2000ull;
|
||||
}
|
||||
uint8_t *tzram_store_address = (uint8_t *)(WARMBOOT_GET_RAM_SEGMENT_ADDRESS(WARMBOOT_RAM_SEGMENT_ID_TZRAM));
|
||||
@@ -202,7 +203,7 @@ static void save_tzram_state(void) {
|
||||
APBDEV_PMC_SEC_DISABLE8_0 = 0x550000;
|
||||
|
||||
/* Perform pre-2.0.0 PMC writes. */
|
||||
if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_200) {
|
||||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_200) {
|
||||
/* TODO: Give these writes appropriate defines in pmc.h */
|
||||
|
||||
/* Save Encrypted context location + lock scratch register. */
|
||||
@@ -239,9 +240,13 @@ void save_se_and_power_down_cpu(void) {
|
||||
/* Save context for warmboot to restore. */
|
||||
save_tzram_state();
|
||||
save_se_state();
|
||||
|
||||
/* Patch the bootrom to disable warmboot signature checks. */
|
||||
MAKE_REG32(PMC_BASE + 0x118) = 0x2202E012;
|
||||
MAKE_REG32(PMC_BASE + 0x11C) = 0x6001DC28;
|
||||
|
||||
if (!configitem_is_retail()) {
|
||||
/* TODO: uart_log("OYASUMI"); */
|
||||
uart_send(UART_A, "OYASUMI", 8);
|
||||
}
|
||||
|
||||
finalize_powerdown();
|
||||
@@ -266,7 +271,7 @@ uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argumen
|
||||
notify_pmic_shutdown();
|
||||
|
||||
/* Validate that the shutdown has correct context. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_200) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
|
||||
mitigate_jamais_vu();
|
||||
}
|
||||
|
||||
@@ -274,7 +279,7 @@ uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argumen
|
||||
configure_pmc_for_deep_powerdown();
|
||||
|
||||
/* Ensure that BPMP SC7 firmware is active. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_200) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
|
||||
setup_bpmp_sc7_firmware();
|
||||
}
|
||||
|
||||
@@ -288,7 +293,7 @@ uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argumen
|
||||
|
||||
/* Ensure that other cores are already asleep. */
|
||||
if (!(APBDEV_PMC_PWRGATE_STATUS_0 & 0xE00)) {
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_200) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
|
||||
call_with_stack_pointer(get_smc_core012_stack_address(), save_se_and_power_down_cpu);
|
||||
} else {
|
||||
save_se_and_power_down_cpu();
|
||||
@@ -14,8 +14,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef EXOSPHERE_LP0_H
|
||||
#define EXOSPHERE_LP0_H
|
||||
#ifndef EXOSPHERE_SC7_H
|
||||
#define EXOSPHERE_SC7_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -43,6 +43,11 @@
|
||||
/* This keyslot was added in 5.0.0. */
|
||||
#define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA
|
||||
|
||||
/* This keyslot was added in 6.00. */
|
||||
#define KEYSLOT_SWITCH_6XTSECKEY 0xC
|
||||
#define KEYSLOT_SWITCH_6XTSECROOTKEY 0xD
|
||||
#define KEYSLOT_SWITCH_6XSBK 0xE
|
||||
|
||||
#define KEYSLOT_AES_MAX 0x10
|
||||
#define KEYSLOT_RSA_MAX 0x2
|
||||
|
||||
|
||||
@@ -33,11 +33,11 @@ static const uint8_t g_seal_key_sources[CRYPTOUSECASE_MAX_5X][0x10] = {
|
||||
{0x0E, 0xE0, 0xC4, 0x33, 0x82, 0x66, 0xE8, 0x08, 0x39, 0x13, 0x41, 0x7D, 0x04, 0x64, 0x2B, 0x6D},
|
||||
{0xE1, 0xA8, 0xAA, 0x6A, 0x2D, 0x9C, 0xDE, 0x43, 0x0C, 0xDE, 0xC6, 0x17, 0xF6, 0xC7, 0xF1, 0xDE},
|
||||
{0x74, 0x20, 0xF6, 0x46, 0x77, 0xB0, 0x59, 0x2C, 0xE8, 0x1B, 0x58, 0x64, 0x47, 0x41, 0x37, 0xD9},
|
||||
{0xAA, 0x19, 0x0F, 0xFA, 0x4C, 0x30, 0x3B, 0x2E, 0xE8, 0x1B, 0x58, 0x64, 0x47, 0x41, 0x37, 0xD9}
|
||||
{0xAA, 0x19, 0x0F, 0xFA, 0x4C, 0x30, 0x3B, 0x2E, 0xE6, 0xD8, 0x9A, 0xCF, 0xE5, 0x3F, 0xB3, 0x4B}
|
||||
};
|
||||
|
||||
bool usecase_is_invalid(unsigned int usecase) {
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
return usecase >= CRYPTOUSECASE_MAX_5X;
|
||||
} else {
|
||||
return usecase >= CRYPTOUSECASE_MAX;
|
||||
|
||||
157
exosphere/src/smc_ams.c
Normal file
157
exosphere/src/smc_ams.c
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "smc_ams.h"
|
||||
#include "arm.h"
|
||||
#include "synchronization.h"
|
||||
#include "memory_map.h"
|
||||
#include "mmu.h"
|
||||
|
||||
static atomic_flag g_ams_userpage_mapped = ATOMIC_FLAG_INIT;
|
||||
static atomic_flag g_ams_iram_page_mapped = ATOMIC_FLAG_INIT;
|
||||
|
||||
static inline uintptr_t get_ams_user_page_secure_monitor_addr(void) {
|
||||
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_USER_PAGE);
|
||||
}
|
||||
|
||||
static inline uintptr_t get_ams_iram_page_secure_monitor_addr(void) {
|
||||
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE);
|
||||
}
|
||||
|
||||
#define AMS_USER_PAGE_SECURE_MONITOR_ADDR (get_ams_user_page_secure_monitor_addr())
|
||||
#define AMS_IRAM_PAGE_SECURE_MONITOR_ADDR (get_ams_iram_page_secure_monitor_addr())
|
||||
|
||||
|
||||
static inline uintptr_t get_page_for_address(void *address) {
|
||||
return ((uintptr_t)(address)) & ~0xFFFULL;
|
||||
}
|
||||
|
||||
static bool ams_is_user_addr_valid(uintptr_t user_address) {
|
||||
/* Check that the address is in dram. */
|
||||
uintptr_t page_address = get_page_for_address((void *)user_address);
|
||||
return (page_address - 0x80000000ull) < (6ull << 30);
|
||||
}
|
||||
|
||||
static bool ams_is_iram_addr_valid(uintptr_t iram_address) {
|
||||
/* Check that the address is in iram. */
|
||||
return 0x40000000ULL <= iram_address && iram_address <= 0x4003FFFFULL;
|
||||
}
|
||||
|
||||
static void ams_map_userpage(uintptr_t user_address) {
|
||||
lock_acquire(&g_ams_userpage_mapped);
|
||||
static const uint64_t userpage_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_NORMAL;
|
||||
uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
|
||||
mmu_map_page(mmu_l3_tbl, AMS_USER_PAGE_SECURE_MONITOR_ADDR, get_page_for_address((void *)user_address), userpage_attributes);
|
||||
tlb_invalidate_page_inner_shareable((void *)AMS_USER_PAGE_SECURE_MONITOR_ADDR);
|
||||
}
|
||||
|
||||
static void ams_unmap_userpage(void) {
|
||||
uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
|
||||
mmu_unmap_page(mmu_l3_tbl, AMS_USER_PAGE_SECURE_MONITOR_ADDR);
|
||||
tlb_invalidate_page_inner_shareable((void *)AMS_USER_PAGE_SECURE_MONITOR_ADDR);
|
||||
lock_release(&g_ams_userpage_mapped);
|
||||
}
|
||||
|
||||
void ams_map_irampage(uintptr_t iram_address) {
|
||||
lock_acquire(&g_ams_iram_page_mapped);
|
||||
static const uint64_t irampage_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_DEVICE;
|
||||
uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
|
||||
mmu_map_page(mmu_l3_tbl, AMS_IRAM_PAGE_SECURE_MONITOR_ADDR, get_page_for_address((void *)iram_address), irampage_attributes);
|
||||
tlb_invalidate_page_inner_shareable((void *)AMS_IRAM_PAGE_SECURE_MONITOR_ADDR);
|
||||
}
|
||||
|
||||
void ams_unmap_irampage(void) {
|
||||
uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
|
||||
mmu_unmap_page(mmu_l3_tbl, AMS_IRAM_PAGE_SECURE_MONITOR_ADDR);
|
||||
tlb_invalidate_page_inner_shareable((void *)AMS_IRAM_PAGE_SECURE_MONITOR_ADDR);
|
||||
lock_release(&g_ams_iram_page_mapped);
|
||||
}
|
||||
|
||||
uint32_t ams_iram_copy(smc_args_t *args) {
|
||||
/* Implements a DRAM <-> IRAM copy of up to one page. */
|
||||
/* This operation is necessary to implement reboot-to-payload. */
|
||||
/* args->X[1] = DRAM address (translated by kernel), must be 4-byte aligned. */
|
||||
/* args->X[2] = IRAM address, must be 4-byte aligned. */
|
||||
/* args->X[3] = size (must be <= 0x1000 and 4-byte aligned). */
|
||||
/* args->X[4] = 0 for read, 1 for write. */
|
||||
|
||||
const uintptr_t dram_address = (uintptr_t)args->X[1];
|
||||
const uintptr_t iram_address = (uintptr_t)args->X[2];
|
||||
const uintptr_t dram_page_offset = (dram_address & 0xFFFULL);
|
||||
const uintptr_t iram_page_offset = (iram_address & 0xFFFULL);
|
||||
const size_t size = args->X[3];
|
||||
const uint32_t option = (uint32_t)args->X[4];
|
||||
|
||||
/* Validate addresses. */
|
||||
if (!ams_is_user_addr_valid(dram_address) || !ams_is_iram_addr_valid(iram_address)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Validate size. */
|
||||
if (size > 0x1000 || (size + dram_page_offset) > 0x1000 || (size + iram_page_offset) > 0x1000) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Validate alignment. */
|
||||
if (size % sizeof(uint32_t) || dram_page_offset % sizeof(uint32_t) || iram_page_offset % sizeof(uint32_t)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Validate argument. */
|
||||
if (option != 0 && option != 1) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Map pages. */
|
||||
ams_map_userpage(dram_address);
|
||||
ams_map_irampage(iram_address);
|
||||
|
||||
/* Set source/destination for copy. */
|
||||
volatile uint32_t *dram_ptr = (volatile uint32_t *)(AMS_USER_PAGE_SECURE_MONITOR_ADDR + dram_page_offset);
|
||||
volatile uint32_t *iram_ptr = (volatile uint32_t *)(AMS_IRAM_PAGE_SECURE_MONITOR_ADDR + iram_page_offset);
|
||||
|
||||
volatile uint32_t *dst;
|
||||
volatile uint32_t *src;
|
||||
const size_t num_dwords = size / sizeof(uint32_t);
|
||||
if (option == 0) {
|
||||
dst = dram_ptr;
|
||||
src = iram_ptr;
|
||||
} else {
|
||||
dst = iram_ptr;
|
||||
src = dram_ptr;
|
||||
}
|
||||
|
||||
/* Actually copy data. */
|
||||
for (size_t i = 0; i < num_dwords; i++) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
|
||||
/* Flush! */
|
||||
flush_dcache_range((void *)dst, (void *)(dst + num_dwords));
|
||||
|
||||
/* Unmap pages. */
|
||||
ams_unmap_irampage();
|
||||
ams_unmap_userpage();
|
||||
|
||||
return 0;
|
||||
}
|
||||
27
exosphere/src/smc_ams.h
Normal file
27
exosphere/src/smc_ams.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 EXOSPHERE_SMC_AMS_H
|
||||
#define EXOSPHERE_SMC_AMS_H
|
||||
|
||||
#include "smc_api.h"
|
||||
|
||||
uint32_t ams_iram_copy(smc_args_t *args);
|
||||
|
||||
void ams_map_irampage(uintptr_t iram_address);
|
||||
void ams_unmap_irampage(void);
|
||||
|
||||
#endif
|
||||
@@ -31,21 +31,24 @@
|
||||
#include "sealedkeys.h"
|
||||
#include "smc_api.h"
|
||||
#include "smc_user.h"
|
||||
#include "smc_ams.h"
|
||||
#include "se.h"
|
||||
#include "userpage.h"
|
||||
#include "titlekey.h"
|
||||
#include "lp0.h"
|
||||
#include "sc7.h"
|
||||
#include "exocfg.h"
|
||||
|
||||
#define SMC_USER_HANDLERS 0x13
|
||||
#define SMC_PRIV_HANDLERS 0x9
|
||||
|
||||
#define SMC_AMS_HANDLERS 0x2
|
||||
|
||||
#define DEBUG_LOG_SMCS 0
|
||||
#define DEBUG_PANIC_ON_FAILURE 0
|
||||
|
||||
/* User SMC prototypes */
|
||||
uint32_t smc_set_config(smc_args_t *args);
|
||||
uint32_t smc_get_config(smc_args_t *args);
|
||||
uint32_t smc_set_config_user(smc_args_t *args);
|
||||
uint32_t smc_get_config_user(smc_args_t *args);
|
||||
uint32_t smc_check_status(smc_args_t *args);
|
||||
uint32_t smc_get_result(smc_args_t *args);
|
||||
uint32_t smc_exp_mod(smc_args_t *args);
|
||||
@@ -71,12 +74,15 @@ uint32_t smc_decrypt_or_import_rsa_key(smc_args_t *args);
|
||||
uint32_t smc_cpu_suspend(smc_args_t *args);
|
||||
uint32_t smc_cpu_off(smc_args_t *args);
|
||||
uint32_t smc_cpu_on(smc_args_t *args);
|
||||
/* uint32_t smc_get_config(smc_args_t *args); */
|
||||
uint32_t smc_get_config_priv(smc_args_t *args);
|
||||
uint32_t smc_get_random_bytes_for_priv(smc_args_t *args);
|
||||
uint32_t smc_panic(smc_args_t *args);
|
||||
uint32_t smc_configure_carveout(smc_args_t *args);
|
||||
uint32_t smc_read_write_register(smc_args_t *args);
|
||||
|
||||
/* Atmosphere SMC prototypes */
|
||||
uint32_t smc_ams_iram_copy(smc_args_t *args);
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
uint32_t (*handler)(smc_args_t *args);
|
||||
@@ -89,8 +95,8 @@ typedef struct {
|
||||
|
||||
static smc_table_entry_t g_smc_user_table[SMC_USER_HANDLERS] = {
|
||||
{0, NULL},
|
||||
{0xC3000401, smc_set_config},
|
||||
{0xC3000002, smc_get_config},
|
||||
{0xC3000401, smc_set_config_user},
|
||||
{0xC3000002, smc_get_config_user},
|
||||
{0xC3000003, smc_check_status},
|
||||
{0xC3000404, smc_get_result},
|
||||
{0xC3000E05, smc_exp_mod},
|
||||
@@ -114,14 +120,20 @@ static smc_table_entry_t g_smc_priv_table[SMC_PRIV_HANDLERS] = {
|
||||
{0xC4000001, smc_cpu_suspend},
|
||||
{0x84000002, smc_cpu_off},
|
||||
{0xC4000003, smc_cpu_on},
|
||||
{0xC3000004, smc_get_config}, /* NOTE: Same function as for USER */
|
||||
{0xC3000004, smc_get_config_priv},
|
||||
{0xC3000005, smc_get_random_bytes_for_priv},
|
||||
{0xC3000006, smc_panic},
|
||||
{0xC3000007, smc_configure_carveout},
|
||||
{0xC3000008, smc_read_write_register}
|
||||
};
|
||||
|
||||
static smc_table_t g_smc_tables[2] = {
|
||||
/* This is a table used for atmosphere-specific SMCs. */
|
||||
static smc_table_entry_t g_smc_ams_table[SMC_AMS_HANDLERS] = {
|
||||
{0, NULL},
|
||||
{0xF0000201, smc_ams_iram_copy},
|
||||
};
|
||||
|
||||
static smc_table_t g_smc_tables[SMC_HANDLER_COUNT + 1] = {
|
||||
{ /* SMC_HANDLER_USER */
|
||||
g_smc_user_table,
|
||||
SMC_USER_HANDLERS
|
||||
@@ -129,6 +141,10 @@ static smc_table_t g_smc_tables[2] = {
|
||||
{ /* SMC_HANDLER_PRIV */
|
||||
g_smc_priv_table,
|
||||
SMC_PRIV_HANDLERS
|
||||
},
|
||||
{ /* SMC_HANDLER_AMS */
|
||||
g_smc_ams_table,
|
||||
SMC_AMS_HANDLERS
|
||||
}
|
||||
};
|
||||
|
||||
@@ -145,20 +161,21 @@ void set_suspend_for_debug(void) {
|
||||
|
||||
void set_version_specific_smcs(void) {
|
||||
switch (exosphere_get_target_firmware()) {
|
||||
case EXOSPHERE_TARGET_FIRMWARE_100:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_100:
|
||||
/* 1.0.0 doesn't have ConfigureCarveout or ReadWriteRegister. */
|
||||
g_smc_priv_table[7].handler = NULL;
|
||||
g_smc_priv_table[8].handler = NULL;
|
||||
/* 1.0.0 doesn't have UnwrapAesWrappedTitlekey. */
|
||||
g_smc_user_table[0x12].handler = NULL;
|
||||
break;
|
||||
case EXOSPHERE_TARGET_FIRMWARE_200:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_300:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_400:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_200:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_300:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_400:
|
||||
/* Do nothing. */
|
||||
break;
|
||||
case EXOSPHERE_TARGET_FIRMWARE_500:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_600:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_500:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_600:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_620:
|
||||
/* No more LoadSecureExpModKey. */
|
||||
g_smc_user_table[0xE].handler = NULL;
|
||||
g_smc_user_table[0xC].id = 0xC300D60C;
|
||||
@@ -227,19 +244,25 @@ void clear_smc_callback(uint64_t key) {
|
||||
_Atomic uint64_t num_smcs_called = 0;
|
||||
|
||||
void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
||||
unsigned char smc_id;
|
||||
unsigned char smc_id, call_range;
|
||||
unsigned int result;
|
||||
unsigned int (*smc_handler)(smc_args_t *args);
|
||||
|
||||
/* Validate top-level handler. */
|
||||
if (handler_id != SMC_HANDLER_USER && handler_id != SMC_HANDLER_PRIV) {
|
||||
if (handler_id >= SMC_HANDLER_COUNT) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
/* Validate core is appropriate for handler. */
|
||||
if (handler_id == SMC_HANDLER_USER && get_core_id() != 3) {
|
||||
/* USER SMCs must be called via svcCallSecureMonitor on core 3 (where spl runs) */
|
||||
generic_panic();
|
||||
/* If user-handler, detect if talking to Atmosphere/validate calling core. */
|
||||
if (handler_id == SMC_HANDLER_USER) {
|
||||
if ((call_range = (unsigned char)((args->X[0] >> 24) & 0x3F)) == SMC_CALL_RANGE_TRUSTED_APP) {
|
||||
/* Nintendo's SMCs are all OEM-specific. */
|
||||
/* Pending a reason not to, we will treat Trusted Application SMCs as intended to talk to Atmosphere. */
|
||||
handler_id = SMC_HANDLER_AMS;
|
||||
} else if (get_core_id() != 3) {
|
||||
/* USER SMCs must be called via svcCallSecureMonitor on core 3 (where spl runs) */
|
||||
generic_panic();
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate sub-handler index */
|
||||
@@ -279,7 +302,7 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
||||
#endif
|
||||
|
||||
#if DEBUG_PANIC_ON_FAILURE
|
||||
if (args->X[0] && (!is_aes_kek || args->X[3] <= EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG))
|
||||
if (args->X[0] && (!is_aes_kek || args->X[3] <= ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG))
|
||||
{
|
||||
MAKE_REG32(get_iram_address_for_debug() + 0x4FF0) = handler_id;
|
||||
MAKE_REG32(get_iram_address_for_debug() + 0x4FF4) = smc_id;
|
||||
@@ -328,15 +351,15 @@ uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *),
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t smc_set_config(smc_args_t *args) {
|
||||
uint32_t smc_set_config_user(smc_args_t *args) {
|
||||
/* Actual value presumed in X3 on hardware. */
|
||||
return configitem_set((ConfigItem)args->X[1], args->X[3]);
|
||||
return configitem_set(false, (ConfigItem)args->X[1], args->X[3]);
|
||||
}
|
||||
|
||||
uint32_t smc_get_config(smc_args_t *args) {
|
||||
uint32_t smc_get_config_user(smc_args_t *args) {
|
||||
uint64_t out_item = 0;
|
||||
uint32_t result;
|
||||
result = configitem_get((ConfigItem)args->X[1], &out_item);
|
||||
result = configitem_get(false, (ConfigItem)args->X[1], &out_item);
|
||||
args->X[1] = out_item;
|
||||
return result;
|
||||
}
|
||||
@@ -533,6 +556,14 @@ uint32_t smc_cpu_suspend(smc_args_t *args) {
|
||||
return smc_wrapper_sync(args, cpu_suspend_wrapper);
|
||||
}
|
||||
|
||||
uint32_t smc_get_config_priv(smc_args_t *args) {
|
||||
uint64_t out_item = 0;
|
||||
uint32_t result;
|
||||
result = configitem_get(true, (ConfigItem)args->X[1], &out_item);
|
||||
args->X[1] = out_item;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t smc_get_random_bytes_for_priv(smc_args_t *args) {
|
||||
/* This is an interesting SMC. */
|
||||
/* The kernel must NEVER be unable to get random bytes, if it needs them */
|
||||
@@ -585,7 +616,7 @@ uint32_t smc_read_write_register(smc_args_t *args) {
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400 && MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) <= address &&
|
||||
} else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400 && MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) <= address &&
|
||||
address < MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) + MMIO_GET_DEVICE_SIZE(MMIO_DEVID_MC)) {
|
||||
/* Memory Controller RW supported only on 4.0.0+ */
|
||||
const uint8_t mc_whitelist[0x68] = {
|
||||
@@ -658,7 +689,7 @@ uint32_t smc_configure_carveout(smc_args_t *args) {
|
||||
}
|
||||
|
||||
/* Configuration is one-shot, and cannot be done multiple times. */
|
||||
if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_300) {
|
||||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_300) {
|
||||
if (g_configured_carveouts[carveout_id]) {
|
||||
return 2;
|
||||
}
|
||||
@@ -674,3 +705,7 @@ uint32_t smc_panic(smc_args_t *args) {
|
||||
uint32_t color = ((args->X[1] & 0xF) << 8) | ((args->X[1] & 0xF0)) | ((args->X[1] & 0xF00) >> 8);
|
||||
panic((color << 20) | 0x40);
|
||||
}
|
||||
|
||||
uint32_t smc_ams_iram_copy(smc_args_t *args) {
|
||||
return smc_wrapper_sync(args, ams_iram_copy);
|
||||
}
|
||||
|
||||
@@ -19,8 +19,19 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SMC_HANDLER_USER 0
|
||||
#define SMC_HANDLER_PRIV 1
|
||||
#define SMC_HANDLER_USER 0
|
||||
#define SMC_HANDLER_PRIV 1
|
||||
#define SMC_HANDLER_COUNT 2
|
||||
|
||||
#define SMC_HANDLER_AMS (SMC_HANDLER_COUNT)
|
||||
|
||||
#define SMC_CALL_RANGE_ARM_ARCH 0
|
||||
#define SMC_CALL_RANGE_CPU 1
|
||||
#define SMC_CALL_RANGE_SIP 2
|
||||
#define SMC_CALL_RANGE_OEM 3
|
||||
#define SMC_CALL_RANGE_STANDARD 4
|
||||
|
||||
#define SMC_CALL_RANGE_TRUSTED_APP 0x30
|
||||
|
||||
typedef struct {
|
||||
uint64_t X[8];
|
||||
|
||||
@@ -42,13 +42,14 @@ static uint8_t g_rsausecase_to_cryptousecase[5] = {1, 2, 3, 5, 6};
|
||||
|
||||
static bool is_user_keyslot_valid(unsigned int keyslot) {
|
||||
switch (exosphere_get_target_firmware()) {
|
||||
case EXOSPHERE_TARGET_FIRMWARE_100:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_200:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_300:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_400:
|
||||
case EXOSPHERE_TARGET_FIRMWARE_500:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_100:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_200:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_300:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_400:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_500:
|
||||
return keyslot <= 3;
|
||||
case EXOSPHERE_TARGET_FIRMWARE_600:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_600:
|
||||
case ATMOSPHERE_TARGET_FIRMWARE_620:
|
||||
default:
|
||||
return keyslot <= 5;
|
||||
}
|
||||
@@ -156,7 +157,7 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
|
||||
uint8_t mask_id = (uint8_t)((packed_options >> 1) & 3);
|
||||
|
||||
/* Switches the output based on how it will be used. */
|
||||
uint8_t usecase = (uint8_t)((packed_options >> 5) & (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500 ? 7 : 3));
|
||||
uint8_t usecase = (uint8_t)((packed_options >> 5) & (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500 ? 7 : 3));
|
||||
|
||||
/* Switched the output based on whether it should be console unique. */
|
||||
bool is_personalized = (int)(packed_options & 1);
|
||||
@@ -164,9 +165,9 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
|
||||
bool is_recovery_boot = configitem_is_recovery_boot();
|
||||
|
||||
/* 5.0.0+ Bounds checking. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (is_personalized) {
|
||||
if (master_key_rev > MASTERKEY_REVISION_600_CURRENT || ((1 << (master_key_rev + 1)) & 0x73) == 0) {
|
||||
if (master_key_rev >= MASTERKEY_REVISION_MAX || (MASTERKEY_REVISION_300 <= master_key_rev && master_key_rev < MASTERKEY_REVISION_400_410)) {
|
||||
return 2;
|
||||
}
|
||||
if (mask_id > 3 || usecase >= CRYPTOUSECASE_MAX_5X) {
|
||||
@@ -218,9 +219,9 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
|
||||
unsigned int keyslot;
|
||||
if (is_personalized) {
|
||||
/* Behavior changed in 4.0.0, and in 5.0.0. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
keyslot = devkey_get_keyslot(master_key_rev);
|
||||
} else if (exosphere_get_target_firmware() == EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
} else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (master_key_rev >= 1) {
|
||||
keyslot = KEYSLOT_SWITCH_DEVICEKEY; /* New device key, 4.x. */
|
||||
} else {
|
||||
@@ -293,7 +294,7 @@ uint32_t user_crypt_aes(smc_args_t *args) {
|
||||
uint32_t keyslot = args->X[1] & 3;
|
||||
uint32_t mode = (args->X[1] >> 4) & 3;
|
||||
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_600) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
|
||||
keyslot = args->X[1] & 7;
|
||||
}
|
||||
|
||||
@@ -309,7 +310,7 @@ uint32_t user_crypt_aes(smc_args_t *args) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
/* Disallow dma lists outside of safe range. */
|
||||
if (in_ll_paddr - 0x80000000 >= 0x3FF7F5) {
|
||||
return 2;
|
||||
@@ -357,7 +358,7 @@ uint32_t user_generate_specific_aes_key(smc_args_t *args) {
|
||||
if (master_key_rev > 0) {
|
||||
master_key_rev -= 1;
|
||||
}
|
||||
if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
master_key_rev = 0;
|
||||
}
|
||||
|
||||
@@ -373,9 +374,9 @@ uint32_t user_generate_specific_aes_key(smc_args_t *args) {
|
||||
unsigned int keyslot;
|
||||
|
||||
/* Behavior changed in 5.0.0. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
keyslot = devkey_get_keyslot(master_key_rev);
|
||||
} else if (exosphere_get_target_firmware() == EXOSPHERE_TARGET_FIRMWARE_400) {
|
||||
} else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
if (master_key_rev >= 1) {
|
||||
keyslot = KEYSLOT_SWITCH_DEVICEKEY; /* New device key, 4.x. */
|
||||
} else {
|
||||
@@ -454,7 +455,7 @@ uint32_t user_load_rsa_oaep_key(smc_args_t *args) {
|
||||
upage_ref_t page_ref;
|
||||
|
||||
/* This function no longer exists in 5.x+. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
@@ -503,7 +504,7 @@ uint32_t user_decrypt_rsa_private_key(smc_args_t *args) {
|
||||
upage_ref_t page_ref;
|
||||
|
||||
/* This function no longer exists in 5.x+. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
@@ -561,7 +562,7 @@ uint32_t user_load_secure_exp_mod_key(smc_args_t *args) {
|
||||
upage_ref_t page_ref;
|
||||
|
||||
/* This function no longer exists in 5.x+. */
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
@@ -617,7 +618,7 @@ uint32_t user_secure_exp_mod(smc_args_t *args) {
|
||||
void *user_modulus = (void *)args->X[2];
|
||||
|
||||
unsigned int exponent_id = 1;
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
switch (args->X[3]) {
|
||||
case 0:
|
||||
exponent_id = 1;
|
||||
@@ -663,7 +664,7 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
|
||||
unsigned int option = (unsigned int)args->X[7];
|
||||
unsigned int master_key_rev;
|
||||
unsigned int titlekey_type;
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_600) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
|
||||
master_key_rev = option & 0x3F;
|
||||
titlekey_type = (option >> 6) & 1;
|
||||
} else {
|
||||
@@ -675,7 +676,7 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
|
||||
master_key_rev -= 1;
|
||||
}
|
||||
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_300) {
|
||||
if (master_key_rev >= MASTERKEY_REVISION_MAX) {
|
||||
return 2;
|
||||
}
|
||||
@@ -740,7 +741,7 @@ uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args) {
|
||||
if (master_key_rev > 0) {
|
||||
master_key_rev -= 1;
|
||||
}
|
||||
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300) {
|
||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_300) {
|
||||
if (master_key_rev >= MASTERKEY_REVISION_MAX) {
|
||||
return 2;
|
||||
}
|
||||
@@ -836,7 +837,7 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
|
||||
upage_ref_t page_ref;
|
||||
|
||||
/* This function only exists in 5.x+. */
|
||||
if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_500) {
|
||||
if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,10 +27,11 @@ static inline uintptr_t get_timers_base(void) {
|
||||
}
|
||||
|
||||
#define TIMERS_BASE (get_timers_base())
|
||||
|
||||
#define MAKE_TIMERS_REG(n) MAKE_REG32(TIMERS_BASE + n)
|
||||
|
||||
#define TIMERUS_CNTR_1US_0 MAKE_REG32(TIMERS_BASE + 0x10)
|
||||
#define TIMERUS_CNTR_1US_0 MAKE_TIMERS_REG(0x10)
|
||||
#define SHARED_INTR_STATUS_0 MAKE_TIMERS_REG(0x1A0)
|
||||
#define SHARED_TIMER_SECURE_CFG_0 MAKE_TIMERS_REG(0x1A4)
|
||||
|
||||
typedef struct {
|
||||
uint32_t CONFIG;
|
||||
@@ -41,7 +42,7 @@ typedef struct {
|
||||
|
||||
#define GET_WDT(n) ((volatile watchdog_timers_t *)(TIMERS_BASE + 0x100 + 0x20 * n))
|
||||
#define WDT_REBOOT_PATTERN 0xC45A
|
||||
#define GET_WDT_REBOOT_CFG_REG(n) MAKE_REG32(TIMERS_BASE + 0x60 + 0x8*n)
|
||||
#define GET_WDT_REBOOT_CFG_REG(n) MAKE_REG32(TIMERS_BASE + 0x60 + 0x8 * n)
|
||||
|
||||
void wait(uint32_t microseconds);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user