Compare commits
163 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
814c9d1cfb | ||
|
|
9d7b548ce0 | ||
|
|
d779eea009 | ||
|
|
3038612774 | ||
|
|
59be817bb8 | ||
|
|
b965e3f335 | ||
|
|
43c0e39c34 | ||
|
|
0d8bde6079 | ||
|
|
38f942adf5 | ||
|
|
145ee8fcc8 | ||
|
|
48772307bf | ||
|
|
2619ccad0c | ||
|
|
6d5d97cfcd | ||
|
|
846f610fff | ||
|
|
2e8f06ef44 | ||
|
|
5fbd728962 | ||
|
|
11ec6a6912 | ||
|
|
b89f0e45ec | ||
|
|
18d998034d | ||
|
|
27994bb306 | ||
|
|
3e2ec256ab | ||
|
|
bf5bbfbcef | ||
|
|
d10621e832 | ||
|
|
d3b697fd1d | ||
|
|
daa7f5db79 | ||
|
|
4adc0e4096 | ||
|
|
8e3c34ea89 | ||
|
|
a85e20bcea | ||
|
|
879f8a5147 | ||
|
|
f78653d815 | ||
|
|
3c7c1fbd8a | ||
|
|
8efdd04fcd | ||
|
|
623b5f4eb9 | ||
|
|
af352e4f7f | ||
|
|
2866cb5fe6 | ||
|
|
b5becba8ff | ||
|
|
36c47a0014 | ||
|
|
0b0fdc5c58 | ||
|
|
5a15d62b8b | ||
|
|
d0404f3cc9 | ||
|
|
2ae298de24 | ||
|
|
a2d2b1b346 | ||
|
|
06e4b94674 | ||
|
|
f1a9dd8a98 | ||
|
|
0a18c63f24 | ||
|
|
f9a199557c | ||
|
|
0fdbdb1f4d | ||
|
|
e734b23f11 | ||
|
|
de1e6c9705 | ||
|
|
71b220a4e9 | ||
|
|
5448332009 | ||
|
|
d3bafc5b3b | ||
|
|
2c9e1a814c | ||
|
|
df012e6e21 | ||
|
|
2420b26981 | ||
|
|
c1d68d7f0d | ||
|
|
7cead4b620 | ||
|
|
27202b2fab | ||
|
|
1556a92a38 | ||
|
|
206b1a1b57 | ||
|
|
a26e157579 | ||
|
|
9578622abf | ||
|
|
d4f99ddb4d | ||
|
|
0105455086 | ||
|
|
28717bfd27 | ||
|
|
71fd69eb5a | ||
|
|
9d7b52e2d4 | ||
|
|
255e46e6d2 | ||
|
|
7472bc1c7f | ||
|
|
3c7ece2f8b | ||
|
|
a7e89c6dbb | ||
|
|
b0cae74bb9 | ||
|
|
889ea5e5aa | ||
|
|
7e6ff1f327 | ||
|
|
ea49c2ccd1 | ||
|
|
d484872a73 | ||
|
|
6ee525201c | ||
|
|
5ac7ae7edb | ||
|
|
0c590eb768 | ||
|
|
bd40d4f237 | ||
|
|
788436b4a3 | ||
|
|
2bb77237bc | ||
|
|
33827fe3a3 | ||
|
|
48b0b2fc46 | ||
|
|
4f29eedfe9 | ||
|
|
66372e2b2e | ||
|
|
2bae1ad116 | ||
|
|
bbdc643b6d | ||
|
|
a66fcde0ee | ||
|
|
7835486a4d | ||
|
|
90367aea0d | ||
|
|
16c638756c | ||
|
|
b08a97d883 | ||
|
|
746dbfe018 | ||
|
|
733f2b3cdd | ||
|
|
ad64cb5212 | ||
|
|
b1a9e8d0df | ||
|
|
4f9838df3c | ||
|
|
f4ca2c02a7 | ||
|
|
e1391d4162 | ||
|
|
8d9c51f204 | ||
|
|
c10ba67973 | ||
|
|
55610694c8 | ||
|
|
8764d94fd9 | ||
|
|
5228768841 | ||
|
|
9c68bea16c | ||
|
|
5484740cab | ||
|
|
421324b498 | ||
|
|
37e065fa2d | ||
|
|
b758e3fc55 | ||
|
|
393596ef9a | ||
|
|
02d4c97c6d | ||
|
|
2c5ef434f0 | ||
|
|
122f3e4403 | ||
|
|
ea3ebbaa7d | ||
|
|
1636668762 | ||
|
|
c6b9a0c4bf | ||
|
|
93a218abeb | ||
|
|
d7a06057eb | ||
|
|
8cb77ac136 | ||
|
|
4059dc6187 | ||
|
|
15773e4755 | ||
|
|
4f455dacf4 | ||
|
|
0b22af1206 | ||
|
|
ae2fa2fa60 | ||
|
|
6abd756e0c | ||
|
|
535e49a38d | ||
|
|
fbb5730369 | ||
|
|
e5d62025d3 | ||
|
|
89c6fc6437 | ||
|
|
799c158b86 | ||
|
|
8d16d2152b | ||
|
|
635ae4e3da | ||
|
|
59140d8dfa | ||
|
|
2cb8aadafc | ||
|
|
aa0826bb70 | ||
|
|
8bd2a9a23b | ||
|
|
2f959785e1 | ||
|
|
88a86a3363 | ||
|
|
0c7827104f | ||
|
|
c8ed190e5c | ||
|
|
f4dcd1db9b | ||
|
|
bd341d5c00 | ||
|
|
add18d868f | ||
|
|
609a302e16 | ||
|
|
e07011be32 | ||
|
|
bb223eb5ae | ||
|
|
73d904036d | ||
|
|
542833866e | ||
|
|
89c484414b | ||
|
|
fe2dd671fb | ||
|
|
8abee1bdaa | ||
|
|
78a730ddf6 | ||
|
|
a750e55f75 | ||
|
|
c62c4846fc | ||
|
|
8db5b01507 | ||
|
|
a6e405c988 | ||
|
|
6613fda4b1 | ||
|
|
a18a6e87df | ||
|
|
93d83c5bb9 | ||
|
|
6ee8720028 | ||
|
|
600d68bd1a | ||
|
|
0c3a294cbe |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
config_templates/hbl_html/accessible-urls/accessible-urls.txt text eol=lf
|
||||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: ReSwitched Discord
|
||||||
|
url: https://discordapp.com/invite/DThbZ7z
|
||||||
|
about: Please ask questions here, instead of making GitHub issues.
|
||||||
7
.github/ISSUE_TEMPLATE/question.md
vendored
7
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
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
|
|
||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
|||||||
[submodule "common/include/boost"]
|
|
||||||
path = common/include/boost
|
|
||||||
url = https://github.com/Atmosphere-NX/ext-boost.git
|
|
||||||
|
|||||||
60
Makefile
60
Makefile
@@ -7,7 +7,7 @@ ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
|||||||
AMSREV := $(AMSREV)-dirty
|
AMSREV := $(AMSREV)-dirty
|
||||||
endif
|
endif
|
||||||
|
|
||||||
COMPONENTS := fusee stratosphere exosphere thermosphere troposphere
|
COMPONENTS := fusee stratosphere mesosphere exosphere thermosphere troposphere libraries
|
||||||
|
|
||||||
all: $(COMPONENTS)
|
all: $(COMPONENTS)
|
||||||
|
|
||||||
@@ -17,30 +17,36 @@ thermosphere:
|
|||||||
exosphere: thermosphere
|
exosphere: thermosphere
|
||||||
$(MAKE) -C exosphere all
|
$(MAKE) -C exosphere all
|
||||||
|
|
||||||
stratosphere: exosphere
|
stratosphere: exosphere libraries
|
||||||
$(MAKE) -C stratosphere all
|
$(MAKE) -C stratosphere all
|
||||||
|
|
||||||
|
mesosphere: exosphere libraries
|
||||||
|
$(MAKE) -C mesosphere all
|
||||||
|
|
||||||
troposphere: stratosphere
|
troposphere: stratosphere
|
||||||
$(MAKE) -C troposphere all
|
$(MAKE) -C troposphere all
|
||||||
|
|
||||||
sept: exosphere
|
sept: exosphere
|
||||||
$(MAKE) -C sept all
|
$(MAKE) -C sept all
|
||||||
|
|
||||||
fusee: exosphere stratosphere sept
|
fusee: exosphere mesosphere stratosphere sept
|
||||||
$(MAKE) -C $@ all
|
$(MAKE) -C $@ all
|
||||||
|
|
||||||
|
libraries:
|
||||||
|
$(MAKE) -C libraries all
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C fusee clean
|
$(MAKE) -C fusee clean
|
||||||
rm -rf out
|
rm -rf out
|
||||||
|
|
||||||
dist: all
|
dist: all
|
||||||
$(eval MAJORVER = $(shell grep '\ATMOSPHERE_RELEASE_VERSION_MAJOR\b' common/include/atmosphere/version.h \
|
$(eval MAJORVER = $(shell grep 'define ATMOSPHERE_RELEASE_VERSION_MAJOR\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
|
||||||
| tr -s [:blank:] \
|
| tr -s [:blank:] \
|
||||||
| cut -d' ' -f3))
|
| cut -d' ' -f3))
|
||||||
$(eval MINORVER = $(shell grep '\ATMOSPHERE_RELEASE_VERSION_MINOR\b' common/include/atmosphere/version.h \
|
$(eval MINORVER = $(shell grep 'define ATMOSPHERE_RELEASE_VERSION_MINOR\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
|
||||||
| tr -s [:blank:] \
|
| tr -s [:blank:] \
|
||||||
| cut -d' ' -f3))
|
| cut -d' ' -f3))
|
||||||
$(eval MICROVER = $(shell grep '\ATMOSPHERE_RELEASE_VERSION_MICRO\b' common/include/atmosphere/version.h \
|
$(eval MICROVER = $(shell grep 'define ATMOSPHERE_RELEASE_VERSION_MICRO\b' libraries/libvapours/include/vapours/ams/ams_api_version.h \
|
||||||
| tr -s [:blank:] \
|
| tr -s [:blank:] \
|
||||||
| cut -d' ' -f3))
|
| cut -d' ' -f3))
|
||||||
$(eval AMSVER = $(MAJORVER).$(MINORVER).$(MICROVER)-$(AMSREV))
|
$(eval AMSVER = $(MAJORVER).$(MINORVER).$(MICROVER)-$(AMSREV))
|
||||||
@@ -50,12 +56,15 @@ dist: all
|
|||||||
mkdir atmosphere-$(AMSVER)/atmosphere
|
mkdir atmosphere-$(AMSVER)/atmosphere
|
||||||
mkdir atmosphere-$(AMSVER)/sept
|
mkdir atmosphere-$(AMSVER)/sept
|
||||||
mkdir atmosphere-$(AMSVER)/switch
|
mkdir atmosphere-$(AMSVER)/switch
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/010000000000000D
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000037
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036
|
||||||
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
|
||||||
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/config_templates
|
||||||
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/config
|
||||||
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
||||||
cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin
|
cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin
|
||||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
||||||
@@ -64,20 +73,21 @@ dist: all
|
|||||||
cp sept/sept-secondary/sept-secondary.bin atmosphere-$(AMSVER)/sept/sept-secondary.bin
|
cp sept/sept-secondary/sept-secondary.bin atmosphere-$(AMSVER)/sept/sept-secondary.bin
|
||||||
cp sept/sept-secondary/sept-secondary_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_00.enc
|
cp sept/sept-secondary/sept-secondary_00.enc atmosphere-$(AMSVER)/sept/sept-secondary_00.enc
|
||||||
cp sept/sept-secondary/sept-secondary_01.enc atmosphere-$(AMSVER)/sept/sept-secondary_01.enc
|
cp sept/sept-secondary/sept-secondary_01.enc atmosphere-$(AMSVER)/sept/sept-secondary_01.enc
|
||||||
cp common/defaults/BCT.ini atmosphere-$(AMSVER)/atmosphere/BCT.ini
|
cp config_templates/BCT.ini atmosphere-$(AMSVER)/atmosphere/config/BCT.ini
|
||||||
cp common/defaults/loader.ini atmosphere-$(AMSVER)/atmosphere/loader.ini
|
cp config_templates/override_config.ini atmosphere-$(AMSVER)/atmosphere/config_templates/override_config.ini
|
||||||
cp common/defaults/system_settings.ini atmosphere-$(AMSVER)/atmosphere/system_settings.ini
|
cp config_templates/system_settings.ini atmosphere-$(AMSVER)/atmosphere/config_templates/system_settings.ini
|
||||||
cp -r common/defaults/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches
|
cp -r config_templates/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches
|
||||||
cp -r common/defaults/hbl_html atmosphere-$(AMSVER)/atmosphere/hbl_html
|
cp -r config_templates/hbl_html atmosphere-$(AMSVER)/atmosphere/hbl_html
|
||||||
cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/atmosphere/titles/010000000000000D/exefs.nsp
|
cp stratosphere/boot2/boot2.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008/exefs.nsp
|
||||||
cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/exefs.nsp
|
cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D/exefs.nsp
|
||||||
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034/exefs.nsp
|
cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/exefs.nsp
|
||||||
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036/exefs.nsp
|
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034/exefs.nsp
|
||||||
cp stratosphere/ro/ro.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000037/exefs.nsp
|
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036/exefs.nsp
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/flags
|
cp stratosphere/ro/ro.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/exefs.nsp
|
||||||
touch atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/flags/boot2.flag
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/flags
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000037/flags
|
touch atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/flags/boot2.flag
|
||||||
touch atmosphere-$(AMSVER)/atmosphere/titles/0100000000000037/flags/boot2.flag
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/flags
|
||||||
|
touch atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/flags/boot2.flag
|
||||||
cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro
|
cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro
|
||||||
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
|
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
|
||||||
rm -r atmosphere-$(AMSVER)
|
rm -r atmosphere-$(AMSVER)
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
[hbl_config]
|
|
||||||
title_id=010000000000100D
|
|
||||||
override_any_app=true
|
|
||||||
path=atmosphere/hbl.nsp
|
|
||||||
override_key=R
|
|
||||||
|
|
||||||
[default_config]
|
|
||||||
override_key=!L
|
|
||||||
cheat_enable_key=!L
|
|
||||||
Submodule common/include/boost deleted from fc6429e463
@@ -7,11 +7,13 @@ stage2_entrypoint = 0xF0000000
|
|||||||
|
|
||||||
[exosphere]
|
[exosphere]
|
||||||
; Note: Disabling debugmode will cause parts of ams.tma to not work, in the future.
|
; Note: Disabling debugmode will cause parts of ams.tma to not work, in the future.
|
||||||
debugmode = 1
|
debugmode = 1
|
||||||
debugmode_user = 0
|
debugmode_user = 0
|
||||||
; Note: Disabling usermode exception handlers will cause atmosphere to not fail gracefully under error conditions.
|
; Note: Disabling usermode exception handlers will cause atmosphere to not fail gracefully under error conditions.
|
||||||
; Support will not be provided to users who disable these. If you do not know what you are doing, leave them on.
|
; Support will not be provided to users who disable these. If you do not know what you are doing, leave them on.
|
||||||
disable_user_exception_handlers = 0
|
disable_user_exception_handlers = 0
|
||||||
|
; Note: It's currently unknown what effects enabling the usermode PMU register access may have on official code.
|
||||||
|
enable_user_pmu_access = 0
|
||||||
|
|
||||||
[stratosphere]
|
[stratosphere]
|
||||||
; To force-enable nogc, add nogc = 1
|
; To force-enable nogc, add nogc = 1
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
19
config_templates/override_config.ini
Normal file
19
config_templates/override_config.ini
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[hbl_config]
|
||||||
|
; Program Specific Config
|
||||||
|
; Up to 8 program-specific configurations can be set.
|
||||||
|
; These use `program_id_#` and `override_key_#`
|
||||||
|
; where # is in range [0,7].
|
||||||
|
; program_id_0=010000000000100D
|
||||||
|
; override_key_0=!R
|
||||||
|
|
||||||
|
; Any Application Config
|
||||||
|
; Note that this will only apply to program IDs that
|
||||||
|
; are both applications and not specified above
|
||||||
|
; by a program specific config.
|
||||||
|
; override_any_app=true
|
||||||
|
; override_any_app_key=R
|
||||||
|
; path=atmosphere/hbl.nsp
|
||||||
|
|
||||||
|
[default_config]
|
||||||
|
; override_key=!L
|
||||||
|
; cheat_enable_key=!L
|
||||||
@@ -1,40 +1,49 @@
|
|||||||
; Disable uploading error reports to Nintendo
|
; Disable uploading error reports to Nintendo
|
||||||
[eupld]
|
[eupld]
|
||||||
upload_enabled = u8!0x0
|
; upload_enabled = u8!0x0
|
||||||
; Enable USB 3.0 superspeed for homebrew
|
|
||||||
[usb]
|
|
||||||
usb30_force_enabled = u8!0x0
|
|
||||||
; Control whether RO should ease its validation of NROs.
|
; Control whether RO should ease its validation of NROs.
|
||||||
; (note: this is normally not necessary, and ips patches can be used.)
|
; (note: this is normally not necessary, and ips patches can be used.)
|
||||||
[ro]
|
[ro]
|
||||||
ease_nro_restriction = u8!0x0
|
; ease_nro_restriction = u8!0x0
|
||||||
; Atmosphere custom settings
|
; Atmosphere custom settings
|
||||||
[atmosphere]
|
[atmosphere]
|
||||||
; Reboot from fatal automatically after some number of milliseconds.
|
; Reboot from fatal automatically after some number of milliseconds.
|
||||||
; If field is not present or 0, fatal will wait indefinitely for user input.
|
; If field is not present or 0, fatal will wait indefinitely for user input.
|
||||||
fatal_auto_reboot_interval = u64!0x0
|
; fatal_auto_reboot_interval = u64!0x0
|
||||||
; Make the power menu's "reboot" button reboot to payload.
|
; Make the power menu's "reboot" button reboot to payload.
|
||||||
; Set to "normal" for normal reboot, "rcm" for rcm reboot.
|
; Set to "normal" for normal reboot, "rcm" for rcm reboot.
|
||||||
power_menu_reboot_function = str!payload
|
; power_menu_reboot_function = str!payload
|
||||||
; Controls whether dmnt cheats should be toggled on or off by
|
; Controls whether dmnt cheats should be toggled on or off by
|
||||||
; default. 1 = toggled on by default, 0 = toggled off by default.
|
; default. 1 = toggled on by default, 0 = toggled off by default.
|
||||||
dmnt_cheats_enabled_by_default = u8!0x1
|
; dmnt_cheats_enabled_by_default = u8!0x1
|
||||||
; Controls whether dmnt should always save cheat toggle state
|
; Controls whether dmnt should always save cheat toggle state
|
||||||
; for restoration on new game launch. 1 = always save toggles,
|
; for restoration on new game launch. 1 = always save toggles,
|
||||||
; 0 = only save toggles if toggle file exists.
|
; 0 = only save toggles if toggle file exists.
|
||||||
dmnt_always_save_cheat_toggles = u8!0x0
|
; dmnt_always_save_cheat_toggles = u8!0x0
|
||||||
|
; Enable writing to BIS partitions for HBL.
|
||||||
|
; This is probably undesirable for normal usage.
|
||||||
|
; enable_hbl_bis_write = u8!0x0
|
||||||
|
; Enable reading the CAL0 partition for HBL.
|
||||||
|
; This is probably undesirable for normal usage.
|
||||||
|
; enable_hbl_cal_read = u8!0x0
|
||||||
; Controls whether fs.mitm should redirect save files
|
; Controls whether fs.mitm should redirect save files
|
||||||
; to directories on the sd card.
|
; to directories on the sd card.
|
||||||
; 0 = Do not redirect, 1 = Redirect.
|
; 0 = Do not redirect, 1 = Redirect.
|
||||||
; NOTE: EXPERIMENTAL
|
; NOTE: EXPERIMENTAL
|
||||||
; If you do not know what you are doing, do not touch this yet.
|
; If you do not know what you are doing, do not touch this yet.
|
||||||
fsmitm_redirect_saves_to_sd = u8!0x0
|
; fsmitm_redirect_saves_to_sd = u8!0x0
|
||||||
|
; Controls whether to enable the deprecated hid mitm
|
||||||
|
; to fix compatibility with old homebrew.
|
||||||
|
; 0 = Do not enable, 1 = Enable.
|
||||||
|
; Please note this setting may be removed in a
|
||||||
|
; future release of Atmosphere.
|
||||||
|
; enable_deprecated_hid_mitm = u8!0x0
|
||||||
[hbloader]
|
[hbloader]
|
||||||
; Controls the size of the homebrew heap when running as applet.
|
; Controls the size of the homebrew heap when running as applet.
|
||||||
; If set to zero, all available applet memory is used as heap.
|
; If set to zero, all available applet memory is used as heap.
|
||||||
; The default is zero.
|
; The default is zero.
|
||||||
applet_heap_size = u64!0x0
|
; applet_heap_size = u64!0x0
|
||||||
; Controls the amount of memory to reserve when running as applet
|
; Controls the amount of memory to reserve when running as applet
|
||||||
; for usage by other applets. This setting has no effect if
|
; for usage by other applets. This setting has no effect if
|
||||||
; applet_heap_size is non-zero. The default is zero.
|
; applet_heap_size is non-zero. The default is 0x8600000.
|
||||||
applet_heap_reservation_size = u64!0x8000000
|
; applet_heap_reservation_size = u64!0x8600000
|
||||||
@@ -1,4 +1,149 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
## 0.10.2
|
||||||
|
+ hbl configuration was made more flexible.
|
||||||
|
+ Up to eight specific program ids can now be specified to have their own override keys.
|
||||||
|
+ This allows designating both the album applet and a specific game as hbl by default as desired.
|
||||||
|
+ Configuration targeting a specific program is now mutually exclusive with override-any-app for that program.
|
||||||
|
+ This fixes unintuitive behavior when override key differed for an application specific program.
|
||||||
|
+ Loader's external content fileystem support was fixed (thanks @misson20000!).
|
||||||
|
+ KernelLdr was reimplemented.
|
||||||
|
+ This is the first step towards developing mesosphere, Atmosphere's planned reimplementation of the Switch's Kernel.
|
||||||
|
+ The typical user won't notice anything different, as there are no extensions, but a lot of groundwork was laid for future development.
|
||||||
|
+ Improvements were made to the way Atmosphere's buildsystem detects source code files.
|
||||||
|
+ This significantly reduces compilation time (saving >30 seconds) on the machine that builds official releases.
|
||||||
|
+ Certain device code was cleaned up and made more correct in fusee/sept/exosphere (thanks @hexkyz!).
|
||||||
|
+ A number of changes were made to the way fs.mitm builds images when providing a layeredfs romfs.
|
||||||
|
+ Some games (Resident Evil 6, Football Manager 2020 Touch, possibly others) have enormous numbers of files.
|
||||||
|
+ Attempting to create a layeredfs mod for these games actually caused fs.mitm to run out of memory, causing a fatal error.
|
||||||
|
+ The code that creates these images was changed to be significantly more memory efficient.
|
||||||
|
+ However, these changes also cause a significant slowdown in the romfs building code (~2-5x).
|
||||||
|
+ This introduced a noticeable stutter when launching a game, because the UI thread would block on the romfs creation.
|
||||||
|
+ To solve this, fs.mitm now lazily initializes the image in a background thread.
|
||||||
|
+ This fixes stutter issues, however some games may be slightly slower (~1-2s in the worst cases) to transition from the "loading" GIF to gameplay now.
|
||||||
|
+ Please note: the slowdown is not noticeable in the common case where games don't have tons of files (typical is ~0.1-0.2 seconds).
|
||||||
|
+ Once the image has been built, there is no further speed penalty at runtime -- only when the game is launched.
|
||||||
|
+ A number of other bugs were fixed, including:
|
||||||
|
+ Several minor logic inversions that could have caused fatal errors when modding games.
|
||||||
|
+ Atmosphere's new-ipc code did not handle "automatic" recvlist buffers correctly, so some non-libnx homebrew could crash.
|
||||||
|
+ fs.mitm now correctly mitms sdb, which makes redirection of certain system data archives work again.
|
||||||
|
+ In 0.10.0/0.10.1, changing the system font/language did not work correctly due to this.
|
||||||
|
+ A bug was fixed in process cleanup that caused the system to hang on < 5.0.0.
|
||||||
|
+ The temporary hid-mitm added in Atmosphere 0.9.0 was disabled by default.
|
||||||
|
+ Please ensure your homebrew is updated.
|
||||||
|
+ For now, users may re-enable this mitm by use of a custom setting (`atmosphere!enable_deprecated_hid_mitm`) to ease the transition process some.
|
||||||
|
+ Please note: support for this setting may be removed to save memory in a future atmosphere release.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
## 0.10.1
|
||||||
|
+ A bug was fixed that caused memory reallocation to the system pool to work improperly on firmware 5.0.0 and above.
|
||||||
|
+ Atmosphere was always trying to deallocate memory away from the applet pool and towards the system pool.
|
||||||
|
+ The intent of this is to facilitate running more custom sysmodules/atmosphere binaries.
|
||||||
|
+ However, while memory was always successfully taken away from the applet pool, on 5.0.0+ granting it to the system pool did not work for technical reasons.
|
||||||
|
+ If you are interested in the technical details, talk to SciresM.
|
||||||
|
+ This has now been fixed by adding new kernel patches, and memory is correctly granted to the system pool as intended.
|
||||||
|
+ Atmosphere's library system has been overhauled:
|
||||||
|
+ libstratosphere's repository has been rebranded, more generally, to "Atmosphere-libs".
|
||||||
|
+ In addition to libstratosphere, a new general library for not-stratosphere-specific code has been added.
|
||||||
|
+ This is currently named `libvapours`.
|
||||||
|
+ In the future, kernel functionality will be available as `libmesosphere`.
|
||||||
|
+ The build system for stratosphere system modules has been similarly overhauled.
|
||||||
|
+ A number of other bugs were fixed, including:
|
||||||
|
+ A bug was fixed that could cause memory corruption when redirecting certain Romfs content.
|
||||||
|
+ A bug was fixed that could cause an infinite loop when redirecting certain Romfs content.
|
||||||
|
+ A bug was fixed that could cause certain NROs to fail to load.
|
||||||
|
+ This caused the latest version of Super Smash Bros to display "An error has occurred" on launch.
|
||||||
|
+ A bug was fixed that caused input/output array sizes for certain circumstances to be calculated incorrectly.
|
||||||
|
+ This caused cheats to fail to function properly.
|
||||||
|
+ C++ exception code is now more thoroughly removed from stratosphere executables.
|
||||||
|
+ This saves a minor amount of memory.
|
||||||
|
+ A number of minor logic inversions were fixed in libstratosphere.
|
||||||
|
+ These did not affect any code currently used by released Atmosphere binaries.
|
||||||
|
+ *Please note**: Because this update is releasing so soon after 0.10.0, the removal of the temporary hid-mitm has been postponed to 0.10.2.
|
||||||
|
+ Please ensure your homebrew is updated.
|
||||||
|
+ Random number generation now uses TinyMT instead of XorShift.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
## 0.10.0
|
||||||
|
+ Support was added for 9.1.0
|
||||||
|
+ **Please note**: The temporary hid-mitm added in Atmosphere 0.9.0 will be removed in Atmosphere 0.10.1.
|
||||||
|
+ Please ensure your homebrew is updated.
|
||||||
|
+ The Stratosphere rewrite was completed.
|
||||||
|
+ libstratosphere was rewritten as part of Stratosphere's refactor.
|
||||||
|
+ Code responsible for providing and managing IPC services was greatly improved.
|
||||||
|
+ The new code is significantly more accurate (it is bug-for-bug compatible with Nintendo's code), and significantly faster.
|
||||||
|
+ ams.mitm was rewritten as part of Stratosphere's refactor.
|
||||||
|
+ Saves redirected to the SD card are now separated for sysmmc vs emummc.
|
||||||
|
+ **Please note**: If you find any bugs, please report them so they can be fixed.
|
||||||
|
+ Thanks to the rewrite, Atmosphere now uses significantly less memory.
|
||||||
|
+ Roughly 10 additional megabytes are now available for custom system modules to use.
|
||||||
|
+ This means you can potentially run more custom system modules simultaneously.
|
||||||
|
+ If system modules are incompatible, please ask their authors to reduce their memory footprints.
|
||||||
|
+ Atmosphere's configuration layout has had major changes.
|
||||||
|
+ Configuration now lives inside /atmosphere/config/.
|
||||||
|
+ Atmosphere code now knows what default values should be, and includes them in code.
|
||||||
|
+ It is no longer an error if configuration inis are not present.
|
||||||
|
+ Correspondingly, Atmosphere no longer distributes default configuration inis.
|
||||||
|
+ Templates are provided in /atmosphere/config_templates.
|
||||||
|
+ loader.ini was renamed to override_config.ini.
|
||||||
|
+ This fixes the longstanding problem that atmosphere updates overwrote user configuration when extracted.
|
||||||
|
+ Atmosphere's process override layout was changed.
|
||||||
|
+ Atmosphere now uses the /atmosphere/contents directory, instead of /atmosphere/titles.
|
||||||
|
+ This goes along with a refactoring to remove all reference to "title id" from code, as Nintendo does not use the term.
|
||||||
|
+ To make this transition easier, a temporary functionality has been added that migrates folders to the new directory.
|
||||||
|
+ When booting into 0.10.0, Atmosphere will rename /atmosphere/titles/`<program id>` to /atmosphere/contents/`<program id>`.
|
||||||
|
+ This functionality may or may not be removed in some future update.
|
||||||
|
+ This should solve any transition difficulties for the typical user.
|
||||||
|
+ Please make sure that any future mods you install extract to the correct directory.
|
||||||
|
+ Support for configuring override keys for hbl was improved.
|
||||||
|
+ The key used to override applications versus a specific program can now be different.
|
||||||
|
+ The key to override a specific program can be managed via override_key.
|
||||||
|
+ The key to override any app can be managed via override_any_app_key.
|
||||||
|
+ Default override behavior was changed.
|
||||||
|
+ By default, atmosphere will now override the album applet with hbl unless R is held.
|
||||||
|
+ By default, atmosphere will now override any application with hbl only if R is held.
|
||||||
|
+ The default amount of applet memory reserved has been slightly increased.
|
||||||
|
+ This allows the profile selector applet to work by default in applet mode.
|
||||||
|
+ The way process override status is captured was changed.
|
||||||
|
+ Process override keys are now captured exactly once, when the process is created.
|
||||||
|
+ This fixes the longstanding issue where letting go of the override button partway into the process launch could cause problems.
|
||||||
|
+ The Mitm API was changed to pass around override status.
|
||||||
|
+ Mitm services now know what keys were held when the client was created, as well as whether the client is HBL/should override contents.
|
||||||
|
+ An extension was added to pm:info to allow querying a process's override status.
|
||||||
|
+ Thanks to process override capture improvements, hbl html behavior has been greatly improved.
|
||||||
|
+ Web applets launched by hbl will now always see the /atmosphere/hbl_html filesystem
|
||||||
|
+ Support was added to exosphere for enabling usermode access to the PMU registers.
|
||||||
|
+ This can be controlled via exosphere!enable_user_pmu_access in BCT.ini.
|
||||||
|
+ An enormous number of minor bugs were fixed.
|
||||||
|
+ dmnt's cheat VM had a fix for an inversion in opcode behavior.
|
||||||
|
+ An issue was fixed in fs.mitm's management of domain object IDs that could lead to system corruption in rare cases.
|
||||||
|
+ The Mitm API no longer silently fails when attempting to handle commands passing C descriptors.
|
||||||
|
+ On previous atmosphere versions, certain commands to FS would silently fail due to this...
|
||||||
|
+ No users reported any visible errors, but it was definitely a problem behind the scenes.
|
||||||
|
+ These commands are now handled correctly.
|
||||||
|
+ Atmosphere can now display a fatal error screen significantly earlier in the boot process, if things go wrong early on.
|
||||||
|
+ The temporary hid mitm will no longer sometimes cause games to fail to detect input.
|
||||||
|
+ Mitm Domain object ID management no longer desynchronizes from the host process.
|
||||||
|
+ An issue was fixed that could cause service acquisition to hang forever if certain sm commands were called in a precise order.
|
||||||
|
+ An off-by-one was fixed that could cause memory corruption in server memory management.
|
||||||
|
+ ... and too many more bugs fixed to reasonably list them all :)
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
## 0.9.4
|
||||||
|
+ Support was added for 9.0.0.
|
||||||
|
+ **Please note**: 9.0.0 made a number of changes that may cause some issues with homebrew. Details:
|
||||||
|
+ 9.0.0 changed HID in a way that causes libnx to be unable to detect button input.
|
||||||
|
+ Homebrew should be recompiled with newest libnx to fix this.
|
||||||
|
+ Atmosphere now provides a temporary hid-mitm that will cause homebrew to continue to work as expected.
|
||||||
|
+ This mitm will be removed in a future Atmosphere revision once homebrew has been updated, to allow users to use a custom hid mitm again if they desire.
|
||||||
|
+ 9.0.0 introduced an dependency in FS on the USB system module in order to launch the SD card.
|
||||||
|
+ This means the USB system module must now be launched before the SD card is initialized.
|
||||||
|
+ Correspondingly, the USB system module can no longer be IPS patched, and its settings cannot be reliably mitm'd.
|
||||||
|
+ We know this is frustrating, so we'll be looking into whether there is some way of addressing this in the future.
|
||||||
|
+ An off-by-one error was fixed in `boot` system module's pinmux initialization.
|
||||||
|
+ This could theoretically have caused issues with HdmiCec communication.
|
||||||
|
+ No users reported issues, so it's unclear if this was a problem in practice.
|
||||||
|
+ A bug was fixed that could cause webapplet launching homebrew to improperly set the accessible url whitelist.
|
||||||
|
+ BIS key generation has been fixed for newer hardware.
|
||||||
|
+ Newer hardware uses new, per-firmware device key to generate BIS keys instead of the first device key, so previously the wrong keys were generated as backup.
|
||||||
|
+ This only affects units manufactured after ~5.0.0.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
## 0.9.3
|
## 0.9.3
|
||||||
+ Thanks to hexkyz, fusee's boot sequence has been greatly optimized.
|
+ Thanks to hexkyz, fusee's boot sequence has been greatly optimized.
|
||||||
+ Memory training is now managed by a separate binary (`fusee-mtc`, loaded by fusee-primary before fusee-secondary).
|
+ Memory training is now managed by a separate binary (`fusee-mtc`, loaded by fusee-primary before fusee-secondary).
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/m4xw/emuMMC
|
remote = https://github.com/m4xw/emuMMC
|
||||||
branch = develop
|
branch = develop
|
||||||
commit = 5f51fa3b81d2b14b348f6e8579454007019fc7a6
|
commit = bd81a674a946c30b566e1732a95c18f19b701558
|
||||||
parent = e871a754a87631c3036ca985ff1c223e00ef4dda
|
parent = 6ee525201ccef107c61d81ba73c891e3eb5f0215
|
||||||
method = rebase
|
method = rebase
|
||||||
cmdver = 0.4.0
|
cmdver = 0.4.0
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
# emuMMC
|
# emuMMC
|
||||||
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||||
|
|
||||||
### Supported Horizon Versions
|
### Supported Horizon Versions
|
||||||
**1.0.0 - 8.1.0**
|
**1.0.0 - 9.1.0**
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* Arbitrary SDMMC backend selection
|
* Arbitrary SDMMC backend selection
|
||||||
**This allows loading eMMC from SD or even SD from eMMC**
|
**This allows loading eMMC from SD or even SD from eMMC**
|
||||||
* On the fly hooking / patching, fully self-infesting
|
* On the fly hooking / patching, fully self-infesting
|
||||||
**Only one payload required for all versions!**
|
**Only one payload required for all versions!**
|
||||||
* File-based SDMMC backend support (from SD)
|
* File-based SDMMC backend support (from SD)
|
||||||
**This allows loading eMMC images from hekate-backups (split or not)**
|
**This allows loading eMMC images from hekate-backups (split or not)**
|
||||||
* SDMMC device based sector offset (*currently eMMC only*)
|
* SDMMC device based sector offset (*currently eMMC only*)
|
||||||
**Raw partition support for eMMC from SD with less performance overhead**
|
**Raw partition support for eMMC from SD with less performance overhead**
|
||||||
* Full support for `/Nintendo` folder redirection to a arbitrary path
|
* Full support for `/Nintendo` folder redirection to a arbitrary path
|
||||||
**No 8 char length restriction!**
|
**No 8 char length restriction!**
|
||||||
* exosphere based context configuration
|
* exosphere based context configuration
|
||||||
**This includes full support for multiple emuMMC images**
|
**This includes full support for multiple emuMMC images**
|
||||||
|
|
||||||
## Compiling
|
## Compiling
|
||||||
|
|||||||
@@ -41,6 +41,10 @@
|
|||||||
#include "offsets/800_exfat.h"
|
#include "offsets/800_exfat.h"
|
||||||
#include "offsets/810.h"
|
#include "offsets/810.h"
|
||||||
#include "offsets/810_exfat.h"
|
#include "offsets/810_exfat.h"
|
||||||
|
#include "offsets/900.h"
|
||||||
|
#include "offsets/900_exfat.h"
|
||||||
|
#include "offsets/910.h"
|
||||||
|
#include "offsets/910_exfat.h"
|
||||||
#include "../utils/fatal.h"
|
#include "../utils/fatal.h"
|
||||||
|
|
||||||
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
||||||
@@ -92,6 +96,10 @@ DEFINE_OFFSET_STRUCT(_800);
|
|||||||
DEFINE_OFFSET_STRUCT(_800_EXFAT);
|
DEFINE_OFFSET_STRUCT(_800_EXFAT);
|
||||||
DEFINE_OFFSET_STRUCT(_810);
|
DEFINE_OFFSET_STRUCT(_810);
|
||||||
DEFINE_OFFSET_STRUCT(_810_EXFAT);
|
DEFINE_OFFSET_STRUCT(_810_EXFAT);
|
||||||
|
DEFINE_OFFSET_STRUCT(_900);
|
||||||
|
DEFINE_OFFSET_STRUCT(_900_EXFAT);
|
||||||
|
DEFINE_OFFSET_STRUCT(_910);
|
||||||
|
DEFINE_OFFSET_STRUCT(_910_EXFAT);
|
||||||
|
|
||||||
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||||
switch (version) {
|
switch (version) {
|
||||||
@@ -145,6 +153,14 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
|||||||
return &(GET_OFFSET_STRUCT_NAME(_810));
|
return &(GET_OFFSET_STRUCT_NAME(_810));
|
||||||
case FS_VER_8_1_0_EXFAT:
|
case FS_VER_8_1_0_EXFAT:
|
||||||
return &(GET_OFFSET_STRUCT_NAME(_810_EXFAT));
|
return &(GET_OFFSET_STRUCT_NAME(_810_EXFAT));
|
||||||
|
case FS_VER_9_0_0:
|
||||||
|
return &(GET_OFFSET_STRUCT_NAME(_900));
|
||||||
|
case FS_VER_9_0_0_EXFAT:
|
||||||
|
return &(GET_OFFSET_STRUCT_NAME(_900_EXFAT));
|
||||||
|
case FS_VER_9_1_0:
|
||||||
|
return &(GET_OFFSET_STRUCT_NAME(_910));
|
||||||
|
case FS_VER_9_1_0_EXFAT:
|
||||||
|
return &(GET_OFFSET_STRUCT_NAME(_910_EXFAT));
|
||||||
default:
|
default:
|
||||||
fatal_abort(Fatal_UnknownVersion);
|
fatal_abort(Fatal_UnknownVersion);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,12 @@ enum FS_VER
|
|||||||
FS_VER_8_1_0,
|
FS_VER_8_1_0,
|
||||||
FS_VER_8_1_0_EXFAT,
|
FS_VER_8_1_0_EXFAT,
|
||||||
|
|
||||||
|
FS_VER_9_0_0,
|
||||||
|
FS_VER_9_0_0_EXFAT,
|
||||||
|
|
||||||
|
FS_VER_9_1_0,
|
||||||
|
FS_VER_9_1_0_EXFAT,
|
||||||
|
|
||||||
FS_VER_MAX,
|
FS_VER_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
59
emummc/source/FS/offsets/900.h
Normal file
59
emummc/source/FS/offsets/900.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||||
|
* Copyright (c) 2019 Atmosphere-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef __FS_900_H__
|
||||||
|
#define __FS_900_H__
|
||||||
|
|
||||||
|
// Accessor vtable getters
|
||||||
|
#define FS_OFFSET_900_SDMMC_ACCESSOR_GC 0x1430F0
|
||||||
|
#define FS_OFFSET_900_SDMMC_ACCESSOR_SD 0x141200
|
||||||
|
#define FS_OFFSET_900_SDMMC_ACCESSOR_NAND 0x13C080
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
#define FS_OFFSET_900_SDMMC_WRAPPER_READ 0x1377E0
|
||||||
|
#define FS_OFFSET_900_SDMMC_WRAPPER_WRITE 0x1378C0
|
||||||
|
#define FS_OFFSET_900_RTLD 0x454
|
||||||
|
#define FS_OFFSET_900_RTLD_DESTINATION 0x9C
|
||||||
|
|
||||||
|
#define FS_OFFSET_900_CLKRST_SET_MIN_V_CLK_RATE 0x136A00
|
||||||
|
|
||||||
|
// Misc funcs
|
||||||
|
#define FS_OFFSET_900_LOCK_MUTEX 0x25280
|
||||||
|
#define FS_OFFSET_900_UNLOCK_MUTEX 0x252D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_900_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
|
||||||
|
|
||||||
|
// Misc Data
|
||||||
|
#define FS_OFFSET_900_SD_MUTEX 0xE1D3E8
|
||||||
|
#define FS_OFFSET_900_NAND_MUTEX 0xE18258
|
||||||
|
#define FS_OFFSET_900_ACTIVE_PARTITION 0xE18298
|
||||||
|
#define FS_OFFSET_900_SDMMC_DAS_HANDLE 0xDFEFA0
|
||||||
|
|
||||||
|
// NOPs
|
||||||
|
#define FS_OFFSET_900_SD_DAS_INIT 0x1472BC
|
||||||
|
|
||||||
|
// Nintendo Paths
|
||||||
|
#define FS_OFFSET_900_NINTENDO_PATHS \
|
||||||
|
{ \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00068A60, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00070A40, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00081CB4, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00081EF4, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x0008211C, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __FS_900_H__
|
||||||
59
emummc/source/FS/offsets/900_exfat.h
Normal file
59
emummc/source/FS/offsets/900_exfat.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||||
|
* Copyright (c) 2019 Atmosphere-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef __FS_900_EXFAT_H__
|
||||||
|
#define __FS_900_EXFAT_H__
|
||||||
|
|
||||||
|
// Accessor vtable getters
|
||||||
|
#define FS_OFFSET_900_EXFAT_SDMMC_ACCESSOR_GC 0x1430F0
|
||||||
|
#define FS_OFFSET_900_EXFAT_SDMMC_ACCESSOR_SD 0x141200
|
||||||
|
#define FS_OFFSET_900_EXFAT_SDMMC_ACCESSOR_NAND 0x13C080
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_READ 0x1377E0
|
||||||
|
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_WRITE 0x1378C0
|
||||||
|
#define FS_OFFSET_900_EXFAT_RTLD 0x454
|
||||||
|
#define FS_OFFSET_900_EXFAT_RTLD_DESTINATION 0x9C
|
||||||
|
|
||||||
|
#define FS_OFFSET_900_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x136A00
|
||||||
|
|
||||||
|
// Misc funcs
|
||||||
|
#define FS_OFFSET_900_EXFAT_LOCK_MUTEX 0x25280
|
||||||
|
#define FS_OFFSET_900_EXFAT_UNLOCK_MUTEX 0x252D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
|
||||||
|
|
||||||
|
// Misc Data
|
||||||
|
#define FS_OFFSET_900_EXFAT_SD_MUTEX 0xE2B3E8
|
||||||
|
#define FS_OFFSET_900_EXFAT_NAND_MUTEX 0xE26258
|
||||||
|
#define FS_OFFSET_900_EXFAT_ACTIVE_PARTITION 0xE26298
|
||||||
|
#define FS_OFFSET_900_EXFAT_SDMMC_DAS_HANDLE 0xE0CFA0
|
||||||
|
|
||||||
|
// NOPs
|
||||||
|
#define FS_OFFSET_900_EXFAT_SD_DAS_INIT 0x1472BC
|
||||||
|
|
||||||
|
// Nintendo Paths
|
||||||
|
#define FS_OFFSET_900_EXFAT_NINTENDO_PATHS \
|
||||||
|
{ \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00068A60, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00070A40, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00081CB4, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00081EF4, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x0008211C, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __FS_900_EXFAT_H__
|
||||||
59
emummc/source/FS/offsets/910.h
Normal file
59
emummc/source/FS/offsets/910.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||||
|
* Copyright (c) 2019 Atmosphere-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef __FS_910_H__
|
||||||
|
#define __FS_910_H__
|
||||||
|
|
||||||
|
// Accessor vtable getters
|
||||||
|
#define FS_OFFSET_910_SDMMC_ACCESSOR_GC 0x143100
|
||||||
|
#define FS_OFFSET_910_SDMMC_ACCESSOR_SD 0x141210
|
||||||
|
#define FS_OFFSET_910_SDMMC_ACCESSOR_NAND 0x13C090
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
#define FS_OFFSET_910_SDMMC_WRAPPER_READ 0x1377F0
|
||||||
|
#define FS_OFFSET_910_SDMMC_WRAPPER_WRITE 0x1378D0
|
||||||
|
#define FS_OFFSET_910_RTLD 0x454
|
||||||
|
#define FS_OFFSET_910_RTLD_DESTINATION 0x9C
|
||||||
|
|
||||||
|
#define FS_OFFSET_910_CLKRST_SET_MIN_V_CLK_RATE 0x136A10
|
||||||
|
|
||||||
|
// Misc funcs
|
||||||
|
#define FS_OFFSET_910_LOCK_MUTEX 0x25280
|
||||||
|
#define FS_OFFSET_910_UNLOCK_MUTEX 0x252D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_910_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750
|
||||||
|
|
||||||
|
// Misc Data
|
||||||
|
#define FS_OFFSET_910_SD_MUTEX 0xE1D3E8
|
||||||
|
#define FS_OFFSET_910_NAND_MUTEX 0xE18258
|
||||||
|
#define FS_OFFSET_910_ACTIVE_PARTITION 0xE18298
|
||||||
|
#define FS_OFFSET_910_SDMMC_DAS_HANDLE 0xDFEFA0
|
||||||
|
|
||||||
|
// NOPs
|
||||||
|
#define FS_OFFSET_910_SD_DAS_INIT 0x1472CC
|
||||||
|
|
||||||
|
// Nintendo Paths
|
||||||
|
#define FS_OFFSET_910_NINTENDO_PATHS \
|
||||||
|
{ \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00068A70, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00070A50, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00081CC4, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00081F04, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x0008212C, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __FS_910_H__
|
||||||
59
emummc/source/FS/offsets/910_exfat.h
Normal file
59
emummc/source/FS/offsets/910_exfat.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||||
|
* Copyright (c) 2019 Atmosphere-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef __FS_910_EXFAT_H__
|
||||||
|
#define __FS_910_EXFAT_H__
|
||||||
|
|
||||||
|
// Accessor vtable getters
|
||||||
|
#define FS_OFFSET_910_EXFAT_SDMMC_ACCESSOR_GC 0x143100
|
||||||
|
#define FS_OFFSET_910_EXFAT_SDMMC_ACCESSOR_SD 0x141210
|
||||||
|
#define FS_OFFSET_910_EXFAT_SDMMC_ACCESSOR_NAND 0x13C090
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
#define FS_OFFSET_910_EXFAT_SDMMC_WRAPPER_READ 0x1377F0
|
||||||
|
#define FS_OFFSET_910_EXFAT_SDMMC_WRAPPER_WRITE 0x1378D0
|
||||||
|
#define FS_OFFSET_910_EXFAT_RTLD 0x454
|
||||||
|
#define FS_OFFSET_910_EXFAT_RTLD_DESTINATION 0x9C
|
||||||
|
|
||||||
|
#define FS_OFFSET_910_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x136A10
|
||||||
|
|
||||||
|
// Misc funcs
|
||||||
|
#define FS_OFFSET_910_EXFAT_LOCK_MUTEX 0x25280
|
||||||
|
#define FS_OFFSET_910_EXFAT_UNLOCK_MUTEX 0x252D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_910_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750
|
||||||
|
|
||||||
|
// Misc Data
|
||||||
|
#define FS_OFFSET_910_EXFAT_SD_MUTEX 0xE2B3E8
|
||||||
|
#define FS_OFFSET_910_EXFAT_NAND_MUTEX 0xE26258
|
||||||
|
#define FS_OFFSET_910_EXFAT_ACTIVE_PARTITION 0xE26298
|
||||||
|
#define FS_OFFSET_910_EXFAT_SDMMC_DAS_HANDLE 0xE0CFA0
|
||||||
|
|
||||||
|
// NOPs
|
||||||
|
#define FS_OFFSET_910_EXFAT_SD_DAS_INIT 0x1472CC
|
||||||
|
|
||||||
|
// Nintendo Paths
|
||||||
|
#define FS_OFFSET_910_EXFAT_NINTENDO_PATHS \
|
||||||
|
{ \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00068A70, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00070A50, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00081CC4, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 3, .adrp_offset = 0x00081F04, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 4, .adrp_offset = 0x0008212C, .add_rel_offset = 0x00000004}, \
|
||||||
|
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __FS_910_EXFAT_H__
|
||||||
@@ -15,13 +15,26 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include "fatal.h"
|
#include "fatal.h"
|
||||||
|
|
||||||
void __attribute__((noreturn)) fatal_abort(enum FatalReason abortReason)
|
void __attribute__((noreturn)) fatal_abort(enum FatalReason abortReason)
|
||||||
{
|
{
|
||||||
|
atmosphere_fatal_error_ctx error_ctx;
|
||||||
|
memset(&error_ctx, 0, sizeof(atmosphere_fatal_error_ctx));
|
||||||
|
|
||||||
|
// Basic error storage for Atmosphere
|
||||||
|
// TODO: Maybe include a small reboot2payload stub?
|
||||||
|
error_ctx.magic = ATMOSPHERE_REBOOT_TO_FATAL_MAGIC;
|
||||||
|
error_ctx.title_id = 0x0100000000000000; // FS
|
||||||
|
error_ctx.error_desc = abortReason;
|
||||||
|
|
||||||
|
// Copy fatal context
|
||||||
|
smcCopyToIram(ATMOSPHERE_FATAL_ERROR_ADDR, &error_ctx, sizeof(atmosphere_fatal_error_ctx));
|
||||||
|
|
||||||
// Reboot to RCM
|
// Reboot to RCM
|
||||||
smcRebootToRcm();
|
smcRebootToRcm();
|
||||||
|
|
||||||
while(true)
|
while (true)
|
||||||
; // Should never be reached
|
; // Should never be reached
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../nx/smc.h"
|
#include "../nx/smc.h"
|
||||||
|
|
||||||
enum FatalReason {
|
enum FatalReason
|
||||||
|
{
|
||||||
Fatal_InitMMC = 0,
|
Fatal_InitMMC = 0,
|
||||||
Fatal_InitSD,
|
Fatal_InitSD,
|
||||||
Fatal_InvalidAccessor,
|
Fatal_InvalidAccessor,
|
||||||
@@ -32,4 +33,45 @@ enum FatalReason {
|
|||||||
Fatal_Max
|
Fatal_Max
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20
|
||||||
|
#define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100
|
||||||
|
|
||||||
|
/* Atmosphere reboot-to-fatal-error. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t magic;
|
||||||
|
uint32_t error_desc;
|
||||||
|
uint64_t title_id;
|
||||||
|
union {
|
||||||
|
uint64_t gprs[32];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint64_t _gprs[29];
|
||||||
|
uint64_t fp;
|
||||||
|
uint64_t lr;
|
||||||
|
uint64_t sp;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
uint64_t pc;
|
||||||
|
uint64_t module_base;
|
||||||
|
uint32_t pstate;
|
||||||
|
uint32_t afsr0;
|
||||||
|
uint32_t afsr1;
|
||||||
|
uint32_t esr;
|
||||||
|
uint64_t far;
|
||||||
|
uint64_t report_identifier; /* Normally just system tick. */
|
||||||
|
uint64_t stack_trace_size;
|
||||||
|
uint64_t stack_dump_size;
|
||||||
|
uint64_t stack_trace[AMS_FATAL_ERROR_MAX_STACKTRACE];
|
||||||
|
uint8_t stack_dump[AMS_FATAL_ERROR_MAX_STACKDUMP];
|
||||||
|
} atmosphere_fatal_error_ctx;
|
||||||
|
|
||||||
|
/* "AFE1" */
|
||||||
|
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC 0x31454641
|
||||||
|
/* "AFE0" */
|
||||||
|
#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0 0x30454641
|
||||||
|
|
||||||
|
#define ATMOSPHERE_FATAL_ERROR_ADDR 0x4003E000
|
||||||
|
#define ATMOSPHERE_FATAL_ERROR_CONTEXT ((volatile atmosphere_fatal_error_ctx *)(ATMOSPHERE_FATAL_ERROR_ADDR))
|
||||||
|
|
||||||
void __attribute__((noreturn)) fatal_abort(enum FatalReason abortReason);
|
void __attribute__((noreturn)) fatal_abort(enum FatalReason abortReason);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ TARGET := $(notdir $(CURDIR))
|
|||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := src src/dbg
|
SOURCES := src src/dbg
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include ../common/include
|
INCLUDES := include ../libraries/libvapours/include
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
@@ -48,7 +48,7 @@ CFLAGS := \
|
|||||||
-Wall \
|
-Wall \
|
||||||
$(ARCH) $(DEFINES)
|
$(ARCH) $(DEFINES)
|
||||||
|
|
||||||
CFLAGS += $(INCLUDE)
|
CFLAGS += $(INCLUDE)
|
||||||
|
|
||||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ TARGET := $(notdir $(CURDIR))
|
|||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := src
|
SOURCES := src
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include ../../common/include
|
INCLUDES := include ../../libraries/libvapours/include
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@@ -33,7 +33,7 @@ static inline uint32_t get_special_clk_reg(CarDevice dev) {
|
|||||||
case CARDEVICE_BPMP: return 0;
|
case CARDEVICE_BPMP: return 0;
|
||||||
default: reboot();
|
default: reboot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t get_special_clk_val(CarDevice dev) {
|
static inline uint32_t get_special_clk_val(CarDevice dev) {
|
||||||
switch (dev) {
|
switch (dev) {
|
||||||
@@ -48,19 +48,19 @@ static inline uint32_t get_special_clk_val(CarDevice dev) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t g_clk_reg_offsets[NUM_CAR_BANKS] = {0x010, 0x014, 0x018, 0x360, 0x364, 0x280, 0x298};
|
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_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};
|
static uint32_t g_clk_clr_reg_offsets[NUM_CAR_BANKS] = {0x324, 0x32C, 0x334, 0x444, 0x44C, 0x228, 0x2A0};
|
||||||
|
|
||||||
void car_configure_oscillators(void) {
|
void car_configure_oscillators(void) {
|
||||||
/* Enable the crystal oscillator, setting drive strength to the saved value in PMC. */
|
/* 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);
|
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.) */
|
/* Set CLK_M_DIVISOR to 1 (causes actual division by 2.) */
|
||||||
CLK_RST_CONTROLLER_SPARE_REG0_0 = (1 << 2);
|
CLK_RST_CONTROLLER_SPARE_REG0_0 = (1 << 2);
|
||||||
/* Reading the register after writing it is required to ensure value takes. */
|
/* Reading the register after writing it is required to ensure value takes. */
|
||||||
(void)(CLK_RST_CONTROLLER_SPARE_REG0_0);
|
(void)(CLK_RST_CONTROLLER_SPARE_REG0_0);
|
||||||
|
|
||||||
/* Set TIMERUS_USEC_CFG to cycle at 0x60 / 0x5 = 19.2 MHz. */
|
/* Set TIMERUS_USEC_CFG to cycle at 0x60 / 0x5 = 19.2 MHz. */
|
||||||
/* Value is (dividend << 8) | (divisor). */
|
/* Value is (dividend << 8) | (divisor). */
|
||||||
TIMERUS_USEC_CFG_0 = 0x45F;
|
TIMERUS_USEC_CFG_0 = 0x45F;
|
||||||
@@ -68,30 +68,30 @@ void car_configure_oscillators(void) {
|
|||||||
|
|
||||||
void car_mbist_workaround(void) {
|
void car_mbist_workaround(void) {
|
||||||
/* This code works around MBIST bug. */
|
/* This code works around MBIST bug. */
|
||||||
|
|
||||||
/* Clear LVL2_CLK_GATE_OVR* registers. */
|
/* Clear LVL2_CLK_GATE_OVR* registers. */
|
||||||
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA_0 = 0;
|
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA_0 = 0;
|
||||||
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_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_OVRC_0 = 0;
|
||||||
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 = 0;
|
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 = 0;
|
||||||
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE_0 = 0;
|
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE_0 = 0;
|
||||||
|
|
||||||
/* Clear bit patterns in CAR. */
|
/* Clear bit patterns in CAR. */
|
||||||
/* L: Reset all but RTC, TMR, GPIO, BPMP Cache (CACHE2). */
|
/* 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;
|
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. */
|
/* 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;
|
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). */
|
/* 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;
|
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. */
|
/* 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;
|
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. */
|
/* 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;
|
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, . */
|
/* 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;
|
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. */
|
/* 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;
|
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. */
|
/* Enable clock to MC1, if CH1 is enabled in EMC. */
|
||||||
if (EMC_FBIO_CFG7_0 & 4) { /* CH1_ENABLE */
|
if (EMC_FBIO_CFG7_0 & 4) { /* CH1_ENABLE */
|
||||||
CLK_RST_CONTROLLER_CLK_ENB_W_SET_0 |= 0x40000000; /* SET_CLK_ENB_MC1 */
|
CLK_RST_CONTROLLER_CLK_ENB_W_SET_0 |= 0x40000000; /* SET_CLK_ENB_MC1 */
|
||||||
@@ -132,3 +132,7 @@ void clkrst_reboot(CarDevice dev) {
|
|||||||
clkrst_disable(dev);
|
clkrst_disable(dev);
|
||||||
clkrst_enable(dev);
|
clkrst_enable(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clkrst_enable_fuse_regs(bool enable) {
|
||||||
|
CLK_RST_CONTROLLER_MISC_CLK_ENB_0 = ((CLK_RST_CONTROLLER_MISC_CLK_ENB_0 & 0xEFFFFFFF) | ((enable & 1) << 28));
|
||||||
|
}
|
||||||
@@ -103,7 +103,8 @@ void rst_disable(CarDevice dev);
|
|||||||
|
|
||||||
void clkrst_enable(CarDevice dev);
|
void clkrst_enable(CarDevice dev);
|
||||||
void clkrst_disable(CarDevice dev);
|
void clkrst_disable(CarDevice dev);
|
||||||
|
|
||||||
void clkrst_reboot(CarDevice dev);
|
void clkrst_reboot(CarDevice dev);
|
||||||
|
|
||||||
|
void clkrst_enable_fuse_regs(bool enable);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ bool fuse_check_downgrade_status(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void fuse_disable_programming(void) {
|
void fuse_disable_programming(void) {
|
||||||
FUSE_REGS->FUSE_DIS_PGM = 1;
|
FUSE_REGS->FUSE_DISABLEREGPROGRAM = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fuse_bypass_data_t g_fuse_bypass_entries[NUM_FUSE_BYPASS_ENTRIES] = {
|
static fuse_bypass_data_t g_fuse_bypass_entries[NUM_FUSE_BYPASS_ENTRIES] = {
|
||||||
@@ -37,13 +37,14 @@ static fuse_bypass_data_t g_fuse_bypass_entries[NUM_FUSE_BYPASS_ENTRIES] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void fuse_configure_fuse_bypass(void) {
|
void fuse_configure_fuse_bypass(void) {
|
||||||
/* Enable fuses in CAR? This seems to affect fuse data visibility. */
|
/* Make all fuse registers visible. */
|
||||||
CLK_RST_CONTROLLER_MISC_CLK_ENB_0 |= 0x10000000;
|
clkrst_enable_fuse_regs(true);
|
||||||
|
|
||||||
/* Configure bypass/override, only if programming is allowed. */
|
/* Configure bypass/override, only if programming is allowed. */
|
||||||
if (!(FUSE_REGS->FUSE_DIS_PGM & 1)) {
|
if (!(FUSE_REGS->FUSE_DISABLEREGPROGRAM & 1)) {
|
||||||
/* Enable write access. */
|
/* Enable write access and flush status. */
|
||||||
FUSE_REGS->FUSE_WRITE_ACCESS = (FUSE_REGS->FUSE_WRITE_ACCESS & ~0x1) | 0x10000;
|
FUSE_REGS->FUSE_WRITE_ACCESS_SW = (FUSE_REGS->FUSE_WRITE_ACCESS_SW & ~0x1) | 0x10000;
|
||||||
|
|
||||||
/* Enable fuse bypass config. */
|
/* Enable fuse bypass config. */
|
||||||
FUSE_REGS->FUSE_FUSEBYPASS = 1;
|
FUSE_REGS->FUSE_FUSEBYPASS = 1;
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ void fuse_configure_fuse_bypass(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Disable fuse write access. */
|
/* Disable fuse write access. */
|
||||||
FUSE_REGS->FUSE_WRITE_ACCESS |= 1;
|
FUSE_REGS->FUSE_WRITE_ACCESS_SW |= 1;
|
||||||
|
|
||||||
/* Enable fuse bypass config. */
|
/* Enable fuse bypass config. */
|
||||||
/* I think this is a bug, and Nintendo meant to write 0 here? */
|
/* I think this is a bug, and Nintendo meant to write 0 here? */
|
||||||
@@ -63,7 +64,7 @@ void fuse_configure_fuse_bypass(void) {
|
|||||||
/* I have no idea why this happens. What? */
|
/* I have no idea why this happens. What? */
|
||||||
/* This is probably also either a bug or does nothing. */
|
/* This is probably also either a bug or does nothing. */
|
||||||
/* Is this bit even clearable? */
|
/* Is this bit even clearable? */
|
||||||
FUSE_REGS->FUSE_DIS_PGM &= 0xFFFFFFFE;
|
FUSE_REGS->FUSE_DISABLEREGPROGRAM &= 0xFFFFFFFE;
|
||||||
|
|
||||||
/* Restore saved private key disable bit. */
|
/* Restore saved private key disable bit. */
|
||||||
FUSE_REGS->FUSE_PRIVATEKEYDISABLE |= (APBDEV_PMC_SECURE_SCRATCH21_0 & 0x10);
|
FUSE_REGS->FUSE_PRIVATEKEYDISABLE |= (APBDEV_PMC_SECURE_SCRATCH21_0 & 0x10);
|
||||||
@@ -71,5 +72,4 @@ void fuse_configure_fuse_bypass(void) {
|
|||||||
/* Lock private key disable secure scratch. */
|
/* Lock private key disable secure scratch. */
|
||||||
APBDEV_PMC_SEC_DISABLE2_0 |= 0x4000000;
|
APBDEV_PMC_SEC_DISABLE2_0 |= 0x4000000;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
@@ -23,154 +23,167 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t FUSE_CTRL;
|
uint32_t FUSE_FUSECTRL;
|
||||||
uint32_t FUSE_REG_ADDR;
|
uint32_t FUSE_FUSEADDR;
|
||||||
uint32_t FUSE_REG_READ;
|
uint32_t FUSE_FUSERDATA;
|
||||||
uint32_t FUSE_REG_WRITE;
|
uint32_t FUSE_FUSEWDATA;
|
||||||
uint32_t FUSE_TIME_RD1;
|
uint32_t FUSE_FUSETIME_RD1;
|
||||||
uint32_t FUSE_TIME_RD2;
|
uint32_t FUSE_FUSETIME_RD2;
|
||||||
uint32_t FUSE_TIME_PGM1;
|
uint32_t FUSE_FUSETIME_PGM1;
|
||||||
uint32_t FUSE_TIME_PGM2;
|
uint32_t FUSE_FUSETIME_PGM2;
|
||||||
uint32_t FUSE_PRIV2INTFC;
|
uint32_t FUSE_PRIV2INTFC_START;
|
||||||
uint32_t FUSE_FUSEBYPASS;
|
uint32_t FUSE_FUSEBYPASS;
|
||||||
uint32_t FUSE_PRIVATEKEYDISABLE;
|
uint32_t FUSE_PRIVATEKEYDISABLE;
|
||||||
uint32_t FUSE_DIS_PGM;
|
uint32_t FUSE_DISABLEREGPROGRAM;
|
||||||
uint32_t FUSE_WRITE_ACCESS;
|
uint32_t FUSE_WRITE_ACCESS_SW;
|
||||||
uint32_t FUSE_PWR_GOOD_SW;
|
uint32_t FUSE_PWR_GOOD_SW;
|
||||||
uint32_t _0x38[0x32];
|
uint32_t _0x38;
|
||||||
} fuse_registers_t;
|
uint32_t FUSE_PRIV2RESHIFT;
|
||||||
|
uint32_t _0x40[0x3];
|
||||||
|
uint32_t FUSE_FUSETIME_RD3;
|
||||||
|
uint32_t _0x50[0xC];
|
||||||
|
uint32_t FUSE_PRIVATE_KEY0_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY1_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY2_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY3_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY4_NONZERO;
|
||||||
|
uint32_t _0x90[0x1C];
|
||||||
|
} tegra_fuse_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t FUSE_PRODUCTION_MODE;
|
uint32_t FUSE_PRODUCTION_MODE;
|
||||||
uint32_t _0x4;
|
uint32_t FUSE_JTAG_SECUREID_VALID;
|
||||||
uint32_t _0x8;
|
uint32_t FUSE_ODM_LOCK;
|
||||||
uint32_t _0xC;
|
uint32_t FUSE_OPT_OPENGL_EN;
|
||||||
uint32_t FUSE_SKU_INFO;
|
uint32_t FUSE_SKU_INFO;
|
||||||
uint32_t FUSE_CPU_SPEEDO_0;
|
uint32_t FUSE_CPU_SPEEDO_0_CALIB;
|
||||||
uint32_t FUSE_CPU_IDDQ;
|
uint32_t FUSE_CPU_IDDQ_CALIB;
|
||||||
uint32_t _0x1C;
|
uint32_t FUSE_DAC_CRT_CALIB;
|
||||||
uint32_t _0x20;
|
uint32_t FUSE_DAC_HDTV_CALIB;
|
||||||
uint32_t _0x24;
|
uint32_t FUSE_DAC_SDTV_CALIB;
|
||||||
uint32_t FUSE_FT_REV;
|
uint32_t FUSE_OPT_FT_REV;
|
||||||
uint32_t FUSE_CPU_SPEEDO_1;
|
uint32_t FUSE_CPU_SPEEDO_1_CALIB;
|
||||||
uint32_t FUSE_CPU_SPEEDO_2;
|
uint32_t FUSE_CPU_SPEEDO_2_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_0;
|
uint32_t FUSE_SOC_SPEEDO_0_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_1;
|
uint32_t FUSE_SOC_SPEEDO_1_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_2;
|
uint32_t FUSE_SOC_SPEEDO_2_CALIB;
|
||||||
uint32_t FUSE_SOC_IDDQ;
|
uint32_t FUSE_SOC_IDDQ_CALIB;
|
||||||
uint32_t _0x44;
|
uint32_t FUSE_RESERVED_PRODUCTION_WP;
|
||||||
uint32_t FUSE_FA;
|
uint32_t FUSE_FA;
|
||||||
uint32_t _0x4C;
|
uint32_t FUSE_RESERVED_PRODUCTION;
|
||||||
uint32_t _0x50;
|
uint32_t FUSE_HDMI_LANE0_CALIB;
|
||||||
uint32_t _0x54;
|
uint32_t FUSE_HDMI_LANE1_CALIB;
|
||||||
uint32_t _0x58;
|
uint32_t FUSE_HDMI_LANE2_CALIB;
|
||||||
uint32_t _0x5C;
|
uint32_t FUSE_HDMI_LANE3_CALIB;
|
||||||
uint32_t _0x60;
|
uint32_t FUSE_ENCRYPTION_RATE;
|
||||||
uint32_t FUSE_PUBLIC_KEY[0x8];
|
uint32_t FUSE_PUBLIC_KEY[0x8];
|
||||||
uint32_t FUSE_TSENSOR_1;
|
uint32_t FUSE_TSENSOR1_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_2;
|
uint32_t FUSE_TSENSOR2_CALIB;
|
||||||
uint32_t _0x8C;
|
uint32_t FUSE_VSENSOR_CALIB;
|
||||||
uint32_t FUSE_CP_REV;
|
uint32_t FUSE_OPT_CP_REV;
|
||||||
uint32_t _0x94;
|
uint32_t FUSE_OPT_PFG;
|
||||||
uint32_t FUSE_TSENSOR_0;
|
uint32_t FUSE_TSENSOR0_CALIB;
|
||||||
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG;
|
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE;
|
||||||
uint32_t FUSE_SECURITY_MODE;
|
uint32_t FUSE_SECURITY_MODE;
|
||||||
uint32_t FUSE_PRIVATE_KEY[0x4];
|
uint32_t FUSE_PRIVATE_KEY[0x5];
|
||||||
uint32_t FUSE_DEVICE_KEY;
|
uint32_t FUSE_ARM_JTAG_DIS;
|
||||||
uint32_t _0xB8;
|
uint32_t FUSE_BOOT_DEVICE_INFO;
|
||||||
uint32_t _0xBC;
|
|
||||||
uint32_t FUSE_RESERVED_SW;
|
uint32_t FUSE_RESERVED_SW;
|
||||||
uint32_t FUSE_VP8_ENABLE;
|
uint32_t FUSE_OPT_VP9_DISABLE;
|
||||||
uint32_t FUSE_RESERVED_ODM[0x8];
|
uint32_t FUSE_RESERVED_ODM[0x8];
|
||||||
uint32_t _0xE8;
|
uint32_t FUSE_OBS_DIS;
|
||||||
uint32_t _0xEC;
|
uint32_t FUSE_NOR_INFO;
|
||||||
uint32_t FUSE_SKU_USB_CALIB;
|
uint32_t FUSE_USB_CALIB;
|
||||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
||||||
uint32_t _0xF8;
|
uint32_t FUSE_KFUSE_PRIVKEY_CTRL;
|
||||||
uint32_t _0xFC;
|
uint32_t FUSE_PACKAGE_INFO;
|
||||||
uint32_t FUSE_VENDOR_CODE;
|
uint32_t FUSE_OPT_VENDOR_CODE;
|
||||||
uint32_t FUSE_FAB_CODE;
|
uint32_t FUSE_OPT_FAB_CODE;
|
||||||
uint32_t FUSE_LOT_CODE_0;
|
uint32_t FUSE_OPT_LOT_CODE_0;
|
||||||
uint32_t FUSE_LOT_CODE_1;
|
uint32_t FUSE_OPT_LOT_CODE_1;
|
||||||
uint32_t FUSE_WAFER_ID;
|
uint32_t FUSE_OPT_WAFER_ID;
|
||||||
uint32_t FUSE_X_COORDINATE;
|
uint32_t FUSE_OPT_X_COORDINATE;
|
||||||
uint32_t FUSE_Y_COORDINATE;
|
uint32_t FUSE_OPT_Y_COORDINATE;
|
||||||
uint32_t _0x11C;
|
uint32_t FUSE_OPT_SEC_DEBUG_EN;
|
||||||
uint32_t _0x120;
|
uint32_t FUSE_OPT_OPS_RESERVED;
|
||||||
uint32_t FUSE_SATA_CALIB;
|
uint32_t FUSE_SATA_CALIB;
|
||||||
uint32_t FUSE_GPU_IDDQ;
|
uint32_t FUSE_GPU_IDDQ_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_3;
|
uint32_t FUSE_TSENSOR3_CALIB;
|
||||||
uint32_t _0x130;
|
uint32_t FUSE_SKU_BOND_OUT_L;
|
||||||
uint32_t _0x134;
|
uint32_t FUSE_SKU_BOND_OUT_H;
|
||||||
uint32_t _0x138;
|
uint32_t FUSE_SKU_BOND_OUT_U;
|
||||||
uint32_t _0x13C;
|
uint32_t FUSE_SKU_BOND_OUT_V;
|
||||||
uint32_t _0x140;
|
uint32_t FUSE_SKU_BOND_OUT_W;
|
||||||
uint32_t _0x144;
|
uint32_t FUSE_OPT_SAMPLE_TYPE;
|
||||||
uint32_t FUSE_OPT_SUBREVISION;
|
uint32_t FUSE_OPT_SUBREVISION;
|
||||||
uint32_t _0x14C;
|
uint32_t FUSE_OPT_SW_RESERVED_0;
|
||||||
uint32_t _0x150;
|
uint32_t FUSE_OPT_SW_RESERVED_1;
|
||||||
uint32_t FUSE_TSENSOR_4;
|
uint32_t FUSE_TSENSOR4_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_5;
|
uint32_t FUSE_TSENSOR5_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_6;
|
uint32_t FUSE_TSENSOR6_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_7;
|
uint32_t FUSE_TSENSOR7_CALIB;
|
||||||
uint32_t FUSE_OPT_PRIV_SEC_DIS;
|
uint32_t FUSE_OPT_PRIV_SEC_EN;
|
||||||
uint32_t FUSE_PKC_DISABLE;
|
uint32_t FUSE_PKC_DISABLE;
|
||||||
uint32_t _0x16C;
|
uint32_t _0x16C;
|
||||||
uint32_t _0x170;
|
uint32_t _0x170;
|
||||||
uint32_t _0x174;
|
uint32_t _0x174;
|
||||||
uint32_t _0x178;
|
uint32_t _0x178;
|
||||||
uint32_t _0x17C;
|
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
||||||
uint32_t FUSE_TSENSOR_COMMON;
|
uint32_t FUSE_TSENSOR_COMMON;
|
||||||
uint32_t _0x184;
|
uint32_t FUSE_OPT_CP_BIN;
|
||||||
uint32_t _0x188;
|
uint32_t FUSE_OPT_GPU_DISABLE;
|
||||||
uint32_t _0x18C;
|
uint32_t FUSE_OPT_FT_BIN;
|
||||||
uint32_t _0x190;
|
uint32_t FUSE_OPT_DONE_MAP;
|
||||||
uint32_t _0x194;
|
uint32_t _0x194;
|
||||||
uint32_t _0x198;
|
uint32_t FUSE_APB2JTAG_DISABLE;
|
||||||
uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
|
uint32_t FUSE_ODM_INFO;
|
||||||
uint32_t _0x1A0;
|
uint32_t _0x1A0;
|
||||||
uint32_t _0x1A4;
|
uint32_t _0x1A4;
|
||||||
uint32_t _0x1A8;
|
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
|
||||||
uint32_t _0x1AC;
|
uint32_t _0x1AC;
|
||||||
uint32_t _0x1B0;
|
uint32_t _0x1B0;
|
||||||
uint32_t _0x1B4;
|
uint32_t _0x1B4;
|
||||||
uint32_t _0x1B8;
|
uint32_t _0x1B8;
|
||||||
uint32_t _0x1BC;
|
uint32_t _0x1BC;
|
||||||
uint32_t _0x1D0;
|
uint32_t FUSE_WOA_SKU_FLAG;
|
||||||
uint32_t FUSE_TSENSOR_8;
|
uint32_t FUSE_ECO_RESERVE_1;
|
||||||
|
uint32_t FUSE_GCPLEX_CONFIG_FUSE;
|
||||||
|
uint32_t FUSE_PRODUCTION_MONTH;
|
||||||
|
uint32_t FUSE_RAM_REPAIR_INDICATOR;
|
||||||
|
uint32_t FUSE_TSENSOR9_CALIB;
|
||||||
uint32_t _0x1D8;
|
uint32_t _0x1D8;
|
||||||
uint32_t _0x1DC;
|
uint32_t FUSE_VMIN_CALIBRATION;
|
||||||
uint32_t _0x1E0;
|
uint32_t FUSE_AGING_SENSOR_CALIBRATION;
|
||||||
uint32_t _0x1E4;
|
uint32_t FUSE_DEBUG_AUTHENTICATION;
|
||||||
uint32_t _0x1E8;
|
uint32_t FUSE_SECURE_PROVISION_INDEX;
|
||||||
uint32_t _0x1EC;
|
uint32_t FUSE_SECURE_PROVISION_INFO;
|
||||||
uint32_t _0x1F0;
|
uint32_t FUSE_OPT_GPU_DISABLE_CP1;
|
||||||
uint32_t _0x1F4;
|
uint32_t FUSE_SPARE_ENDIS;
|
||||||
uint32_t _0x1F8;
|
uint32_t FUSE_ECO_RESERVE_0;
|
||||||
uint32_t _0x1FC;
|
uint32_t _0x1FC;
|
||||||
uint32_t _0x200;
|
uint32_t _0x200;
|
||||||
uint32_t FUSE_RESERVED_CALIB;
|
uint32_t FUSE_RESERVED_CALIB0;
|
||||||
uint32_t _0x208;
|
uint32_t FUSE_RESERVED_CALIB1;
|
||||||
uint32_t _0x20C;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE;
|
||||||
uint32_t _0x210;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1;
|
||||||
uint32_t _0x214;
|
uint32_t FUSE_OPT_CPU_DISABLE;
|
||||||
uint32_t _0x218;
|
uint32_t FUSE_OPT_CPU_DISABLE_CP1;
|
||||||
uint32_t FUSE_TSENSOR_9;
|
uint32_t FUSE_TSENSOR10_CALIB;
|
||||||
uint32_t _0x220;
|
uint32_t FUSE_TSENSOR10_CALIB_AUX;
|
||||||
uint32_t _0x224;
|
uint32_t FUSE_OPT_RAM_SVOP_DP;
|
||||||
uint32_t _0x228;
|
uint32_t FUSE_OPT_RAM_SVOP_PDP;
|
||||||
uint32_t _0x22C;
|
uint32_t FUSE_OPT_RAM_SVOP_REG;
|
||||||
uint32_t _0x230;
|
uint32_t FUSE_OPT_RAM_SVOP_SP;
|
||||||
uint32_t _0x234;
|
uint32_t FUSE_OPT_RAM_SVOP_SMPDP;
|
||||||
uint32_t _0x238;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2;
|
||||||
uint32_t _0x23C;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE;
|
||||||
uint32_t _0x240;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1;
|
||||||
uint32_t _0x244;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2;
|
||||||
uint32_t _0x248;
|
uint32_t FUSE_OPT_CPU_DISABLE_CP2;
|
||||||
uint32_t _0x24C;
|
uint32_t FUSE_OPT_GPU_DISABLE_CP2;
|
||||||
uint32_t FUSE_USB_CALIB_EXT;
|
uint32_t FUSE_USB_CALIB_EXT;
|
||||||
uint32_t _0x254;
|
uint32_t FUSE_RESERVED_FIELD;
|
||||||
uint32_t _0x258;
|
uint32_t FUSE_OPT_ECC_EN;
|
||||||
uint32_t _0x25C;
|
uint32_t _0x25C;
|
||||||
uint32_t _0x260;
|
uint32_t _0x260;
|
||||||
uint32_t _0x264;
|
uint32_t _0x264;
|
||||||
@@ -179,12 +192,12 @@ typedef struct {
|
|||||||
uint32_t _0x270;
|
uint32_t _0x270;
|
||||||
uint32_t _0x274;
|
uint32_t _0x274;
|
||||||
uint32_t _0x278;
|
uint32_t _0x278;
|
||||||
uint32_t _0x27C;
|
uint32_t FUSE_SPARE_REALIGNMENT_REG;
|
||||||
uint32_t FUSE_SPARE_BIT[0x20];
|
uint32_t FUSE_SPARE_BIT[0x20];
|
||||||
} fuse_chip_registers_t;
|
} tegra_fuse_chip_t;
|
||||||
|
|
||||||
#define FUSE_REGS ((volatile fuse_registers_t *)(0x7000F800))
|
#define FUSE_REGS ((volatile tegra_fuse_t *)(0x7000F800))
|
||||||
#define FUSE_CHIP_REGS ((volatile fuse_chip_registers_t *)(0x7000F900))
|
#define FUSE_CHIP_REGS ((volatile tegra_fuse_chip_t *)(0x7000F900))
|
||||||
|
|
||||||
#define MAKE_FUSE_REG(n) MAKE_REG32(0x7000F800 + n)
|
#define MAKE_FUSE_REG(n) MAKE_REG32(0x7000F800 + n)
|
||||||
|
|
||||||
@@ -194,9 +207,7 @@ typedef struct {
|
|||||||
} fuse_bypass_data_t;
|
} fuse_bypass_data_t;
|
||||||
|
|
||||||
bool fuse_check_downgrade_status(void);
|
bool fuse_check_downgrade_status(void);
|
||||||
|
|
||||||
void fuse_configure_fuse_bypass(void);
|
void fuse_configure_fuse_bypass(void);
|
||||||
|
|
||||||
void fuse_disable_programming(void);
|
void fuse_disable_programming(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -35,6 +35,14 @@
|
|||||||
#define MC_SMMU_PTB_DATA 0x20
|
#define MC_SMMU_PTB_DATA 0x20
|
||||||
#define MC_SMMU_TLB_FLUSH 0x30
|
#define MC_SMMU_TLB_FLUSH 0x30
|
||||||
#define MC_SMMU_PTC_FLUSH 0x34
|
#define MC_SMMU_PTC_FLUSH 0x34
|
||||||
|
#define MC_SMMU_ASID_SECURITY 0x38
|
||||||
|
#define MC_SMMU_ASID_SECURITY_1 0x3c
|
||||||
|
#define MC_SMMU_ASID_SECURITY_2 0x9e0
|
||||||
|
#define MC_SMMU_ASID_SECURITY_3 0x9e4
|
||||||
|
#define MC_SMMU_ASID_SECURITY_4 0x9e8
|
||||||
|
#define MC_SMMU_ASID_SECURITY_5 0x9ec
|
||||||
|
#define MC_SMMU_ASID_SECURITY_6 0x9f0
|
||||||
|
#define MC_SMMU_ASID_SECURITY_7 0x9f4
|
||||||
#define MC_SMMU_AFI_ASID 0x238
|
#define MC_SMMU_AFI_ASID 0x238
|
||||||
#define MC_SMMU_AVPC_ASID 0x23c
|
#define MC_SMMU_AVPC_ASID 0x23c
|
||||||
#define MC_SMMU_PPCS1_ASID 0x298
|
#define MC_SMMU_PPCS1_ASID 0x298
|
||||||
|
|||||||
@@ -23,26 +23,26 @@
|
|||||||
#include "pmc.h"
|
#include "pmc.h"
|
||||||
|
|
||||||
void misc_configure_device_dbg_settings(void) {
|
void misc_configure_device_dbg_settings(void) {
|
||||||
/* Enable RTCK daisychaining by setting TBE bit. */
|
/* Set APB_MISC_PP_CONFIG_CTL_TBE (enables RTCK daisy-chaining). */
|
||||||
APB_MISC_PP_CONFIG_CTL_0 = 0x80;
|
APB_MISC_PP_CONFIG_CTL_0 = 0x80;
|
||||||
|
|
||||||
/* Literally none of this is documented in the TRM, lol. */
|
/* Configure JTAG and debug bits. */
|
||||||
if (FUSE_CHIP_REGS->FUSE_SECURITY_MODE == 1) {
|
if (FUSE_CHIP_REGS->FUSE_SECURITY_MODE == 1) {
|
||||||
uint32_t secure_boot_val = 0b0100; /* Sets NIDEN for aarch64. */
|
uint32_t secure_boot_val = 0b0100; /* Set NIDEN for aarch64. */
|
||||||
uint32_t misc_val = 0x40;
|
uint32_t pp_config_ctl_val = 0x40; /* Set APB_MISC_PP_CONFIG_CTL_JTAG. */
|
||||||
if (APBDEV_PMC_STICKY_BITS_0 & 0x40) {
|
if (APBDEV_PMC_STICKY_BITS_0 & 0x40) {
|
||||||
misc_val = 0x0;
|
pp_config_ctl_val = 0x0;
|
||||||
} else {
|
} else {
|
||||||
secure_boot_val = 0b1101; /* Sets SPNIDEN, NIDEN, DBGEN for aarch64. */
|
secure_boot_val = 0b1101; /* Set SPNIDEN, NIDEN, DBGEN for aarch64. */
|
||||||
}
|
}
|
||||||
SB_PFCFG_0 = (SB_PFCFG_0 & ~0b1111) | secure_boot_val; /* Configures debug bits. */
|
SB_PFCFG_0 = (SB_PFCFG_0 & ~0b1111) | secure_boot_val; /* Configure debug bits. */
|
||||||
APB_MISC_PP_CONFIG_CTL_0 |= misc_val; /* Undocumented, seems to control invasive debugging/JTAG. */
|
APB_MISC_PP_CONFIG_CTL_0 |= pp_config_ctl_val; /* Configure JTAG. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set sticky bits based SECURITY_MODE. */
|
/* Set HDA_LPBK_DIS if FUSE_SECURITY_MODE is set (disables HDA codec loopback). */
|
||||||
APBDEV_PMC_STICKY_BITS_0 |= FUSE_CHIP_REGS->FUSE_SECURITY_MODE;
|
APBDEV_PMC_STICKY_BITS_0 |= FUSE_CHIP_REGS->FUSE_SECURITY_MODE;
|
||||||
|
|
||||||
/* Set E_INPUT in PINMUX_AUX_GPIO_PA6_0 */
|
/* Set E_INPUT in PINMUX_AUX_GPIO_PA6_0 (needed by the XUSB and SATA controllers). */
|
||||||
PINMUX_AUX_GPIO_PA6_0 |= 0x40;
|
PINMUX_AUX_GPIO_PA6_0 |= 0x40;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,17 +26,14 @@
|
|||||||
#define MAKE_MISC_REG(n) MAKE_REG32(MISC_BASE + n)
|
#define MAKE_MISC_REG(n) MAKE_REG32(MISC_BASE + n)
|
||||||
|
|
||||||
#define APB_MISC_PP_CONFIG_CTL_0 MAKE_MISC_REG(0x024)
|
#define APB_MISC_PP_CONFIG_CTL_0 MAKE_MISC_REG(0x024)
|
||||||
|
|
||||||
#define APB_MISC_GP_ASDBGREG_0 MAKE_MISC_REG(0x810)
|
#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_SCL_0 MAKE_MISC_REG(0x30DC)
|
||||||
#define PINMUX_AUX_PWR_I2C_SDA_0 MAKE_MISC_REG(0x30E0)
|
#define PINMUX_AUX_PWR_I2C_SDA_0 MAKE_MISC_REG(0x30E0)
|
||||||
#define PINMUX_AUX_DVFS_PWM_0 MAKE_MISC_REG(0x3184)
|
#define PINMUX_AUX_DVFS_PWM_0 MAKE_MISC_REG(0x3184)
|
||||||
|
|
||||||
#define PINMUX_AUX_GPIO_PA6_0 MAKE_MISC_REG(0x3244)
|
#define PINMUX_AUX_GPIO_PA6_0 MAKE_MISC_REG(0x3244)
|
||||||
|
|
||||||
void misc_configure_device_dbg_settings(void);
|
void misc_configure_device_dbg_settings(void);
|
||||||
|
|
||||||
void misc_restore_ram_svop(void);
|
void misc_restore_ram_svop(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,47 +23,35 @@
|
|||||||
|
|
||||||
#define MAKE_PMC_REG(ofs) (MAKE_REG32(PMC_BASE + ofs))
|
#define MAKE_PMC_REG(ofs) (MAKE_REG32(PMC_BASE + ofs))
|
||||||
|
|
||||||
#define APBDEV_PMC_CNTRL_0 MAKE_PMC_REG(0x000)
|
#define APBDEV_PMC_CNTRL_0 MAKE_PMC_REG(0x000)
|
||||||
|
#define APBDEV_PMC_DPD_SAMPLE_0 MAKE_PMC_REG(0x020)
|
||||||
#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_DPD_ENABLE_0 MAKE_PMC_REG(0x024)
|
#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x030)
|
||||||
|
#define APBDEV_PMC_REMOVE_CLAMPING_CMD_0 MAKE_PMC_REG(0x034)
|
||||||
#define APBDEV_PMC_CLAMP_STATUS_0 MAKE_PMC_REG(0x02C)
|
#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x038)
|
||||||
|
#define APBDEV_PMC_SCRATCH12_0 MAKE_PMC_REG(0x080)
|
||||||
#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x030)
|
#define APBDEV_PMC_SCRATCH13_0 MAKE_PMC_REG(0x084)
|
||||||
#define APBDEV_PMC_REMOVE_CLAMPING_CMD_0 MAKE_PMC_REG(0x034)
|
#define APBDEV_PMC_SCRATCH18_0 MAKE_PMC_REG(0x098)
|
||||||
#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x038)
|
#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818)
|
||||||
|
#define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4)
|
||||||
#define APBDEV_PMC_SCRATCH12_0 MAKE_PMC_REG(0x080)
|
#define APBDEV_PMC_STICKY_BITS_0 MAKE_PMC_REG(0x2C0)
|
||||||
#define APBDEV_PMC_SCRATCH13_0 MAKE_PMC_REG(0x084)
|
#define APBDEV_PMC_SEC_DISABLE2_0 MAKE_PMC_REG(0x2C4)
|
||||||
#define APBDEV_PMC_SCRATCH18_0 MAKE_PMC_REG(0x098)
|
#define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8)
|
||||||
#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818)
|
#define APBDEV_PMC_SECURE_SCRATCH21_0 MAKE_PMC_REG(0x334)
|
||||||
|
#define APBDEV_PMC_SECURE_SCRATCH32_0 MAKE_PMC_REG(0x360)
|
||||||
#define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4)
|
#define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_PMC_REG(0x368)
|
||||||
|
#define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_PMC_REG(0x36C)
|
||||||
#define APBDEV_PMC_STICKY_BITS_0 MAKE_PMC_REG(0x2C0)
|
#define APBDEV_PMC_SECURE_SCRATCH112_0 MAKE_PMC_REG(0xB18)
|
||||||
#define APBDEV_PMC_SEC_DISABLE2_0 MAKE_PMC_REG(0x2C4)
|
#define APBDEV_PMC_SECURE_SCRATCH113_0 MAKE_PMC_REG(0xB1C)
|
||||||
#define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8)
|
#define APBDEV_PMC_SECURE_SCRATCH114_0 MAKE_PMC_REG(0xB20)
|
||||||
|
#define APBDEV_PMC_SECURE_SCRATCH115_0 MAKE_PMC_REG(0xB24)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH21_0 MAKE_PMC_REG(0x334)
|
#define APBDEV_PMC_FUSE_CTRL MAKE_PMC_REG(0x450)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH32_0 MAKE_PMC_REG(0x360)
|
#define APBDEV_PMC_IO_DPD3_REQ_0 MAKE_PMC_REG(0x45C)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_PMC_REG(0x368)
|
#define APBDEV_PMC_IO_DPD3_STATUS_0 MAKE_PMC_REG(0x460)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_PMC_REG(0x36C)
|
#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_SECURE_SCRATCH112_0 MAKE_PMC_REG(0xB18)
|
#define APBDEV_PMC_SET_SW_CLAMP_0 MAKE_PMC_REG(0x47C)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH113_0 MAKE_PMC_REG(0xB1C)
|
#define APBDEV_PMC_DDR_CNTRL_0 MAKE_PMC_REG(0x4E4)
|
||||||
#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
|
#endif
|
||||||
|
|||||||
@@ -36,20 +36,20 @@ static void __attribute__((__noinline__)) ll_init(volatile se_ll_t *ll, void *bu
|
|||||||
}
|
}
|
||||||
|
|
||||||
void se_check_error_status_reg(void) {
|
void se_check_error_status_reg(void) {
|
||||||
if (se_get_regs()->ERR_STATUS_REG) {
|
if (se_get_regs()->SE_ERR_STATUS) {
|
||||||
reboot();
|
reboot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_check_for_error(void) {
|
void se_check_for_error(void) {
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
volatile tegra_se_t *se = se_get_regs();
|
||||||
if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) {
|
if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) {
|
||||||
reboot();
|
reboot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_verify_flags_cleared(void) {
|
void se_verify_flags_cleared(void) {
|
||||||
if (se_get_regs()->FLAGS_REG & 3) {
|
if (se_get_regs()->SE_STATUS & 3) {
|
||||||
reboot();
|
reboot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,8 +63,8 @@ void clear_aes_keyslot(unsigned int keyslot) {
|
|||||||
|
|
||||||
/* Zero out the whole keyslot and IV. */
|
/* Zero out the whole keyslot and IV. */
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
for (unsigned int i = 0; i < 0x10; i++) {
|
||||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
|
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
|
||||||
se->AES_KEYTABLE_DATA = 0;
|
se->SE_CRYPTO_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,13 +78,13 @@ void clear_rsa_keyslot(unsigned int keyslot) {
|
|||||||
/* Zero out the whole keyslot. */
|
/* Zero out the whole keyslot. */
|
||||||
for (unsigned int i = 0; i < 0x40; i++) {
|
for (unsigned int i = 0; i < 0x40; i++) {
|
||||||
/* Select Keyslot Modulus[i] */
|
/* Select Keyslot Modulus[i] */
|
||||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
|
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
|
||||||
se->RSA_KEYTABLE_DATA = 0;
|
se->SE_RSA_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < 0x40; i++) {
|
for (unsigned int i = 0; i < 0x40; i++) {
|
||||||
/* Select Keyslot Expontent[i] */
|
/* Select Keyslot Expontent[i] */
|
||||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
||||||
se->RSA_KEYTABLE_DATA = 0;
|
se->SE_RSA_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,8 +96,8 @@ void clear_aes_keyslot_iv(unsigned int keyslot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (0x10 >> 2); i++) {
|
for (size_t i = 0; i < (0x10 >> 2); i++) {
|
||||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
||||||
se->AES_KEYTABLE_DATA = 0;
|
se->SE_CRYPTO_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,15 +111,15 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v
|
|||||||
ll_init(&out_ll, dst, dst_size);
|
ll_init(&out_ll, dst, dst_size);
|
||||||
|
|
||||||
/* Set the LLs. */
|
/* Set the LLs. */
|
||||||
se->IN_LL_ADDR_REG = (uint32_t)(&in_ll);
|
se->SE_IN_LL_ADDR = (uint32_t)(&in_ll);
|
||||||
se->OUT_LL_ADDR_REG = (uint32_t) (&out_ll);
|
se->SE_OUT_LL_ADDR = (uint32_t) (&out_ll);
|
||||||
|
|
||||||
/* Set registers for operation. */
|
/* Set registers for operation. */
|
||||||
se->ERR_STATUS_REG = se->ERR_STATUS_REG;
|
se->SE_ERR_STATUS = se->SE_ERR_STATUS;
|
||||||
se->INT_STATUS_REG = se->INT_STATUS_REG;
|
se->SE_INT_STATUS = se->SE_INT_STATUS;
|
||||||
se->OPERATION_REG = op;
|
se->SE_OPERATION = op;
|
||||||
|
|
||||||
while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
|
while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ }
|
||||||
se_check_for_error();
|
se_check_for_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Trigger AES operation. */
|
/* Trigger AES operation. */
|
||||||
se_get_regs()->BLOCK_COUNT_REG = 0;
|
se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
|
trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
|
||||||
|
|
||||||
/* Copy output data into dst. */
|
/* Copy output data into dst. */
|
||||||
@@ -154,8 +154,8 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
|
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
|
||||||
se->CRYPTO_REG = keyslot << 24 | 0x100;
|
se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100;
|
||||||
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,8 +166,8 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size,
|
|||||||
reboot();
|
reboot();
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
|
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY);
|
||||||
se->CRYPTO_REG = keyslot << 24;
|
se->SE_CRYPTO_CONFIG = keyslot << 24;
|
||||||
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,16 +198,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
|
|||||||
shift_left_xor_rb(derived_key);
|
shift_left_xor_rb(derived_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | (0x145);
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145);
|
||||||
clear_aes_keyslot_iv(keyslot);
|
clear_aes_keyslot_iv(keyslot);
|
||||||
|
|
||||||
unsigned int num_blocks = (data_size + 0xF) >> 4;
|
unsigned int num_blocks = (data_size + 0xF) >> 4;
|
||||||
/* Handle aligned blocks. */
|
/* Handle aligned blocks. */
|
||||||
if (num_blocks > 1) {
|
if (num_blocks > 1) {
|
||||||
se->BLOCK_COUNT_REG = num_blocks - 2;
|
se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2;
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
|
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
|
||||||
se->CRYPTO_REG |= 0x80;
|
se->SE_CRYPTO_CONFIG |= 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create final block. */
|
/* Create final block. */
|
||||||
@@ -224,12 +224,12 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Perform last operation. */
|
/* Perform last operation. */
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
|
trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
|
||||||
|
|
||||||
/* Copy output CMAC. */
|
/* Copy output CMAC. */
|
||||||
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
|
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
|
||||||
((uint32_t *)cmac)[i] = ((volatile uint32_t *)se->HASH_RESULT_REG)[i];
|
((uint32_t *)cmac)[i] = ((volatile uint32_t *)se->SE_HASH_RESULT)[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,9 +244,9 @@ void se_aes_256_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, co
|
|||||||
reboot();
|
reboot();
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY) | (0x202 << 16);
|
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY) | (0x202 << 16);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | 0x66;
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x66;
|
||||||
clear_aes_keyslot_iv(keyslot);
|
clear_aes_keyslot_iv(keyslot);
|
||||||
se->BLOCK_COUNT_REG = (src_size >> 4) - 1;
|
se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1;
|
||||||
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
|
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
|
||||||
}
|
}
|
||||||
@@ -92,71 +92,59 @@
|
|||||||
#define RSA_2048_BYTES 0x100
|
#define RSA_2048_BYTES 0x100
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t _0x0;
|
uint32_t SE_SE_SECURITY;
|
||||||
uint32_t _0x4;
|
uint32_t SE_TZRAM_SECURITY;
|
||||||
uint32_t OPERATION_REG;
|
uint32_t SE_OPERATION;
|
||||||
uint32_t INT_ENABLE_REG;
|
uint32_t SE_INT_ENABLE;
|
||||||
uint32_t INT_STATUS_REG;
|
uint32_t SE_INT_STATUS;
|
||||||
uint32_t CONFIG_REG;
|
uint32_t SE_CONFIG;
|
||||||
uint32_t IN_LL_ADDR_REG;
|
uint32_t SE_IN_LL_ADDR;
|
||||||
uint32_t _0x1C;
|
uint32_t SE_IN_CUR_BYTE_ADDR;
|
||||||
uint32_t _0x20;
|
uint32_t SE_IN_CUR_LL_ID;
|
||||||
uint32_t OUT_LL_ADDR_REG;
|
uint32_t SE_OUT_LL_ADDR;
|
||||||
uint32_t _0x28;
|
uint32_t SE_OUT_CUR_BYTE_ADDR;
|
||||||
uint32_t _0x2C;
|
uint32_t SE_OUT_CUR_LL_ID;
|
||||||
uint8_t HASH_RESULT_REG[0x20];
|
uint32_t SE_HASH_RESULT[0x10];
|
||||||
uint8_t _0x50[0x20];
|
uint32_t SE_CTX_SAVE_CONFIG;
|
||||||
uint32_t CONTEXT_SAVE_CONFIG_REG;
|
uint32_t _0x74[0x63];
|
||||||
uint8_t _0x74[0x18C];
|
uint32_t SE_SHA_CONFIG;
|
||||||
uint32_t SHA_CONFIG_REG;
|
uint32_t SE_SHA_MSG_LENGTH[0x4];
|
||||||
uint32_t SHA_MSG_LENGTH_REG;
|
uint32_t SE_SHA_MSG_LEFT[0x4];
|
||||||
uint32_t _0x208;
|
uint32_t _0x224[0x17];
|
||||||
uint32_t _0x20C;
|
uint32_t SE_CRYPTO_SECURITY_PERKEY;
|
||||||
uint32_t _0x210;
|
uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10];
|
||||||
uint32_t SHA_MSG_LEFT_REG;
|
uint32_t _0x2C4[0x10];
|
||||||
uint32_t _0x218;
|
uint32_t SE_CRYPTO_CONFIG;
|
||||||
uint32_t _0x21C;
|
uint32_t SE_CRYPTO_LINEAR_CTR[0x4];
|
||||||
uint32_t _0x220;
|
uint32_t SE_CRYPTO_LAST_BLOCK;
|
||||||
uint32_t _0x224;
|
uint32_t SE_CRYPTO_KEYTABLE_ADDR;
|
||||||
uint8_t _0x228[0x58];
|
uint32_t SE_CRYPTO_KEYTABLE_DATA;
|
||||||
uint32_t AES_KEY_READ_DISABLE_REG;
|
uint32_t _0x324[0x3];
|
||||||
uint32_t AES_KEYSLOT_FLAGS[0x10];
|
uint32_t SE_CRYPTO_KEYTABLE_DST;
|
||||||
uint8_t _0x2C4[0x3C];
|
uint32_t _0x334[0x3];
|
||||||
uint32_t _0x300;
|
uint32_t SE_RNG_CONFIG;
|
||||||
uint32_t CRYPTO_REG;
|
uint32_t SE_RNG_SRC_CONFIG;
|
||||||
uint32_t CRYPTO_CTR_REG[4];
|
uint32_t SE_RNG_RESEED_INTERVAL;
|
||||||
uint32_t BLOCK_COUNT_REG;
|
uint32_t _0x34C[0x2D];
|
||||||
uint32_t AES_KEYTABLE_ADDR;
|
uint32_t SE_RSA_CONFIG;
|
||||||
uint32_t AES_KEYTABLE_DATA;
|
uint32_t SE_RSA_KEY_SIZE;
|
||||||
uint32_t _0x324;
|
uint32_t SE_RSA_EXP_SIZE;
|
||||||
uint32_t _0x328;
|
uint32_t SE_RSA_SECURITY_PERKEY;
|
||||||
uint32_t _0x32C;
|
uint32_t SE_RSA_KEYTABLE_ACCESS[0x2];
|
||||||
uint32_t CRYPTO_KEYTABLE_DST_REG;
|
uint32_t _0x418[0x2];
|
||||||
uint8_t _0x334[0xC];
|
uint32_t SE_RSA_KEYTABLE_ADDR;
|
||||||
uint32_t RNG_CONFIG_REG;
|
uint32_t SE_RSA_KEYTABLE_DATA;
|
||||||
uint32_t RNG_SRC_CONFIG_REG;
|
uint32_t SE_RSA_OUTPUT[0x40];
|
||||||
uint32_t RNG_RESEED_INTERVAL_REG;
|
uint32_t _0x528[0xB6];
|
||||||
uint8_t _0x34C[0xB4];
|
uint32_t SE_STATUS;
|
||||||
uint32_t RSA_CONFIG;
|
uint32_t SE_ERR_STATUS;
|
||||||
uint32_t RSA_KEY_SIZE_REG;
|
uint32_t SE_MISC;
|
||||||
uint32_t RSA_EXP_SIZE_REG;
|
uint32_t SE_SPARE;
|
||||||
uint32_t RSA_KEY_READ_DISABLE_REG;
|
uint32_t SE_ENTROPY_DEBUG_COUNTER;
|
||||||
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 _0x814;
|
||||||
uint32_t _0x818;
|
uint32_t _0x818;
|
||||||
uint32_t _0x81C;
|
uint32_t _0x81C;
|
||||||
uint8_t _0x820[0x17E0];
|
uint32_t _0x820[0x5F8];
|
||||||
} tegra_se_t;
|
} tegra_se_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ void secmon_restore_to_tzram(const uint32_t target_firmware) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make security engine require secure busmaster. */
|
/* Make security engine require secure busmaster. */
|
||||||
se_get_regs()->_0x4 = 0;
|
se_get_regs()->SE_TZRAM_SECURITY = 0;
|
||||||
|
|
||||||
/* TODO: se_verify_keys_unreadable(); */
|
/* TODO: se_verify_keys_unreadable(); */
|
||||||
|
|
||||||
|
|||||||
@@ -13,14 +13,14 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EXOSPHERE_WARMBOOT_BIN_UTILS_H
|
#ifndef EXOSPHERE_WARMBOOT_BIN_UTILS_H
|
||||||
#define EXOSPHERE_WARMBOOT_BIN_UTILS_H
|
#define EXOSPHERE_WARMBOOT_BIN_UTILS_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <atmosphere.h>
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#define BIT(n) (1u << (n))
|
#define BIT(n) (1u << (n))
|
||||||
#define BITL(n) (1ull << (n))
|
#define BITL(n) (1ull << (n))
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ void setup_dram_magic_numbers(void) {
|
|||||||
void bootup_misc_mmio(void) {
|
void bootup_misc_mmio(void) {
|
||||||
/* Initialize Fuse registers. */
|
/* Initialize Fuse registers. */
|
||||||
fuse_init();
|
fuse_init();
|
||||||
|
|
||||||
/* Verify Security Engine sanity. */
|
/* Verify Security Engine sanity. */
|
||||||
se_set_in_context_save_mode(false);
|
se_set_in_context_save_mode(false);
|
||||||
/* TODO: se_verify_keys_unreadable(); */
|
/* TODO: se_verify_keys_unreadable(); */
|
||||||
@@ -85,6 +85,9 @@ void bootup_misc_mmio(void) {
|
|||||||
setup_dram_magic_numbers();
|
setup_dram_magic_numbers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* On 9.0.0+, Nintendo writes random values to context save scratch here, and locks the SRK scratch. */
|
||||||
|
/* There's no real need for us to do this, so we won't. */
|
||||||
|
|
||||||
/* Mark TMR5, TMR6, TMR7, TMR8, WDT0, WDT1, WDT2 and WDT3 as secure. */
|
/* Mark TMR5, TMR6, TMR7, TMR8, WDT0, WDT1, WDT2 and WDT3 as secure. */
|
||||||
SHARED_TIMER_SECURE_CFG_0 = 0xF1E0;
|
SHARED_TIMER_SECURE_CFG_0 = 0xF1E0;
|
||||||
|
|
||||||
@@ -111,7 +114,7 @@ void bootup_misc_mmio(void) {
|
|||||||
MAKE_MC_REG(MC_SECURITY_CFG1) = 0;
|
MAKE_MC_REG(MC_SECURITY_CFG1) = 0;
|
||||||
MAKE_MC_REG(MC_SECURITY_CFG3) = 3;
|
MAKE_MC_REG(MC_SECURITY_CFG3) = 3;
|
||||||
configure_default_carveouts();
|
configure_default_carveouts();
|
||||||
|
|
||||||
/* Mark registers secure world only. */
|
/* Mark registers secure world only. */
|
||||||
if (exosphere_get_target_firmware() == ATMOSPHERE_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_REG0_0 = APB_SSER0_SATA_AUX | APB_SSER0_DTV | APB_SSER0_QSPI | APB_SSER0_SATA | APB_SSER0_LA;
|
||||||
@@ -140,28 +143,26 @@ void bootup_misc_mmio(void) {
|
|||||||
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = sec_disable_2;
|
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = sec_disable_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset Translation Enable Registers. */
|
/* Reset Translation Enable registers. */
|
||||||
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_0) = 0xFFFFFFFF;
|
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_1) = 0xFFFFFFFF;
|
||||||
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_2) = 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_3) = 0xFFFFFFFF;
|
||||||
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_4) = 0xFFFFFFFF;
|
MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_4) = 0xFFFFFFFF;
|
||||||
|
|
||||||
/* TODO: What are these MC reg writes? */
|
/* Set SMMU ASID security registers. */
|
||||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
MAKE_MC_REG(0x038) = 0xE;
|
MAKE_MC_REG(MC_SMMU_ASID_SECURITY) = 0xE;
|
||||||
} else {
|
} else {
|
||||||
MAKE_MC_REG(0x038) = 0x0;
|
MAKE_MC_REG(MC_SMMU_ASID_SECURITY) = 0x0;
|
||||||
}
|
}
|
||||||
MAKE_MC_REG(0x03C) = 0;
|
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_1) = 0;
|
||||||
|
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_2) = 0;
|
||||||
/* MISC registers. */
|
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_3) = 0;
|
||||||
MAKE_MC_REG(0x9E0) = 0;
|
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_4) = 0;
|
||||||
MAKE_MC_REG(0x9E4) = 0;
|
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_5) = 0;
|
||||||
MAKE_MC_REG(0x9E8) = 0;
|
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_6) = 0;
|
||||||
MAKE_MC_REG(0x9EC) = 0;
|
MAKE_MC_REG(MC_SMMU_ASID_SECURITY_7) = 0;
|
||||||
MAKE_MC_REG(0x9F0) = 0;
|
|
||||||
MAKE_MC_REG(0x9F4) = 0;
|
|
||||||
|
|
||||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
MAKE_MC_REG(MC_SMMU_PTB_ASID) = 0;
|
MAKE_MC_REG(MC_SMMU_PTB_ASID) = 0;
|
||||||
@@ -176,7 +177,7 @@ void bootup_misc_mmio(void) {
|
|||||||
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
||||||
MAKE_MC_REG(MC_SMMU_CONFIG) = 1; /* Enable SMMU. */
|
MAKE_MC_REG(MC_SMMU_CONFIG) = 1; /* Enable SMMU. */
|
||||||
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
(void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
|
||||||
|
|
||||||
/* Clear RESET Vector, setup CPU Secure Boot RESET Vectors. */
|
/* Clear RESET Vector, setup CPU Secure Boot RESET Vectors. */
|
||||||
uint32_t reset_vec;
|
uint32_t reset_vec;
|
||||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
|
||||||
@@ -204,7 +205,7 @@ void bootup_misc_mmio(void) {
|
|||||||
intr_set_enabled(INTERRUPT_ID_SECURITY_ENGINE, 1);
|
intr_set_enabled(INTERRUPT_ID_SECURITY_ENGINE, 1);
|
||||||
intr_set_cpu_mask(INTERRUPT_ID_SECURITY_ENGINE, 8);
|
intr_set_cpu_mask(INTERRUPT_ID_SECURITY_ENGINE, 8);
|
||||||
intr_set_edge_level(INTERRUPT_ID_SECURITY_ENGINE, 0);
|
intr_set_edge_level(INTERRUPT_ID_SECURITY_ENGINE, 0);
|
||||||
|
|
||||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
intr_set_priority(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
|
intr_set_priority(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
|
||||||
intr_set_group(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
|
intr_set_group(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
|
||||||
@@ -218,7 +219,7 @@ void bootup_misc_mmio(void) {
|
|||||||
uart_config(UART_A);
|
uart_config(UART_A);
|
||||||
clkrst_reboot(CARDEVICE_UARTA);
|
clkrst_reboot(CARDEVICE_UARTA);
|
||||||
uart_init(UART_A, 115200);
|
uart_init(UART_A, 115200);
|
||||||
|
|
||||||
intr_register_handler(INTERRUPT_ID_SECURITY_ENGINE, se_operation_completed);
|
intr_register_handler(INTERRUPT_ID_SECURITY_ENGINE, se_operation_completed);
|
||||||
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
intr_register_handler(INTERRUPT_ID_ACTIVITY_MONITOR_4X, actmon_interrupt_handler);
|
intr_register_handler(INTERRUPT_ID_ACTIVITY_MONITOR_4X, actmon_interrupt_handler);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@@ -30,7 +30,7 @@ static inline uint32_t get_special_clk_reg(CarDevice dev) {
|
|||||||
case CARDEVICE_BPMP: return 0;
|
case CARDEVICE_BPMP: return 0;
|
||||||
default: generic_panic();
|
default: generic_panic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t get_special_clk_val(CarDevice dev) {
|
static inline uint32_t get_special_clk_val(CarDevice dev) {
|
||||||
switch (dev) {
|
switch (dev) {
|
||||||
@@ -45,7 +45,7 @@ static inline uint32_t get_special_clk_val(CarDevice dev) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t g_clk_reg_offsets[NUM_CAR_BANKS] = {0x010, 0x014, 0x018, 0x360, 0x364, 0x280, 0x298};
|
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_rst_reg_offsets[NUM_CAR_BANKS] = {0x004, 0x008, 0x00C, 0x358, 0x35C, 0x28C, 0x2A4};
|
||||||
|
|
||||||
void clk_enable(CarDevice dev) {
|
void clk_enable(CarDevice dev) {
|
||||||
uint32_t special_reg;
|
uint32_t special_reg;
|
||||||
@@ -67,7 +67,6 @@ void rst_disable(CarDevice dev) {
|
|||||||
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
|
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void clkrst_enable(CarDevice dev) {
|
void clkrst_enable(CarDevice dev) {
|
||||||
clk_enable(dev);
|
clk_enable(dev);
|
||||||
rst_disable(dev);
|
rst_disable(dev);
|
||||||
@@ -82,3 +81,7 @@ void clkrst_reboot(CarDevice dev) {
|
|||||||
clkrst_disable(dev);
|
clkrst_disable(dev);
|
||||||
clkrst_enable(dev);
|
clkrst_enable(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clkrst_enable_fuse_regs(bool enable) {
|
||||||
|
CLK_RST_CONTROLLER_MISC_CLK_ENB_0 = ((CLK_RST_CONTROLLER_MISC_CLK_ENB_0 & 0xEFFFFFFF) | ((enable & 1) << 28));
|
||||||
|
}
|
||||||
@@ -51,7 +51,8 @@ void rst_disable(CarDevice dev);
|
|||||||
|
|
||||||
void clkrst_enable(CarDevice dev);
|
void clkrst_enable(CarDevice dev);
|
||||||
void clkrst_disable(CarDevice dev);
|
void clkrst_disable(CarDevice dev);
|
||||||
|
|
||||||
void clkrst_reboot(CarDevice dev);
|
void clkrst_reboot(CarDevice dev);
|
||||||
|
|
||||||
|
void clkrst_enable_fuse_regs(bool enable);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,9 +13,9 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <atmosphere/version.h>
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#include "bootconfig.h"
|
#include "bootconfig.h"
|
||||||
#include "configitem.h"
|
#include "configitem.h"
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
static bool g_hiz_mode_enabled = false;
|
static bool g_hiz_mode_enabled = false;
|
||||||
static bool g_debugmode_override_user = false, g_debugmode_override_priv = false;
|
static bool g_debugmode_override_user = false, g_debugmode_override_priv = false;
|
||||||
static bool g_enable_usermode_exception_handlers = true;
|
static bool g_enable_usermode_exception_handlers = true;
|
||||||
|
static bool g_enable_usermode_pmu_access = false;
|
||||||
|
|
||||||
uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
|
uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
|
||||||
switch (item) {
|
switch (item) {
|
||||||
@@ -63,14 +64,14 @@ uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
|
|||||||
/* Set SVC handler to jump to reboot stub in IRAM. */
|
/* 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) + 0x520ull) = 0x4003F000;
|
||||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x53Cull) = 0x6000F208;
|
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x53Cull) = 0x6000F208;
|
||||||
|
|
||||||
/* Copy reboot stub payload. */
|
/* Copy reboot stub payload. */
|
||||||
ams_map_irampage(0x4003F000);
|
ams_map_irampage(0x4003F000);
|
||||||
for (unsigned int i = 0; i < rebootstub_bin_size; i += 4) {
|
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);
|
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE) + i) = read32le(rebootstub_bin, i);
|
||||||
}
|
}
|
||||||
ams_unmap_irampage();
|
ams_unmap_irampage();
|
||||||
|
|
||||||
/* Ensure stub is flushed. */
|
/* Ensure stub is flushed. */
|
||||||
flush_dcache_all();
|
flush_dcache_all();
|
||||||
break;
|
break;
|
||||||
@@ -95,7 +96,7 @@ uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
|
|||||||
/* Set SVC handler to jump to reboot stub in IRAM. */
|
/* 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) + 0x520ull) = 0x4003F000;
|
||||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x53Cull) = 0x6000F208;
|
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x53Cull) = 0x6000F208;
|
||||||
|
|
||||||
/* Copy reboot stub payload. */
|
/* Copy reboot stub payload. */
|
||||||
ams_map_irampage(0x4003F000);
|
ams_map_irampage(0x4003F000);
|
||||||
for (unsigned int i = 0; i < rebootstub_bin_size; i += 4) {
|
for (unsigned int i = 0; i < rebootstub_bin_size; i += 4) {
|
||||||
@@ -104,7 +105,7 @@ uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
|
|||||||
/* Tell rebootstub to shut down. */
|
/* Tell rebootstub to shut down. */
|
||||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE) + 0x10) = 0x0;
|
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE) + 0x10) = 0x0;
|
||||||
ams_unmap_irampage();
|
ams_unmap_irampage();
|
||||||
|
|
||||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10;
|
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10;
|
||||||
while (1) { }
|
while (1) { }
|
||||||
}
|
}
|
||||||
@@ -112,7 +113,7 @@ uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
|
|||||||
default:
|
default:
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +169,10 @@ void configitem_disable_usermode_exception_handlers(void) {
|
|||||||
g_enable_usermode_exception_handlers = false;
|
g_enable_usermode_exception_handlers = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void configitem_enable_usermode_pmu_access(void) {
|
||||||
|
g_enable_usermode_pmu_access = true;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue) {
|
uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue) {
|
||||||
uint32_t result = 0;
|
uint32_t result = 0;
|
||||||
switch (item) {
|
switch (item) {
|
||||||
@@ -182,11 +187,10 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
|
|||||||
*p_outvalue = INTERRUPT_ID_USER_SECURITY_ENGINE;
|
*p_outvalue = INTERRUPT_ID_USER_SECURITY_ENGINE;
|
||||||
break;
|
break;
|
||||||
case CONFIGITEM_VERSION:
|
case CONFIGITEM_VERSION:
|
||||||
/* Always returns maxver - 1 on hardware. */
|
*p_outvalue = fuse_get_expected_fuse_version(exosphere_get_target_firmware());
|
||||||
*p_outvalue = PACKAGE2_MAXVER_400_410 - 1;
|
|
||||||
break;
|
break;
|
||||||
case CONFIGITEM_HARDWARETYPE:
|
case CONFIGITEM_HARDWARETYPE:
|
||||||
*p_outvalue = fuse_get_hardware_type();
|
*p_outvalue = fuse_get_hardware_type(exosphere_get_target_firmware());
|
||||||
break;
|
break;
|
||||||
case CONFIGITEM_ISRETAIL:
|
case CONFIGITEM_ISRETAIL:
|
||||||
*p_outvalue = fuse_get_retail_type();
|
*p_outvalue = fuse_get_retail_type();
|
||||||
@@ -222,6 +226,10 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
|
|||||||
if (g_enable_usermode_exception_handlers) {
|
if (g_enable_usermode_exception_handlers) {
|
||||||
config |= KERNELCONFIGFLAG_ENABLE_USER_EXCEPTION_HANDLERS;
|
config |= KERNELCONFIGFLAG_ENABLE_USER_EXCEPTION_HANDLERS;
|
||||||
}
|
}
|
||||||
|
/* Allow for enabling usermode pmu access. */
|
||||||
|
if (g_enable_usermode_pmu_access) {
|
||||||
|
config |= KERNELCONFIGFLAG_ENABLE_USER_PMU_ACCESS;
|
||||||
|
}
|
||||||
*p_outvalue = config;
|
*p_outvalue = config;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -262,7 +270,7 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
|
|||||||
break;
|
break;
|
||||||
case CONFIGITEM_EXOSPHERE_VERSION:
|
case CONFIGITEM_EXOSPHERE_VERSION:
|
||||||
/* UNOFFICIAL: Gets information about the current exosphere version. */
|
/* UNOFFICIAL: Gets information about the current exosphere version. */
|
||||||
*p_outvalue = ((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MAJOR & 0xFF) << 32ull) |
|
*p_outvalue = ((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MAJOR & 0xFF) << 32ull) |
|
||||||
((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MINOR & 0xFF) << 24ull) |
|
((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MINOR & 0xFF) << 24ull) |
|
||||||
((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MICRO & 0xFF) << 16ull) |
|
((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MICRO & 0xFF) << 16ull) |
|
||||||
((uint64_t)(exosphere_get_target_firmware() & 0xFF) << 8ull) |
|
((uint64_t)(exosphere_get_target_firmware() & 0xFF) << 8ull) |
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EXOSPHERE_CFG_ITEM_H
|
#ifndef EXOSPHERE_CFG_ITEM_H
|
||||||
#define EXOSPHERE_CFG_ITEM_H
|
#define EXOSPHERE_CFG_ITEM_H
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ typedef enum {
|
|||||||
CONFIGITEM_NEWHARDWARETYPE_5X = 15,
|
CONFIGITEM_NEWHARDWARETYPE_5X = 15,
|
||||||
CONFIGITEM_NEWKEYGENERATION_5X = 16,
|
CONFIGITEM_NEWKEYGENERATION_5X = 16,
|
||||||
CONFIGITEM_PACKAGE2HASH_5X = 17,
|
CONFIGITEM_PACKAGE2HASH_5X = 17,
|
||||||
|
|
||||||
/* These are unofficial, for usage by Exosphere. */
|
/* These are unofficial, for usage by Exosphere. */
|
||||||
CONFIGITEM_EXOSPHERE_VERSION = 65000,
|
CONFIGITEM_EXOSPHERE_VERSION = 65000,
|
||||||
CONFIGITEM_NEEDS_REBOOT = 65001,
|
CONFIGITEM_NEEDS_REBOOT = 65001,
|
||||||
@@ -61,6 +61,7 @@ bool configitem_is_debugmode_priv(void);
|
|||||||
|
|
||||||
void configitem_set_debugmode_override(bool user, bool priv);
|
void configitem_set_debugmode_override(bool user, bool priv);
|
||||||
void configitem_disable_usermode_exception_handlers(void);
|
void configitem_disable_usermode_exception_handlers(void);
|
||||||
|
void configitem_enable_usermode_pmu_access(void);
|
||||||
void configitem_set_hiz_mode_enabled(bool enabled);
|
void configitem_set_hiz_mode_enabled(bool enabled);
|
||||||
|
|
||||||
uint64_t configitem_get_hardware_type(void);
|
uint64_t configitem_get_hardware_type(void);
|
||||||
|
|||||||
@@ -13,12 +13,12 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EXOSPHERE_EMUMMC_CONFIG_H
|
#ifndef EXOSPHERE_EMUMMC_CONFIG_H
|
||||||
#define EXOSPHERE_EMUMMC_CONFIG_H
|
#define EXOSPHERE_EMUMMC_CONFIG_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <atmosphere.h>
|
#include <vapours/ams_version.h>
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
/* "EFS0" */
|
/* "EFS0" */
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Declare the exception vector table, enforcing it is aligned on a
|
* Declare the exception vector table, enforcing it is aligned on a
|
||||||
@@ -92,7 +92,7 @@ vector_entry fiq_spx
|
|||||||
vector_entry serror_spx
|
vector_entry serror_spx
|
||||||
b unknown_exception
|
b unknown_exception
|
||||||
check_vector_size serror_spx
|
check_vector_size serror_spx
|
||||||
|
|
||||||
/* Lower EL, A64 */
|
/* Lower EL, A64 */
|
||||||
vector_entry synch_a64
|
vector_entry synch_a64
|
||||||
stp x29, x30, [sp, #-0x10]!
|
stp x29, x30, [sp, #-0x10]!
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
#include "memory_map.h"
|
#include "memory_map.h"
|
||||||
|
|
||||||
static exosphere_config_t g_exosphere_cfg = {MAGIC_EXOSPHERE_CONFIG, ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG, EXOSPHERE_FLAGS_DEFAULT};
|
static exosphere_config_t g_exosphere_cfg = {MAGIC_EXOSPHERE_CONFIG, ATMOSPHERE_TARGET_FIRMWARE_CURRENT, EXOSPHERE_FLAGS_DEFAULT};
|
||||||
static bool g_has_loaded_config = false;
|
static bool g_has_loaded_config = false;
|
||||||
|
|
||||||
#define EXOSPHERE_CHECK_FLAG(flag) ((g_exosphere_cfg.flags & flag) != 0)
|
#define EXOSPHERE_CHECK_FLAG(flag) ((g_exosphere_cfg.flags & flag) != 0)
|
||||||
@@ -84,6 +84,14 @@ unsigned int exosphere_should_disable_usermode_exception_handlers(void) {
|
|||||||
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS);
|
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int exosphere_should_enable_usermode_pmu_access(void) {
|
||||||
|
if (!g_has_loaded_config) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS);
|
||||||
|
}
|
||||||
|
|
||||||
const exo_emummc_config_t *exosphere_get_emummc_config(void) {
|
const exo_emummc_config_t *exosphere_get_emummc_config(void) {
|
||||||
if (!g_has_loaded_config) {
|
if (!g_has_loaded_config) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#define EXOSPHERE_EXOSPHERE_CONFIG_H
|
#define EXOSPHERE_EXOSPHERE_CONFIG_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <atmosphere.h>
|
#include <vapours/ams_version.h>
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include "memory_map.h"
|
#include "memory_map.h"
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
|
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
|
||||||
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
|
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
|
||||||
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
|
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
|
||||||
|
#define EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS (1 << 4u)
|
||||||
#define EXOSPHERE_FLAGS_DEFAULT (EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV)
|
#define EXOSPHERE_FLAGS_DEFAULT (EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -58,6 +59,7 @@ unsigned int exosphere_should_perform_620_keygen(void);
|
|||||||
unsigned int exosphere_should_override_debugmode_priv(void);
|
unsigned int exosphere_should_override_debugmode_priv(void);
|
||||||
unsigned int exosphere_should_override_debugmode_user(void);
|
unsigned int exosphere_should_override_debugmode_user(void);
|
||||||
unsigned int exosphere_should_disable_usermode_exception_handlers(void);
|
unsigned int exosphere_should_disable_usermode_exception_handlers(void);
|
||||||
|
unsigned int exosphere_should_enable_usermode_pmu_access(void);
|
||||||
|
|
||||||
const exo_emummc_config_t *exosphere_get_emummc_config(void);
|
const exo_emummc_config_t *exosphere_get_emummc_config(void);
|
||||||
|
|
||||||
@@ -66,7 +68,7 @@ static inline unsigned int exosphere_get_target_firmware_for_init(void) {
|
|||||||
if (magic == MAGIC_EXOSPHERE_CONFIG) {
|
if (magic == MAGIC_EXOSPHERE_CONFIG) {
|
||||||
return MAILBOX_EXOSPHERE_CONFIG_PHYS.target_firmware;
|
return MAILBOX_EXOSPHERE_CONFIG_PHYS.target_firmware;
|
||||||
} else {
|
} else {
|
||||||
return ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG;
|
return ATMOSPHERE_TARGET_FIRMWARE_CURRENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,185 +13,168 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
#include "utils.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#include "exocfg.h"
|
|
||||||
|
|
||||||
#include "masterkey.h"
|
#include "masterkey.h"
|
||||||
|
#include "pmc.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
static bool g_has_checked_for_rcm_bug_patch = false;
|
static bool g_has_checked_for_rcm_bug_patch = false;
|
||||||
static bool g_has_rcm_bug_patch = false;
|
static bool g_has_rcm_bug_patch = false;
|
||||||
|
|
||||||
/* Prototypes for internal commands. */
|
/* Prototypes for internal commands. */
|
||||||
void fuse_make_regs_visible(void);
|
|
||||||
|
|
||||||
void fuse_enable_power(void);
|
void fuse_enable_power(void);
|
||||||
void fuse_disable_power(void);
|
void fuse_disable_power(void);
|
||||||
void fuse_wait_idle(void);
|
void fuse_wait_idle(void);
|
||||||
|
|
||||||
/* Initialize the FUSE driver */
|
/* Initialize the fuse driver */
|
||||||
void fuse_init(void)
|
void fuse_init(void) {
|
||||||
{
|
/* Make all fuse registers visible, disable the private key and disable programming. */
|
||||||
fuse_make_regs_visible();
|
clkrst_enable_fuse_regs(true);
|
||||||
fuse_secondary_private_key_disable();
|
fuse_disable_private_key();
|
||||||
fuse_disable_programming();
|
fuse_disable_programming();
|
||||||
|
|
||||||
/* TODO: Should we allow this to be done later? */
|
/* TODO: Should we allow this to be done later? */
|
||||||
if (!g_has_checked_for_rcm_bug_patch) {
|
if (!g_has_checked_for_rcm_bug_patch) {
|
||||||
(void)(fuse_has_rcm_bug_patch());
|
(void)(fuse_has_rcm_bug_patch());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Overrides (iROM patches) and various reads happen here */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make all fuse registers visible */
|
/* Disable access to the private key and set the TZ sticky bit. */
|
||||||
void fuse_make_regs_visible(void)
|
void fuse_disable_private_key(void) {
|
||||||
{
|
FUSE_REGS->FUSE_PRIVATEKEYDISABLE = 0x10;
|
||||||
CLK_RST_CONTROLLER_MISC_CLK_ENB_0 |= BIT(28);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable power to the fuse hardware array */
|
|
||||||
void fuse_enable_power(void)
|
|
||||||
{
|
|
||||||
FUSE_REGS->FUSE_PWR_GOOD_SW = 1;
|
|
||||||
wait(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable power to the fuse hardware array */
|
|
||||||
void fuse_disable_power(void)
|
|
||||||
{
|
|
||||||
FUSE_REGS->FUSE_PWR_GOOD_SW = 0;
|
|
||||||
wait(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for the fuse driver to go idle */
|
|
||||||
void fuse_wait_idle(void)
|
|
||||||
{
|
|
||||||
uint32_t ctrl_val = 0;
|
|
||||||
|
|
||||||
/* Wait for STATE_IDLE */
|
|
||||||
while ((ctrl_val & (0xF0000)) != 0x40000)
|
|
||||||
{
|
|
||||||
wait(1);
|
|
||||||
ctrl_val = FUSE_REGS->FUSE_CTRL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read a fuse from the hardware array */
|
|
||||||
uint32_t fuse_hw_read(uint32_t addr)
|
|
||||||
{
|
|
||||||
fuse_wait_idle();
|
|
||||||
|
|
||||||
/* Program the target address */
|
|
||||||
FUSE_REGS->FUSE_REG_ADDR = addr;
|
|
||||||
|
|
||||||
/* Enable read operation in control register */
|
|
||||||
uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
|
|
||||||
ctrl_val &= ~0x3;
|
|
||||||
ctrl_val |= 0x1; /* Set FUSE_READ command */
|
|
||||||
FUSE_REGS->FUSE_CTRL = ctrl_val;
|
|
||||||
|
|
||||||
fuse_wait_idle();
|
|
||||||
|
|
||||||
return FUSE_REGS->FUSE_REG_READ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write a fuse in the hardware array */
|
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr)
|
|
||||||
{
|
|
||||||
fuse_wait_idle();
|
|
||||||
|
|
||||||
/* Program the target address and value */
|
|
||||||
FUSE_REGS->FUSE_REG_ADDR = addr;
|
|
||||||
FUSE_REGS->FUSE_REG_WRITE = value;
|
|
||||||
|
|
||||||
/* Enable write operation in control register */
|
|
||||||
uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
|
|
||||||
ctrl_val &= ~0x3;
|
|
||||||
ctrl_val |= 0x2; /* Set FUSE_WRITE command */
|
|
||||||
FUSE_REGS->FUSE_CTRL = ctrl_val;
|
|
||||||
|
|
||||||
fuse_wait_idle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sense the fuse hardware array into the shadow cache */
|
|
||||||
void fuse_hw_sense(void)
|
|
||||||
{
|
|
||||||
fuse_wait_idle();
|
|
||||||
|
|
||||||
/* Enable sense operation in control register */
|
|
||||||
uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
|
|
||||||
ctrl_val &= ~0x3;
|
|
||||||
ctrl_val |= 0x3; /* Set FUSE_SENSE command */
|
|
||||||
FUSE_REGS->FUSE_CTRL = ctrl_val;
|
|
||||||
|
|
||||||
fuse_wait_idle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disables all fuse programming. */
|
/* Disables all fuse programming. */
|
||||||
void fuse_disable_programming(void) {
|
void fuse_disable_programming(void) {
|
||||||
FUSE_REGS->FUSE_DIS_PGM = 1;
|
FUSE_REGS->FUSE_DISABLEREGPROGRAM = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */
|
/* Enable power to the fuse hardware array. */
|
||||||
void fuse_secondary_private_key_disable(void) {
|
void fuse_enable_power(void) {
|
||||||
FUSE_REGS->FUSE_PRIVATEKEYDISABLE = 0x10;
|
APBDEV_PMC_FUSE_CTRL &= ~(0x200); /* Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
|
||||||
|
mdelay(1);
|
||||||
|
APBDEV_PMC_FUSE_CTRL |= 0x100; /* Set PMC_FUSE_CTRL_PS18_LATCH_SET. */
|
||||||
|
mdelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Disable power to the fuse hardware array. */
|
||||||
|
void fuse_disable_power(void) {
|
||||||
|
APBDEV_PMC_FUSE_CTRL &= ~(0x100); /* Clear PMC_FUSE_CTRL_PS18_LATCH_SET. */
|
||||||
|
mdelay(1);
|
||||||
|
APBDEV_PMC_FUSE_CTRL |= 0x200; /* Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
|
||||||
|
mdelay(1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Read the SKU info register from the shadow cache */
|
/* Wait for the fuse driver to go idle. */
|
||||||
uint32_t fuse_get_sku_info(void)
|
void fuse_wait_idle(void) {
|
||||||
{
|
uint32_t ctrl_val = 0;
|
||||||
|
|
||||||
|
/* Wait for STATE_IDLE */
|
||||||
|
while ((ctrl_val & (0xF0000)) != 0x40000)
|
||||||
|
ctrl_val = FUSE_REGS->FUSE_FUSECTRL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read a fuse from the hardware array. */
|
||||||
|
uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
|
/* Wait for idle state. */
|
||||||
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
/* Program the target address. */
|
||||||
|
FUSE_REGS->FUSE_FUSEADDR = addr;
|
||||||
|
|
||||||
|
/* Enable read operation in control register. */
|
||||||
|
uint32_t ctrl_val = FUSE_REGS->FUSE_FUSECTRL;
|
||||||
|
ctrl_val &= ~0x3;
|
||||||
|
ctrl_val |= 0x1; /* Set READ command. */
|
||||||
|
FUSE_REGS->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
return FUSE_REGS->FUSE_FUSERDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write a fuse in the hardware array. */
|
||||||
|
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
|
/* Wait for idle state. */
|
||||||
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
/* Program the target address and value. */
|
||||||
|
FUSE_REGS->FUSE_FUSEADDR = addr;
|
||||||
|
FUSE_REGS->FUSE_FUSEWDATA = value;
|
||||||
|
|
||||||
|
/* Enable write operation in control register. */
|
||||||
|
uint32_t ctrl_val = FUSE_REGS->FUSE_FUSECTRL;
|
||||||
|
ctrl_val &= ~0x3;
|
||||||
|
ctrl_val |= 0x2; /* Set WRITE command. */
|
||||||
|
FUSE_REGS->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
|
fuse_wait_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sense the fuse hardware array into the shadow cache. */
|
||||||
|
void fuse_hw_sense(void) {
|
||||||
|
/* Wait for idle state. */
|
||||||
|
fuse_wait_idle();
|
||||||
|
|
||||||
|
/* Enable sense operation in control register */
|
||||||
|
uint32_t ctrl_val = FUSE_REGS->FUSE_FUSECTRL;
|
||||||
|
ctrl_val &= ~0x3;
|
||||||
|
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
||||||
|
FUSE_REGS->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
|
fuse_wait_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the SKU info register from the shadow cache. */
|
||||||
|
uint32_t fuse_get_sku_info(void) {
|
||||||
return FUSE_CHIP_REGS->FUSE_SKU_INFO;
|
return FUSE_CHIP_REGS->FUSE_SKU_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the bootrom patch version from a register in the shadow cache */
|
/* Read the bootrom patch version from a register in the shadow cache. */
|
||||||
uint32_t fuse_get_bootrom_patch_version(void)
|
uint32_t fuse_get_bootrom_patch_version(void) {
|
||||||
{
|
return FUSE_CHIP_REGS->FUSE_SOC_SPEEDO_1_CALIB;
|
||||||
return FUSE_CHIP_REGS->FUSE_SOC_SPEEDO_1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a spare bit register from the shadow cache */
|
/* Read a spare bit register from the shadow cache */
|
||||||
uint32_t fuse_get_spare_bit(uint32_t idx)
|
uint32_t fuse_get_spare_bit(uint32_t idx) {
|
||||||
{
|
if (idx < 32) {
|
||||||
if (idx >= 32) {
|
return FUSE_CHIP_REGS->FUSE_SPARE_BIT[idx];
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FUSE_CHIP_REGS->FUSE_SPARE_BIT[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read a reserved ODM register from the shadow cache */
|
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t idx)
|
|
||||||
{
|
|
||||||
if (idx >= 8) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FUSE_CHIP_REGS->FUSE_RESERVED_ODM[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t fuse_get_5x_key_generation(void) {
|
|
||||||
if ((fuse_get_reserved_odm(4) & 0x800) && fuse_get_reserved_odm(0) == 0x8E61ECAE && fuse_get_reserved_odm(1) == 0xF2BA3BB2) {
|
|
||||||
return fuse_get_reserved_odm(2) & 0x1F;
|
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Device ID using values in the shadow cache */
|
/* Read a reserved ODM register from the shadow cache. */
|
||||||
|
uint32_t fuse_get_reserved_odm(uint32_t idx) {
|
||||||
|
if (idx < 8) {
|
||||||
|
return FUSE_CHIP_REGS->FUSE_RESERVED_ODM[idx];
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the DRAM ID using values in the shadow cache. */
|
||||||
|
uint32_t fuse_get_dram_id(void) {
|
||||||
|
return ((fuse_get_reserved_odm(4) >> 3) & 0x7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Derive the Device ID using values in the shadow cache. */
|
||||||
uint64_t fuse_get_device_id(void) {
|
uint64_t fuse_get_device_id(void) {
|
||||||
uint64_t device_id = 0;
|
uint64_t device_id = 0;
|
||||||
uint64_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF;
|
uint64_t y_coord = FUSE_CHIP_REGS->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint64_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF;
|
uint64_t x_coord = FUSE_CHIP_REGS->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint64_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F;
|
uint64_t wafer_id = FUSE_CHIP_REGS->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code = FUSE_CHIP_REGS->FUSE_LOT_CODE_0;
|
uint32_t lot_code = FUSE_CHIP_REGS->FUSE_OPT_LOT_CODE_0;
|
||||||
uint64_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F;
|
uint64_t fab_code = FUSE_CHIP_REGS->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
|
|
||||||
uint64_t derived_lot_code = 0;
|
uint64_t derived_lot_code = 0;
|
||||||
for (unsigned int i = 0; i < 5; i++) {
|
for (unsigned int i = 0; i < 5; i++) {
|
||||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||||
@@ -203,40 +186,41 @@ uint64_t fuse_get_device_id(void) {
|
|||||||
device_id |= wafer_id << 18;
|
device_id |= wafer_id << 18;
|
||||||
device_id |= derived_lot_code << 24;
|
device_id |= derived_lot_code << 24;
|
||||||
device_id |= fab_code << 50;
|
device_id |= fab_code << 50;
|
||||||
|
|
||||||
return device_id;
|
return device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the DRAM ID using values in the shadow cache */
|
/* Derive the Hardware Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_dram_id(void) {
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
|
||||||
return (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 3) & 0x7;
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
}
|
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
||||||
|
|
||||||
/* Derive the Hardware Type using values in the shadow cache */
|
/* Firmware from versions 1.0.0 to 3.0.2. */
|
||||||
uint32_t fuse_get_hardware_type(void) {
|
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
/* This function is very different between 4.x and < 4.x */
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
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() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
|
|
||||||
static const uint32_t types[] = {0,1,4,3};
|
|
||||||
|
|
||||||
hardware_type |= (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 14) & 0x3C;
|
|
||||||
hardware_type--;
|
|
||||||
return hardware_type > 3 ? 4 : types[hardware_type];
|
|
||||||
} else {
|
|
||||||
if (hardware_type >= 1) {
|
if (hardware_type >= 1) {
|
||||||
return hardware_type > 2 ? 3 : hardware_type - 1;
|
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
||||||
} else if ((FUSE_CHIP_REGS->FUSE_SPARE_BIT[9] & 1) == 0) {
|
} else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
||||||
|
static const uint32_t types[] = {0,1,4,3};
|
||||||
|
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
||||||
|
hardware_type--;
|
||||||
|
return (hardware_type > 3) ? 4 : types[hardware_type];
|
||||||
|
} else { /* Firmware versions from 7.0.0 onwards. */
|
||||||
|
/* Always return 0 in retail. */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Retail Type using values in the shadow cache */
|
/* Derive the Retail Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_retail_type(void) {
|
uint32_t fuse_get_retail_type(void) {
|
||||||
/* Retail type = IS_RETAIL | UNIT_TYPE */
|
/* Retail Type = IS_RETAIL | UNIT_TYPE. */
|
||||||
uint32_t retail_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 4) | (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] & 3);
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
|
uint32_t retail_type = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3));
|
||||||
if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */
|
if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */
|
||||||
return 1;
|
return 1;
|
||||||
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
|
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
|
||||||
@@ -249,17 +233,17 @@ uint32_t fuse_get_retail_type(void) {
|
|||||||
void fuse_get_hardware_info(void *dst) {
|
void fuse_get_hardware_info(void *dst) {
|
||||||
uint32_t hw_info[0x4];
|
uint32_t hw_info[0x4];
|
||||||
|
|
||||||
uint32_t unk_hw_fuse = FUSE_CHIP_REGS->_0x120 & 0x3F;
|
uint32_t ops_reserved = FUSE_CHIP_REGS->FUSE_OPT_OPS_RESERVED & 0x3F;
|
||||||
uint32_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF;
|
uint32_t y_coord = FUSE_CHIP_REGS->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint32_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF;
|
uint32_t x_coord = FUSE_CHIP_REGS->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint32_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F;
|
uint32_t wafer_id = FUSE_CHIP_REGS->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code_0 = FUSE_CHIP_REGS->FUSE_LOT_CODE_0;
|
uint32_t lot_code_0 = FUSE_CHIP_REGS->FUSE_OPT_LOT_CODE_0;
|
||||||
uint32_t lot_code_1 = FUSE_CHIP_REGS->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
|
uint32_t lot_code_1 = FUSE_CHIP_REGS->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF;
|
||||||
uint32_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F;
|
uint32_t fab_code = FUSE_CHIP_REGS->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
uint32_t vendor_code = FUSE_CHIP_REGS->FUSE_VENDOR_CODE & 0xF;
|
uint32_t vendor_code = FUSE_CHIP_REGS->FUSE_OPT_VENDOR_CODE & 0xF;
|
||||||
|
|
||||||
/* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
|
/* Hardware Info = OPS_RESERVED || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
|
||||||
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse));
|
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (ops_reserved));
|
||||||
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
|
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
|
||||||
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
|
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
|
||||||
hw_info[3] = (uint32_t)(vendor_code);
|
hw_info[3] = (uint32_t)(vendor_code);
|
||||||
@@ -267,15 +251,50 @@ void fuse_get_hardware_info(void *dst) {
|
|||||||
memcpy(dst, hw_info, 0x10);
|
memcpy(dst, hw_info, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the Key Generation value. */
|
||||||
|
uint32_t fuse_get_5x_key_generation(void) {
|
||||||
|
if ((fuse_get_reserved_odm(4) & 0x800) && (fuse_get_reserved_odm(0) == 0x8E61ECAE) && (fuse_get_reserved_odm(1) == 0xF2BA3BB2)) {
|
||||||
|
return (fuse_get_reserved_odm(2) & 0x1F);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the fuse version expected for the firmware. */
|
||||||
|
uint32_t fuse_get_expected_fuse_version(uint32_t target_firmware) {
|
||||||
|
static const uint8_t expected_versions[ATMOSPHERE_TARGET_FIRMWARE_COUNT+1] = {
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_100] = 1,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_200] = 2,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_300] = 3,
|
||||||
|
/* [ATMOSPHERE_TARGET_FIRMWARE_302] = 4, */
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_400] = 5,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_500] = 6,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_600] = 7,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_620] = 8,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_700] = 9,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_800] = 9,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_810] = 10,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_900] = 11,
|
||||||
|
[ATMOSPHERE_TARGET_FIRMWARE_910] = 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (target_firmware > ATMOSPHERE_TARGET_FIRMWARE_COUNT) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
return expected_versions[target_firmware];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for RCM bug patches. */
|
||||||
bool fuse_has_rcm_bug_patch(void) {
|
bool fuse_has_rcm_bug_patch(void) {
|
||||||
/* Only check for RCM bug patch once, and cache our result. */
|
/* Only check for RCM bug patch once, and cache our result. */
|
||||||
if (!g_has_checked_for_rcm_bug_patch) {
|
if (!g_has_checked_for_rcm_bug_patch) {
|
||||||
/* Patched units have this bit set in reserved_sw, according to reports. */
|
/* Some patched units use XUSB in RCM. */
|
||||||
if (FUSE_CHIP_REGS->FUSE_RESERVED_SW & 0x80) {
|
if (FUSE_CHIP_REGS->FUSE_RESERVED_SW & 0x80) {
|
||||||
g_has_rcm_bug_patch = true;
|
g_has_rcm_bug_patch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Also check for an ipatch. */
|
/* Other units have a proper ipatch instead. */
|
||||||
{
|
{
|
||||||
uint32_t word_count = FUSE_CHIP_REGS->FUSE_FIRST_BOOTROM_PATCH_SIZE & 0x7f;
|
uint32_t word_count = FUSE_CHIP_REGS->FUSE_FIRST_BOOTROM_PATCH_SIZE & 0x7f;
|
||||||
uint32_t word_addr = 191;
|
uint32_t word_addr = 191;
|
||||||
@@ -301,4 +320,4 @@ bool fuse_has_rcm_bug_patch(void) {
|
|||||||
g_has_checked_for_rcm_bug_patch = true;
|
g_has_checked_for_rcm_bug_patch = true;
|
||||||
|
|
||||||
return g_has_rcm_bug_patch;
|
return g_has_rcm_bug_patch;
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EXOSPHERE_FUSE_H
|
#ifndef EXOSPHERE_FUSE_H
|
||||||
#define EXOSPHERE_FUSE_H
|
#define EXOSPHERE_FUSE_H
|
||||||
|
|
||||||
@@ -24,154 +24,167 @@
|
|||||||
/* Exosphere driver for the Tegra X1 FUSE registers. */
|
/* Exosphere driver for the Tegra X1 FUSE registers. */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t FUSE_CTRL;
|
uint32_t FUSE_FUSECTRL;
|
||||||
uint32_t FUSE_REG_ADDR;
|
uint32_t FUSE_FUSEADDR;
|
||||||
uint32_t FUSE_REG_READ;
|
uint32_t FUSE_FUSERDATA;
|
||||||
uint32_t FUSE_REG_WRITE;
|
uint32_t FUSE_FUSEWDATA;
|
||||||
uint32_t FUSE_TIME_RD1;
|
uint32_t FUSE_FUSETIME_RD1;
|
||||||
uint32_t FUSE_TIME_RD2;
|
uint32_t FUSE_FUSETIME_RD2;
|
||||||
uint32_t FUSE_TIME_PGM1;
|
uint32_t FUSE_FUSETIME_PGM1;
|
||||||
uint32_t FUSE_TIME_PGM2;
|
uint32_t FUSE_FUSETIME_PGM2;
|
||||||
uint32_t FUSE_PRIV2INTFC;
|
uint32_t FUSE_PRIV2INTFC_START;
|
||||||
uint32_t FUSE_FUSEBYPASS;
|
uint32_t FUSE_FUSEBYPASS;
|
||||||
uint32_t FUSE_PRIVATEKEYDISABLE;
|
uint32_t FUSE_PRIVATEKEYDISABLE;
|
||||||
uint32_t FUSE_DIS_PGM;
|
uint32_t FUSE_DISABLEREGPROGRAM;
|
||||||
uint32_t FUSE_WRITE_ACCESS;
|
uint32_t FUSE_WRITE_ACCESS_SW;
|
||||||
uint32_t FUSE_PWR_GOOD_SW;
|
uint32_t FUSE_PWR_GOOD_SW;
|
||||||
uint32_t _0x38[0x32];
|
uint32_t _0x38;
|
||||||
} fuse_registers_t;
|
uint32_t FUSE_PRIV2RESHIFT;
|
||||||
|
uint32_t _0x40[0x3];
|
||||||
|
uint32_t FUSE_FUSETIME_RD3;
|
||||||
|
uint32_t _0x50[0xC];
|
||||||
|
uint32_t FUSE_PRIVATE_KEY0_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY1_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY2_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY3_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY4_NONZERO;
|
||||||
|
uint32_t _0x90[0x1C];
|
||||||
|
} tegra_fuse_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t FUSE_PRODUCTION_MODE;
|
uint32_t FUSE_PRODUCTION_MODE;
|
||||||
uint32_t _0x4;
|
uint32_t FUSE_JTAG_SECUREID_VALID;
|
||||||
uint32_t _0x8;
|
uint32_t FUSE_ODM_LOCK;
|
||||||
uint32_t _0xC;
|
uint32_t FUSE_OPT_OPENGL_EN;
|
||||||
uint32_t FUSE_SKU_INFO;
|
uint32_t FUSE_SKU_INFO;
|
||||||
uint32_t FUSE_CPU_SPEEDO_0;
|
uint32_t FUSE_CPU_SPEEDO_0_CALIB;
|
||||||
uint32_t FUSE_CPU_IDDQ;
|
uint32_t FUSE_CPU_IDDQ_CALIB;
|
||||||
uint32_t _0x1C;
|
uint32_t FUSE_DAC_CRT_CALIB;
|
||||||
uint32_t _0x20;
|
uint32_t FUSE_DAC_HDTV_CALIB;
|
||||||
uint32_t _0x24;
|
uint32_t FUSE_DAC_SDTV_CALIB;
|
||||||
uint32_t FUSE_FT_REV;
|
uint32_t FUSE_OPT_FT_REV;
|
||||||
uint32_t FUSE_CPU_SPEEDO_1;
|
uint32_t FUSE_CPU_SPEEDO_1_CALIB;
|
||||||
uint32_t FUSE_CPU_SPEEDO_2;
|
uint32_t FUSE_CPU_SPEEDO_2_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_0;
|
uint32_t FUSE_SOC_SPEEDO_0_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_1;
|
uint32_t FUSE_SOC_SPEEDO_1_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_2;
|
uint32_t FUSE_SOC_SPEEDO_2_CALIB;
|
||||||
uint32_t FUSE_SOC_IDDQ;
|
uint32_t FUSE_SOC_IDDQ_CALIB;
|
||||||
uint32_t _0x44;
|
uint32_t FUSE_RESERVED_PRODUCTION_WP;
|
||||||
uint32_t FUSE_FA;
|
uint32_t FUSE_FA;
|
||||||
uint32_t _0x4C;
|
uint32_t FUSE_RESERVED_PRODUCTION;
|
||||||
uint32_t _0x50;
|
uint32_t FUSE_HDMI_LANE0_CALIB;
|
||||||
uint32_t _0x54;
|
uint32_t FUSE_HDMI_LANE1_CALIB;
|
||||||
uint32_t _0x58;
|
uint32_t FUSE_HDMI_LANE2_CALIB;
|
||||||
uint32_t _0x5C;
|
uint32_t FUSE_HDMI_LANE3_CALIB;
|
||||||
uint32_t _0x60;
|
uint32_t FUSE_ENCRYPTION_RATE;
|
||||||
uint32_t FUSE_PUBLIC_KEY[0x8];
|
uint32_t FUSE_PUBLIC_KEY[0x8];
|
||||||
uint32_t FUSE_TSENSOR_1;
|
uint32_t FUSE_TSENSOR1_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_2;
|
uint32_t FUSE_TSENSOR2_CALIB;
|
||||||
uint32_t _0x8C;
|
uint32_t FUSE_VSENSOR_CALIB;
|
||||||
uint32_t FUSE_CP_REV;
|
uint32_t FUSE_OPT_CP_REV;
|
||||||
uint32_t _0x94;
|
uint32_t FUSE_OPT_PFG;
|
||||||
uint32_t FUSE_TSENSOR_0;
|
uint32_t FUSE_TSENSOR0_CALIB;
|
||||||
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE;
|
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE;
|
||||||
uint32_t FUSE_SECURITY_MODE;
|
uint32_t FUSE_SECURITY_MODE;
|
||||||
uint32_t FUSE_PRIVATE_KEY[0x4];
|
uint32_t FUSE_PRIVATE_KEY[0x5];
|
||||||
uint32_t FUSE_DEVICE_KEY;
|
uint32_t FUSE_ARM_JTAG_DIS;
|
||||||
uint32_t _0xB8;
|
uint32_t FUSE_BOOT_DEVICE_INFO;
|
||||||
uint32_t _0xBC;
|
|
||||||
uint32_t FUSE_RESERVED_SW;
|
uint32_t FUSE_RESERVED_SW;
|
||||||
uint32_t FUSE_VP8_ENABLE;
|
uint32_t FUSE_OPT_VP9_DISABLE;
|
||||||
uint32_t FUSE_RESERVED_ODM[0x8];
|
uint32_t FUSE_RESERVED_ODM[0x8];
|
||||||
uint32_t _0xE8;
|
uint32_t FUSE_OBS_DIS;
|
||||||
uint32_t _0xEC;
|
uint32_t FUSE_NOR_INFO;
|
||||||
uint32_t FUSE_SKU_USB_CALIB;
|
uint32_t FUSE_USB_CALIB;
|
||||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
||||||
uint32_t _0xF8;
|
uint32_t FUSE_KFUSE_PRIVKEY_CTRL;
|
||||||
uint32_t _0xFC;
|
uint32_t FUSE_PACKAGE_INFO;
|
||||||
uint32_t FUSE_VENDOR_CODE;
|
uint32_t FUSE_OPT_VENDOR_CODE;
|
||||||
uint32_t FUSE_FAB_CODE;
|
uint32_t FUSE_OPT_FAB_CODE;
|
||||||
uint32_t FUSE_LOT_CODE_0;
|
uint32_t FUSE_OPT_LOT_CODE_0;
|
||||||
uint32_t FUSE_LOT_CODE_1;
|
uint32_t FUSE_OPT_LOT_CODE_1;
|
||||||
uint32_t FUSE_WAFER_ID;
|
uint32_t FUSE_OPT_WAFER_ID;
|
||||||
uint32_t FUSE_X_COORDINATE;
|
uint32_t FUSE_OPT_X_COORDINATE;
|
||||||
uint32_t FUSE_Y_COORDINATE;
|
uint32_t FUSE_OPT_Y_COORDINATE;
|
||||||
uint32_t _0x11C;
|
uint32_t FUSE_OPT_SEC_DEBUG_EN;
|
||||||
uint32_t _0x120;
|
uint32_t FUSE_OPT_OPS_RESERVED;
|
||||||
uint32_t FUSE_SATA_CALIB;
|
uint32_t FUSE_SATA_CALIB;
|
||||||
uint32_t FUSE_GPU_IDDQ;
|
uint32_t FUSE_GPU_IDDQ_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_3;
|
uint32_t FUSE_TSENSOR3_CALIB;
|
||||||
uint32_t _0x130;
|
uint32_t FUSE_SKU_BOND_OUT_L;
|
||||||
uint32_t _0x134;
|
uint32_t FUSE_SKU_BOND_OUT_H;
|
||||||
uint32_t _0x138;
|
uint32_t FUSE_SKU_BOND_OUT_U;
|
||||||
uint32_t _0x13C;
|
uint32_t FUSE_SKU_BOND_OUT_V;
|
||||||
uint32_t _0x140;
|
uint32_t FUSE_SKU_BOND_OUT_W;
|
||||||
uint32_t _0x144;
|
uint32_t FUSE_OPT_SAMPLE_TYPE;
|
||||||
uint32_t FUSE_OPT_SUBREVISION;
|
uint32_t FUSE_OPT_SUBREVISION;
|
||||||
uint32_t _0x14C;
|
uint32_t FUSE_OPT_SW_RESERVED_0;
|
||||||
uint32_t _0x150;
|
uint32_t FUSE_OPT_SW_RESERVED_1;
|
||||||
uint32_t FUSE_TSENSOR_4;
|
uint32_t FUSE_TSENSOR4_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_5;
|
uint32_t FUSE_TSENSOR5_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_6;
|
uint32_t FUSE_TSENSOR6_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_7;
|
uint32_t FUSE_TSENSOR7_CALIB;
|
||||||
uint32_t FUSE_OPT_PRIV_SEC_DIS;
|
uint32_t FUSE_OPT_PRIV_SEC_EN;
|
||||||
uint32_t FUSE_PKC_DISABLE;
|
uint32_t FUSE_PKC_DISABLE;
|
||||||
uint32_t _0x16C;
|
uint32_t _0x16C;
|
||||||
uint32_t _0x170;
|
uint32_t _0x170;
|
||||||
uint32_t _0x174;
|
uint32_t _0x174;
|
||||||
uint32_t _0x178;
|
uint32_t _0x178;
|
||||||
uint32_t _0x17C;
|
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
||||||
uint32_t FUSE_TSENSOR_COMMON;
|
uint32_t FUSE_TSENSOR_COMMON;
|
||||||
uint32_t _0x184;
|
uint32_t FUSE_OPT_CP_BIN;
|
||||||
uint32_t _0x188;
|
uint32_t FUSE_OPT_GPU_DISABLE;
|
||||||
uint32_t _0x18C;
|
uint32_t FUSE_OPT_FT_BIN;
|
||||||
uint32_t _0x190;
|
uint32_t FUSE_OPT_DONE_MAP;
|
||||||
uint32_t _0x194;
|
uint32_t _0x194;
|
||||||
uint32_t _0x198;
|
uint32_t FUSE_APB2JTAG_DISABLE;
|
||||||
uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
|
uint32_t FUSE_ODM_INFO;
|
||||||
uint32_t _0x1A0;
|
uint32_t _0x1A0;
|
||||||
uint32_t _0x1A4;
|
uint32_t _0x1A4;
|
||||||
uint32_t _0x1A8;
|
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
|
||||||
uint32_t _0x1AC;
|
uint32_t _0x1AC;
|
||||||
uint32_t _0x1B0;
|
uint32_t _0x1B0;
|
||||||
uint32_t _0x1B4;
|
uint32_t _0x1B4;
|
||||||
uint32_t _0x1B8;
|
uint32_t _0x1B8;
|
||||||
uint32_t _0x1BC;
|
uint32_t _0x1BC;
|
||||||
uint32_t _0x1D0;
|
uint32_t FUSE_WOA_SKU_FLAG;
|
||||||
uint32_t FUSE_TSENSOR_8;
|
uint32_t FUSE_ECO_RESERVE_1;
|
||||||
|
uint32_t FUSE_GCPLEX_CONFIG_FUSE;
|
||||||
|
uint32_t FUSE_PRODUCTION_MONTH;
|
||||||
|
uint32_t FUSE_RAM_REPAIR_INDICATOR;
|
||||||
|
uint32_t FUSE_TSENSOR9_CALIB;
|
||||||
uint32_t _0x1D8;
|
uint32_t _0x1D8;
|
||||||
uint32_t _0x1DC;
|
uint32_t FUSE_VMIN_CALIBRATION;
|
||||||
uint32_t _0x1E0;
|
uint32_t FUSE_AGING_SENSOR_CALIBRATION;
|
||||||
uint32_t _0x1E4;
|
uint32_t FUSE_DEBUG_AUTHENTICATION;
|
||||||
uint32_t _0x1E8;
|
uint32_t FUSE_SECURE_PROVISION_INDEX;
|
||||||
uint32_t _0x1EC;
|
uint32_t FUSE_SECURE_PROVISION_INFO;
|
||||||
uint32_t _0x1F0;
|
uint32_t FUSE_OPT_GPU_DISABLE_CP1;
|
||||||
uint32_t _0x1F4;
|
uint32_t FUSE_SPARE_ENDIS;
|
||||||
uint32_t _0x1F8;
|
uint32_t FUSE_ECO_RESERVE_0;
|
||||||
uint32_t _0x1FC;
|
uint32_t _0x1FC;
|
||||||
uint32_t _0x200;
|
uint32_t _0x200;
|
||||||
uint32_t FUSE_RESERVED_CALIB;
|
uint32_t FUSE_RESERVED_CALIB0;
|
||||||
uint32_t _0x208;
|
uint32_t FUSE_RESERVED_CALIB1;
|
||||||
uint32_t _0x20C;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE;
|
||||||
uint32_t _0x210;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1;
|
||||||
uint32_t _0x214;
|
uint32_t FUSE_OPT_CPU_DISABLE;
|
||||||
uint32_t _0x218;
|
uint32_t FUSE_OPT_CPU_DISABLE_CP1;
|
||||||
uint32_t FUSE_TSENSOR_9;
|
uint32_t FUSE_TSENSOR10_CALIB;
|
||||||
uint32_t _0x220;
|
uint32_t FUSE_TSENSOR10_CALIB_AUX;
|
||||||
uint32_t _0x224;
|
uint32_t FUSE_OPT_RAM_SVOP_DP;
|
||||||
uint32_t _0x228;
|
uint32_t FUSE_OPT_RAM_SVOP_PDP;
|
||||||
uint32_t _0x22C;
|
uint32_t FUSE_OPT_RAM_SVOP_REG;
|
||||||
uint32_t _0x230;
|
uint32_t FUSE_OPT_RAM_SVOP_SP;
|
||||||
uint32_t _0x234;
|
uint32_t FUSE_OPT_RAM_SVOP_SMPDP;
|
||||||
uint32_t _0x238;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2;
|
||||||
uint32_t _0x23C;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE;
|
||||||
uint32_t _0x240;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1;
|
||||||
uint32_t _0x244;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2;
|
||||||
uint32_t _0x248;
|
uint32_t FUSE_OPT_CPU_DISABLE_CP2;
|
||||||
uint32_t _0x24C;
|
uint32_t FUSE_OPT_GPU_DISABLE_CP2;
|
||||||
uint32_t FUSE_USB_CALIB_EXT;
|
uint32_t FUSE_USB_CALIB_EXT;
|
||||||
uint32_t _0x254;
|
uint32_t FUSE_RESERVED_FIELD;
|
||||||
uint32_t _0x258;
|
uint32_t FUSE_OPT_ECC_EN;
|
||||||
uint32_t _0x25C;
|
uint32_t _0x25C;
|
||||||
uint32_t _0x260;
|
uint32_t _0x260;
|
||||||
uint32_t _0x264;
|
uint32_t _0x264;
|
||||||
@@ -180,41 +193,42 @@ typedef struct {
|
|||||||
uint32_t _0x270;
|
uint32_t _0x270;
|
||||||
uint32_t _0x274;
|
uint32_t _0x274;
|
||||||
uint32_t _0x278;
|
uint32_t _0x278;
|
||||||
uint32_t _0x27C;
|
uint32_t FUSE_SPARE_REALIGNMENT_REG;
|
||||||
uint32_t FUSE_SPARE_BIT[0x20];
|
uint32_t FUSE_SPARE_BIT[0x20];
|
||||||
} fuse_chip_registers_t;
|
} tegra_fuse_chip_t;
|
||||||
|
|
||||||
static inline volatile fuse_registers_t *get_fuse_regs(void) {
|
static inline volatile tegra_fuse_t *fuse_get_regs(void) {
|
||||||
return (volatile fuse_registers_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x800);
|
return (volatile tegra_fuse_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x800);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline volatile fuse_chip_registers_t *get_fuse_chip_regs(void) {
|
static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) {
|
||||||
return (volatile fuse_chip_registers_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x900);
|
return (volatile tegra_fuse_chip_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x900);
|
||||||
}
|
}
|
||||||
#define FUSE_REGS (get_fuse_regs())
|
|
||||||
#define FUSE_CHIP_REGS (get_fuse_chip_regs())
|
#define FUSE_REGS (fuse_get_regs())
|
||||||
|
#define FUSE_CHIP_REGS (fuse_chip_get_regs())
|
||||||
|
|
||||||
void fuse_init(void);
|
void fuse_init(void);
|
||||||
|
|
||||||
uint32_t fuse_hw_read(uint32_t addr);
|
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr);
|
|
||||||
void fuse_hw_sense(void);
|
|
||||||
void fuse_disable_programming(void);
|
void fuse_disable_programming(void);
|
||||||
void fuse_secondary_private_key_disable(void);
|
void fuse_disable_private_key(void);
|
||||||
|
|
||||||
uint32_t fuse_get_sku_info(void);
|
uint32_t fuse_get_sku_info(void);
|
||||||
uint32_t fuse_get_spare_bit(uint32_t idx);
|
uint32_t fuse_get_spare_bit(uint32_t idx);
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t idx);
|
uint32_t fuse_get_reserved_odm(uint32_t idx);
|
||||||
|
|
||||||
uint32_t fuse_get_5x_key_generation(void);
|
|
||||||
|
|
||||||
uint32_t fuse_get_bootrom_patch_version(void);
|
uint32_t fuse_get_bootrom_patch_version(void);
|
||||||
uint64_t fuse_get_device_id(void);
|
uint64_t fuse_get_device_id(void);
|
||||||
uint32_t fuse_get_dram_id(void);
|
uint32_t fuse_get_dram_id(void);
|
||||||
uint32_t fuse_get_hardware_type(void);
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware);
|
||||||
uint32_t fuse_get_retail_type(void);
|
uint32_t fuse_get_retail_type(void);
|
||||||
void fuse_get_hardware_info(void *dst);
|
void fuse_get_hardware_info(void *dst);
|
||||||
|
uint32_t fuse_get_5x_key_generation(void);
|
||||||
bool fuse_has_rcm_bug_patch(void);
|
bool fuse_has_rcm_bug_patch(void);
|
||||||
|
|
||||||
|
uint32_t fuse_hw_read(uint32_t addr);
|
||||||
|
void fuse_hw_write(uint32_t value, uint32_t addr);
|
||||||
|
void fuse_hw_sense(void);
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t fuse_get_expected_fuse_version(uint32_t target_firmware);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
@@ -32,7 +32,7 @@ bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_
|
|||||||
/* Configure I2C pinmux. */
|
/* Configure I2C pinmux. */
|
||||||
void i2c_config(I2CDevice id) {
|
void i2c_config(I2CDevice id) {
|
||||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case I2C_1:
|
case I2C_1:
|
||||||
pinmux->gen1_i2c_scl = PINMUX_INPUT;
|
pinmux->gen1_i2c_scl = PINMUX_INPUT;
|
||||||
@@ -74,7 +74,7 @@ void i2c_init(I2CDevice id) {
|
|||||||
|
|
||||||
/* Wait a while until BUS_CLEAR_DONE is set. */
|
/* Wait a while until BUS_CLEAR_DONE is set. */
|
||||||
for (unsigned int i = 0; i < 10; i++) {
|
for (unsigned int i = 0; i < 10; i++) {
|
||||||
wait(20000);
|
wait(25);
|
||||||
if (regs->I2C_INTERRUPT_STATUS_REGISTER_0 & 0x800) {
|
if (regs->I2C_INTERRUPT_STATUS_REGISTER_0 & 0x800) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ void i2c_init(I2CDevice id) {
|
|||||||
regs->I2C_INTERRUPT_STATUS_REGISTER_0 = int_status;
|
regs->I2C_INTERRUPT_STATUS_REGISTER_0 = int_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sets a bit in a PMIC register over I2C during CPU shutdown. */
|
/* Sets a bit in a PMIC register over I2C during CPU shutdown. */
|
||||||
void i2c_send_pmic_cpu_shutdown_cmd(void) {
|
void i2c_send_pmic_cpu_shutdown_cmd(void) {
|
||||||
uint32_t val = 0;
|
uint32_t val = 0;
|
||||||
/* PMIC == Device 4:3C. */
|
/* PMIC == Device 4:3C. */
|
||||||
@@ -162,7 +162,7 @@ void i2c_load_config(volatile tegra_i2c_t *regs) {
|
|||||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
||||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
||||||
uint32_t val = r;
|
uint32_t val = r;
|
||||||
|
|
||||||
/* Write single byte register ID to device. */
|
/* Write single byte register ID to device. */
|
||||||
if (!i2c_write(regs, device, &val, 1)) {
|
if (!i2c_write(regs, device, &val, 1)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -171,12 +171,12 @@ bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_si
|
|||||||
if (dst_size > 4) {
|
if (dst_size > 4) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return i2c_read(regs, device, dst, dst_size);
|
return i2c_read(regs, device, dst, dst_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Writes a value to a register over I2C. */
|
/* Writes a value to a register over I2C. */
|
||||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
||||||
uint32_t val = r;
|
uint32_t val = r;
|
||||||
if (src_size == 0) {
|
if (src_size == 0) {
|
||||||
return true;
|
return true;
|
||||||
@@ -240,7 +240,7 @@ bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_
|
|||||||
while (regs->I2C_I2C_STATUS_0 & 0x100) {
|
while (regs->I2C_I2C_STATUS_0 & 0x100) {
|
||||||
/* Wait until not busy. */
|
/* Wait until not busy. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure success. */
|
/* Ensure success. */
|
||||||
if ((regs->I2C_I2C_STATUS_0 & 0xF) != 0) {
|
if ((regs->I2C_I2C_STATUS_0 & 0xF) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ static const uint8_t mkey_vectors_dev[MASTERKEY_REVISION_MAX][0x10] =
|
|||||||
{0x6F, 0xD2, 0x84, 0x1D, 0x05, 0xEC, 0x40, 0x94, 0x5F, 0x18, 0xB3, 0x81, 0x09, 0x98, 0x8D, 0x4E}, /* Master key 05 encrypted with Master key 06. */
|
{0x6F, 0xD2, 0x84, 0x1D, 0x05, 0xEC, 0x40, 0x94, 0x5F, 0x18, 0xB3, 0x81, 0x09, 0x98, 0x8D, 0x4E}, /* Master key 05 encrypted with Master key 06. */
|
||||||
{0x37, 0xAF, 0xAB, 0x35, 0x79, 0x09, 0xD9, 0x48, 0x29, 0xD2, 0xDB, 0xA5, 0xA5, 0xF5, 0x30, 0x19}, /* Master key 06 encrypted with Master key 07. */
|
{0x37, 0xAF, 0xAB, 0x35, 0x79, 0x09, 0xD9, 0x48, 0x29, 0xD2, 0xDB, 0xA5, 0xA5, 0xF5, 0x30, 0x19}, /* Master key 06 encrypted with Master key 07. */
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: Master key 07 encrypted with Master key 08. */
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: Master key 07 encrypted with Master key 08. */
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: Master key 08 encrypted with Master key 09. */
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: Master key 09 encrypted with Master key 0A. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Retail unit keys. */
|
/* Retail unit keys. */
|
||||||
@@ -57,6 +59,8 @@ static const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] =
|
|||||||
{0x1E, 0x1E, 0x22, 0xC0, 0x5A, 0x33, 0x3C, 0xB9, 0x0B, 0xA9, 0x03, 0x04, 0xBA, 0xDB, 0x07, 0x57}, /* Master key 05 encrypted with Master key 06. */
|
{0x1E, 0x1E, 0x22, 0xC0, 0x5A, 0x33, 0x3C, 0xB9, 0x0B, 0xA9, 0x03, 0x04, 0xBA, 0xDB, 0x07, 0x57}, /* Master key 05 encrypted with Master key 06. */
|
||||||
{0xA4, 0xD4, 0x52, 0x6F, 0xD1, 0xE4, 0x36, 0xAA, 0x9F, 0xCB, 0x61, 0x27, 0x1C, 0x67, 0x65, 0x1F}, /* Master key 06 encrypted with Master key 07. */
|
{0xA4, 0xD4, 0x52, 0x6F, 0xD1, 0xE4, 0x36, 0xAA, 0x9F, 0xCB, 0x61, 0x27, 0x1C, 0x67, 0x65, 0x1F}, /* Master key 06 encrypted with Master key 07. */
|
||||||
{0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29}, /* Master key 07 encrypted with Master key 08. */
|
{0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29}, /* Master key 07 encrypted with Master key 08. */
|
||||||
|
{0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80}, /* Master key 08 encrypted with Master key 09. */
|
||||||
|
{0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A}, /* Master key 09 encrypted with Master key 0A. */
|
||||||
};
|
};
|
||||||
|
|
||||||
bool check_mkey_revision(unsigned int revision, bool is_retail) {
|
bool check_mkey_revision(unsigned int revision, bool is_retail) {
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
|
|
||||||
/* This is glue code to enable master key support across versions. */
|
/* This is glue code to enable master key support across versions. */
|
||||||
|
|
||||||
/* TODO: Update to 0xA on release of new master key. */
|
/* TODO: Update to 0xC on release of new master key. */
|
||||||
#define MASTERKEY_REVISION_MAX 0x9
|
#define MASTERKEY_REVISION_MAX 0xB
|
||||||
|
|
||||||
#define MASTERKEY_REVISION_100_230 0x00
|
#define MASTERKEY_REVISION_100_230 0x00
|
||||||
#define MASTERKEY_REVISION_300 0x01
|
#define MASTERKEY_REVISION_300 0x01
|
||||||
@@ -29,8 +29,10 @@
|
|||||||
#define MASTERKEY_REVISION_500_510 0x04
|
#define MASTERKEY_REVISION_500_510 0x04
|
||||||
#define MASTERKEY_REVISION_600_610 0x05
|
#define MASTERKEY_REVISION_600_610 0x05
|
||||||
#define MASTERKEY_REVISION_620 0x06
|
#define MASTERKEY_REVISION_620 0x06
|
||||||
#define MASTERKEY_REVISION_700_800 0x07
|
#define MASTERKEY_REVISION_700_800 0x07
|
||||||
#define MASTERKEY_REVISION_810_CURRENT 0x08
|
#define MASTERKEY_REVISION_810 0x08
|
||||||
|
#define MASTERKEY_REVISION_900 0x09
|
||||||
|
#define MASTERKEY_REVISION_910_CURRENT 0x0A
|
||||||
|
|
||||||
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)
|
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,14 @@ static inline uintptr_t get_mc_base(void) {
|
|||||||
#define MC_SMMU_PTB_DATA 0x20
|
#define MC_SMMU_PTB_DATA 0x20
|
||||||
#define MC_SMMU_TLB_FLUSH 0x30
|
#define MC_SMMU_TLB_FLUSH 0x30
|
||||||
#define MC_SMMU_PTC_FLUSH 0x34
|
#define MC_SMMU_PTC_FLUSH 0x34
|
||||||
|
#define MC_SMMU_ASID_SECURITY 0x38
|
||||||
|
#define MC_SMMU_ASID_SECURITY_1 0x3c
|
||||||
|
#define MC_SMMU_ASID_SECURITY_2 0x9e0
|
||||||
|
#define MC_SMMU_ASID_SECURITY_3 0x9e4
|
||||||
|
#define MC_SMMU_ASID_SECURITY_4 0x9e8
|
||||||
|
#define MC_SMMU_ASID_SECURITY_5 0x9ec
|
||||||
|
#define MC_SMMU_ASID_SECURITY_6 0x9f0
|
||||||
|
#define MC_SMMU_ASID_SECURITY_7 0x9f4
|
||||||
#define MC_SMMU_AFI_ASID 0x238
|
#define MC_SMMU_AFI_ASID 0x238
|
||||||
#define MC_SMMU_AVPC_ASID 0x23c
|
#define MC_SMMU_AVPC_ASID 0x23c
|
||||||
#define MC_SMMU_PPCS1_ASID 0x298
|
#define MC_SMMU_PPCS1_ASID 0x298
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ static const uint8_t new_device_key_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10]
|
|||||||
{0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */
|
{0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */
|
||||||
{0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17}, /* 6.2.0 New Device Key Source. */
|
{0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17}, /* 6.2.0 New Device Key Source. */
|
||||||
{0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D}, /* 7.0.0 New Device Key Source. */
|
{0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D}, /* 7.0.0 New Device Key Source. */
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 8.1.0 New Device Key Source to be added on next change-of-keys. */
|
{0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE}, /* 8.1.0 New Device Key Source. */
|
||||||
|
{0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49}, /* 9.0.0 New Device Key Source. */
|
||||||
|
{0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94}, /* 9.1.0 New Device Key Source. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
|
static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
|
||||||
@@ -52,7 +54,9 @@ static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x
|
|||||||
{0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF}, /* 6.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. */
|
{0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB}, /* 6.2.0 New Device Keygen Source. */
|
||||||
{0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E}, /* 7.0.0 New Device Keygen Source. */
|
{0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E}, /* 7.0.0 New Device Keygen Source. */
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 8.1.0 New Device Key Source to be added on next change-of-keys. */
|
{0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D}, /* 8.1.0 New Device Keygen Source. */
|
||||||
|
{0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED}, /* 9.0.0 New Device Keygen Source. */
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 9.1.0 New Device Keygen Source to be added on next change-of-keys. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
|
static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
|
||||||
@@ -61,7 +65,9 @@ static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS
|
|||||||
{0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5}, /* 6.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. */
|
{0x20, 0xAB, 0xF2, 0x0F, 0x05, 0xE3, 0xDE, 0x2E, 0xA1, 0xFB, 0x37, 0x5E, 0x8B, 0x22, 0x1A, 0x38}, /* 6.2.0 New Device Keygen Source. */
|
||||||
{0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE}, /* 7.0.0 New Device Keygen Source. */
|
{0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE}, /* 7.0.0 New Device Keygen Source. */
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 8.1.0 New Device Key Source to be added on next change-of-keys. */
|
{0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87}, /* 8.1.0 New Device Keygen Source. */
|
||||||
|
{0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F}, /* 9.0.0 New Device Keygen Source. */
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 9.1.0 New Device Keygen Source to be added on next change-of-keys. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void derive_new_device_keys(unsigned int keygen_keyslot) {
|
static void derive_new_device_keys(unsigned int keygen_keyslot) {
|
||||||
@@ -100,15 +106,15 @@ static void setup_se(void) {
|
|||||||
|
|
||||||
/* Perform some sanity initialization. */
|
/* Perform some sanity initialization. */
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
volatile tegra_se_t *se = se_get_regs();
|
||||||
se->_0x0 &= 0xFFFEFFFF; /* Clear bit 16. */
|
se->SE_SE_SECURITY &= 0xFFFEFFFF; /* Clear bit 16. */
|
||||||
(void)(se->FLAGS_REG);
|
(void)(se->SE_STATUS);
|
||||||
__dsb_sy();
|
__dsb_sy();
|
||||||
|
|
||||||
/* NOTE: On 8.1.0+, Nintendo does not make keyslots 0-5 unreadable. */
|
/* NOTE: On 8.1.0+, Nintendo does not make keyslots 0-5 unreadable. */
|
||||||
se->_0x4 = 0;
|
se->SE_TZRAM_SECURITY = 0;
|
||||||
se->AES_KEY_READ_DISABLE_REG = 0;
|
se->SE_CRYPTO_SECURITY_PERKEY = 0;
|
||||||
se->RSA_KEY_READ_DISABLE_REG = 0;
|
se->SE_RSA_SECURITY_PERKEY = 0;
|
||||||
se->_0x0 &= 0xFFFFFFFB;
|
se->SE_SE_SECURITY &= 0xFFFFFFFB;
|
||||||
|
|
||||||
/* Currently unknown what each flag does. */
|
/* Currently unknown what each flag does. */
|
||||||
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
|
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
|
||||||
@@ -141,6 +147,8 @@ static void setup_se(void) {
|
|||||||
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
||||||
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
||||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||||
|
case ATMOSPHERE_TARGET_FIRMWARE_900:
|
||||||
|
case ATMOSPHERE_TARGET_FIRMWARE_910:
|
||||||
derive_new_device_keys(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY);
|
derive_new_device_keys(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -330,7 +338,7 @@ static bool validate_package2_metadata(package2_meta_t *metadata) {
|
|||||||
|
|
||||||
/* Perform version checks. */
|
/* Perform version checks. */
|
||||||
/* We will be compatible with all package2s released before current, but not newer ones. */
|
/* 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_810_CURRENT) {
|
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_910_CURRENT) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,6 +464,8 @@ static void copy_warmboot_bin_to_dram() {
|
|||||||
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
||||||
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
||||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||||
|
case ATMOSPHERE_TARGET_FIRMWARE_900:
|
||||||
|
case ATMOSPHERE_TARGET_FIRMWARE_910:
|
||||||
warmboot_src = (uint8_t *)0x4003E000;
|
warmboot_src = (uint8_t *)0x4003E000;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -502,6 +512,9 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
|||||||
if (exosphere_should_disable_usermode_exception_handlers() != 0) {
|
if (exosphere_should_disable_usermode_exception_handlers() != 0) {
|
||||||
configitem_disable_usermode_exception_handlers();
|
configitem_disable_usermode_exception_handlers();
|
||||||
}
|
}
|
||||||
|
if (exosphere_should_enable_usermode_pmu_access()) {
|
||||||
|
configitem_enable_usermode_pmu_access();
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup the Security Engine. */
|
/* Setup the Security Engine. */
|
||||||
setup_se();
|
setup_se();
|
||||||
@@ -532,6 +545,12 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
|
|||||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||||
MAKE_REG32(PMC_BASE + 0x360) = 0x14A;
|
MAKE_REG32(PMC_BASE + 0x360) = 0x14A;
|
||||||
break;
|
break;
|
||||||
|
case ATMOSPHERE_TARGET_FIRMWARE_900:
|
||||||
|
MAKE_REG32(PMC_BASE + 0x360) = 0x16B;
|
||||||
|
break;
|
||||||
|
case ATMOSPHERE_TARGET_FIRMWARE_910:
|
||||||
|
MAKE_REG32(PMC_BASE + 0x360) = 0x18C;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,9 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(unsigned int targetfw) {
|
|||||||
#define PACKAGE2_MAXVER_600_610 0x8
|
#define PACKAGE2_MAXVER_600_610 0x8
|
||||||
#define PACKAGE2_MAXVER_620 0x9
|
#define PACKAGE2_MAXVER_620 0x9
|
||||||
#define PACKAGE2_MAXVER_700_800 0xA
|
#define PACKAGE2_MAXVER_700_800 0xA
|
||||||
#define PACKAGE2_MAXVER_810_CURRENT 0xB
|
#define PACKAGE2_MAXVER_810 0xB
|
||||||
|
#define PACKAGE2_MAXVER_900 0xC
|
||||||
|
#define PACKAGE2_MAXVER_910_CURRENT 0xD
|
||||||
|
|
||||||
#define PACKAGE2_MINVER_100 0x3
|
#define PACKAGE2_MINVER_100 0x3
|
||||||
#define PACKAGE2_MINVER_200 0x4
|
#define PACKAGE2_MINVER_200 0x4
|
||||||
@@ -82,7 +84,9 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(unsigned int targetfw) {
|
|||||||
#define PACKAGE2_MINVER_600_610 0x9
|
#define PACKAGE2_MINVER_600_610 0x9
|
||||||
#define PACKAGE2_MINVER_620 0xA
|
#define PACKAGE2_MINVER_620 0xA
|
||||||
#define PACKAGE2_MINVER_700_800 0xB
|
#define PACKAGE2_MINVER_700_800 0xB
|
||||||
#define PACKAGE2_MINVER_810_CURRENT 0xC
|
#define PACKAGE2_MINVER_810 0xC
|
||||||
|
#define PACKAGE2_MINVER_900 0xD
|
||||||
|
#define PACKAGE2_MINVER_910_CURRENT 0xE
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
|
|||||||
@@ -29,32 +29,24 @@ static inline uintptr_t get_pmc_base(void) {
|
|||||||
#define PMC_BASE (get_pmc_base())
|
#define PMC_BASE (get_pmc_base())
|
||||||
|
|
||||||
#define APBDEV_PMC_DPD_ENABLE_0 MAKE_REG32(PMC_BASE + 0x24)
|
#define APBDEV_PMC_DPD_ENABLE_0 MAKE_REG32(PMC_BASE + 0x24)
|
||||||
|
|
||||||
#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_REG32(PMC_BASE + 0x30)
|
#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_REG32(PMC_BASE + 0x30)
|
||||||
#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_REG32(PMC_BASE + 0x38)
|
#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_REG32(PMC_BASE + 0x38)
|
||||||
|
|
||||||
#define APBDEV_PMC_SCRATCH0_0 MAKE_REG32(PMC_BASE + 0x50)
|
#define APBDEV_PMC_SCRATCH0_0 MAKE_REG32(PMC_BASE + 0x50)
|
||||||
|
|
||||||
#define APBDEV_PMC_CRYPTO_OP_0 MAKE_REG32(PMC_BASE + 0xF4)
|
#define APBDEV_PMC_CRYPTO_OP_0 MAKE_REG32(PMC_BASE + 0xF4)
|
||||||
|
|
||||||
#define APBDEV_PM_0 MAKE_REG32(PMC_BASE + 0x14)
|
#define APBDEV_PM_0 MAKE_REG32(PMC_BASE + 0x14)
|
||||||
#define APBDEV_PMC_WAKE2_STATUS_0 MAKE_REG32(PMC_BASE + 0x168)
|
#define APBDEV_PMC_WAKE2_STATUS_0 MAKE_REG32(PMC_BASE + 0x168)
|
||||||
#define APBDEV_PMC_CNTRL2_0 MAKE_REG32(PMC_BASE + 0x440)
|
#define APBDEV_PMC_CNTRL2_0 MAKE_REG32(PMC_BASE + 0x440)
|
||||||
|
#define APBDEV_PMC_FUSE_CTRL MAKE_REG32(PMC_BASE + 0x450)
|
||||||
#define APBDEV_PMC_SCRATCH43_0 MAKE_REG32(PMC_BASE + 0x22C)
|
#define APBDEV_PMC_SCRATCH43_0 MAKE_REG32(PMC_BASE + 0x22C)
|
||||||
#define APBDEV_PMC_SEC_DISABLE8_0 MAKE_REG32(PMC_BASE + 0x5C0)
|
#define APBDEV_PMC_SEC_DISABLE8_0 MAKE_REG32(PMC_BASE + 0x5C0)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH112_0 MAKE_REG32(PMC_BASE + 0xB18)
|
#define APBDEV_PMC_SECURE_SCRATCH112_0 MAKE_REG32(PMC_BASE + 0xB18)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH113_0 MAKE_REG32(PMC_BASE + 0xB1C)
|
#define APBDEV_PMC_SECURE_SCRATCH113_0 MAKE_REG32(PMC_BASE + 0xB1C)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH114_0 MAKE_REG32(PMC_BASE + 0xB20)
|
#define APBDEV_PMC_SECURE_SCRATCH114_0 MAKE_REG32(PMC_BASE + 0xB20)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH115_0 MAKE_REG32(PMC_BASE + 0xB24)
|
#define APBDEV_PMC_SECURE_SCRATCH115_0 MAKE_REG32(PMC_BASE + 0xB24)
|
||||||
|
|
||||||
#define APBDEV_PMC_SCRATCH200_0 MAKE_REG32(PMC_BASE + 0x840)
|
#define APBDEV_PMC_SCRATCH200_0 MAKE_REG32(PMC_BASE + 0x840)
|
||||||
|
|
||||||
|
|
||||||
#define APBDEV_PMC_SEC_DISABLE3_0 MAKE_REG32(PMC_BASE + 0x2D8)
|
#define APBDEV_PMC_SEC_DISABLE3_0 MAKE_REG32(PMC_BASE + 0x2D8)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_REG32(PMC_BASE + 0x368)
|
#define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_REG32(PMC_BASE + 0x368)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_REG32(PMC_BASE + 0x36C)
|
#define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_REG32(PMC_BASE + 0x36C)
|
||||||
|
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH16_0 MAKE_REG32(PMC_BASE + 0x320)
|
#define APBDEV_PMC_SECURE_SCRATCH16_0 MAKE_REG32(PMC_BASE + 0x320)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH51_0 MAKE_REG32(PMC_BASE + 0x3AC)
|
#define APBDEV_PMC_SECURE_SCRATCH51_0 MAKE_REG32(PMC_BASE + 0x3AC)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH55_0 MAKE_REG32(PMC_BASE + 0x3BC)
|
#define APBDEV_PMC_SECURE_SCRATCH55_0 MAKE_REG32(PMC_BASE + 0x3BC)
|
||||||
@@ -70,5 +62,4 @@ static inline uintptr_t get_pmc_base(void) {
|
|||||||
#define APBDEV_PMC_SECURE_SCRATCH103_0 MAKE_REG32(PMC_BASE + 0xAF4)
|
#define APBDEV_PMC_SECURE_SCRATCH103_0 MAKE_REG32(PMC_BASE + 0xAF4)
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH39_0 MAKE_REG32(PMC_BASE + 0x37C)
|
#define APBDEV_PMC_SECURE_SCRATCH39_0 MAKE_REG32(PMC_BASE + 0x37C)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -77,6 +77,7 @@ static void enable_lp0_wake_events(void) {
|
|||||||
|
|
||||||
static void notify_pmic_shutdown(void) {
|
static void notify_pmic_shutdown(void) {
|
||||||
clkrst_reboot(CARDEVICE_I2C5);
|
clkrst_reboot(CARDEVICE_I2C5);
|
||||||
|
i2c_init(I2C_5);
|
||||||
if (fuse_get_bootrom_patch_version() >= 0x7F) {
|
if (fuse_get_bootrom_patch_version() >= 0x7F) {
|
||||||
i2c_send_pmic_cpu_shutdown_cmd();
|
i2c_send_pmic_cpu_shutdown_cmd();
|
||||||
}
|
}
|
||||||
@@ -132,7 +133,7 @@ static void setup_bpmp_sc7_firmware(void) {
|
|||||||
BPMP_VECTOR_UNK = 0x40003004; /* Reboot. */
|
BPMP_VECTOR_UNK = 0x40003004; /* Reboot. */
|
||||||
BPMP_VECTOR_IRQ = 0x40003004; /* Reboot. */
|
BPMP_VECTOR_IRQ = 0x40003004; /* Reboot. */
|
||||||
BPMP_VECTOR_FIQ = 0x40003004; /* Reboot. */
|
BPMP_VECTOR_FIQ = 0x40003004; /* Reboot. */
|
||||||
|
|
||||||
/* Hold the BPMP in reset. */
|
/* Hold the BPMP in reset. */
|
||||||
MAKE_CAR_REG(0x300) = 2;
|
MAKE_CAR_REG(0x300) = 2;
|
||||||
|
|
||||||
@@ -141,7 +142,7 @@ static void setup_bpmp_sc7_firmware(void) {
|
|||||||
for (unsigned int i = 0; i < sc7fw_bin_size; i += 4) {
|
for (unsigned int i = 0; i < sc7fw_bin_size; i += 4) {
|
||||||
write32le(lp0_entry_code, i, read32le(sc7fw_bin, i));
|
write32le(lp0_entry_code, i, read32le(sc7fw_bin, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
flush_dcache_range(lp0_entry_code, lp0_entry_code + sc7fw_bin_size);
|
flush_dcache_range(lp0_entry_code, lp0_entry_code + sc7fw_bin_size);
|
||||||
|
|
||||||
/* Take the BPMP out of reset. */
|
/* Take the BPMP out of reset. */
|
||||||
@@ -181,7 +182,7 @@ static void save_tzram_state(void) {
|
|||||||
flush_dcache_range(tzram_encryption_dst, tzram_encryption_dst + LP0_TZRAM_SAVE_SIZE);
|
flush_dcache_range(tzram_encryption_dst, tzram_encryption_dst + LP0_TZRAM_SAVE_SIZE);
|
||||||
flush_dcache_range(tzram_encryption_src, tzram_encryption_src + LP0_TZRAM_SAVE_SIZE);
|
flush_dcache_range(tzram_encryption_src, tzram_encryption_src + LP0_TZRAM_SAVE_SIZE);
|
||||||
|
|
||||||
/* Use the all-zero cmac buffer as an IV. */
|
/* Use the all-zero cmac buffer as an IV. */
|
||||||
se_aes_256_cbc_encrypt(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_encryption_dst, LP0_TZRAM_SAVE_SIZE, tzram_encryption_src, LP0_TZRAM_SAVE_SIZE, tzram_cmac);
|
se_aes_256_cbc_encrypt(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_encryption_dst, LP0_TZRAM_SAVE_SIZE, tzram_encryption_src, LP0_TZRAM_SAVE_SIZE, tzram_cmac);
|
||||||
flush_dcache_range(tzram_encryption_dst, tzram_encryption_dst + LP0_TZRAM_SAVE_SIZE);
|
flush_dcache_range(tzram_encryption_dst, tzram_encryption_dst + LP0_TZRAM_SAVE_SIZE);
|
||||||
|
|
||||||
@@ -189,12 +190,12 @@ static void save_tzram_state(void) {
|
|||||||
for (unsigned int i = 0; i < LP0_TZRAM_SAVE_SIZE; i += 4) {
|
for (unsigned int i = 0; i < LP0_TZRAM_SAVE_SIZE; i += 4) {
|
||||||
write32le(tzram_store_address, i, read32le(tzram_encryption_dst, i));
|
write32le(tzram_store_address, i, read32le(tzram_encryption_dst, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
flush_dcache_range(tzram_store_address, tzram_store_address + LP0_TZRAM_SAVE_SIZE);
|
flush_dcache_range(tzram_store_address, tzram_store_address + LP0_TZRAM_SAVE_SIZE);
|
||||||
|
|
||||||
/* Compute CMAC. */
|
/* Compute CMAC. */
|
||||||
se_compute_aes_256_cmac(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_cmac, sizeof(tzram_cmac), tzram_encryption_src, LP0_TZRAM_SAVE_SIZE);
|
se_compute_aes_256_cmac(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_cmac, sizeof(tzram_cmac), tzram_encryption_src, LP0_TZRAM_SAVE_SIZE);
|
||||||
|
|
||||||
/* Write CMAC, lock registers. */
|
/* Write CMAC, lock registers. */
|
||||||
APBDEV_PMC_SECURE_SCRATCH112_0 = tzram_cmac[0];
|
APBDEV_PMC_SECURE_SCRATCH112_0 = tzram_cmac[0];
|
||||||
APBDEV_PMC_SECURE_SCRATCH113_0 = tzram_cmac[1];
|
APBDEV_PMC_SECURE_SCRATCH113_0 = tzram_cmac[1];
|
||||||
@@ -240,7 +241,7 @@ void save_se_and_power_down_cpu(void) {
|
|||||||
/* Save context for warmboot to restore. */
|
/* Save context for warmboot to restore. */
|
||||||
save_tzram_state();
|
save_tzram_state();
|
||||||
save_se_state();
|
save_se_state();
|
||||||
|
|
||||||
/* Patch the bootrom to disable warmboot signature checks. */
|
/* Patch the bootrom to disable warmboot signature checks. */
|
||||||
MAKE_REG32(PMC_BASE + 0x118) = 0x2202E012;
|
MAKE_REG32(PMC_BASE + 0x118) = 0x2202E012;
|
||||||
MAKE_REG32(PMC_BASE + 0x11C) = 0x6001DC28;
|
MAKE_REG32(PMC_BASE + 0x11C) = 0x6001DC28;
|
||||||
@@ -248,14 +249,14 @@ void save_se_and_power_down_cpu(void) {
|
|||||||
if (!configitem_is_retail()) {
|
if (!configitem_is_retail()) {
|
||||||
uart_send(UART_A, "OYASUMI", 8);
|
uart_send(UART_A, "OYASUMI", 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
finalize_powerdown();
|
finalize_powerdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argument) {
|
uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argument) {
|
||||||
/* TODO: 6.0.0 introduces heavy deja vu mitigations. */
|
/* TODO: 6.0.0 introduces heavy deja vu mitigations. */
|
||||||
/* Exosphere may want to implement these. */
|
/* Exosphere may want to implement these. */
|
||||||
|
|
||||||
/* Ensure SMC call is to enter deep sleep. */
|
/* Ensure SMC call is to enter deep sleep. */
|
||||||
if ((power_state & 0x17FFF) != 0x1001B) {
|
if ((power_state & 0x17FFF) != 0x1001B) {
|
||||||
return 0xFFFFFFFD;
|
return 0xFFFFFFFD;
|
||||||
@@ -285,7 +286,7 @@ uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argumen
|
|||||||
|
|
||||||
/* Prepare the current core for sleep. */
|
/* Prepare the current core for sleep. */
|
||||||
configure_flow_regs_for_sleep();
|
configure_flow_regs_for_sleep();
|
||||||
|
|
||||||
/* Save core context. */
|
/* Save core context. */
|
||||||
set_core_entrypoint_and_argument(get_core_id(), entrypoint, argument);
|
set_core_entrypoint_and_argument(get_core_id(), entrypoint, argument);
|
||||||
save_current_core_context();
|
save_current_core_context();
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ void set_security_engine_callback(unsigned int (*callback)(void)) {
|
|||||||
|
|
||||||
/* Fires on Security Engine operation completion. */
|
/* Fires on Security Engine operation completion. */
|
||||||
void se_operation_completed(void) {
|
void se_operation_completed(void) {
|
||||||
se_get_regs()->INT_ENABLE_REG = 0;
|
se_get_regs()->SE_INT_ENABLE = 0;
|
||||||
if (g_se_callback != NULL) {
|
if (g_se_callback != NULL) {
|
||||||
g_se_callback();
|
g_se_callback();
|
||||||
g_se_callback = NULL;
|
g_se_callback = NULL;
|
||||||
@@ -69,14 +69,14 @@ void se_operation_completed(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void se_check_error_status_reg(void) {
|
void se_check_error_status_reg(void) {
|
||||||
if (se_get_regs()->ERR_STATUS_REG) {
|
if (se_get_regs()->SE_ERR_STATUS) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_check_for_error(void) {
|
void se_check_for_error(void) {
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
volatile tegra_se_t *se = se_get_regs();
|
||||||
if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) {
|
if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ void se_trigger_interrupt(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void se_verify_flags_cleared(void) {
|
void se_verify_flags_cleared(void) {
|
||||||
if (se_get_regs()->FLAGS_REG & 3) {
|
if (se_get_regs()->SE_STATUS & 3) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,12 +129,12 @@ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
|||||||
|
|
||||||
/* Misc flags. */
|
/* Misc flags. */
|
||||||
if (flags & ~0x80) {
|
if (flags & ~0x80) {
|
||||||
se->AES_KEYSLOT_FLAGS[keyslot] = ~flags;
|
se->SE_CRYPTO_KEYTABLE_ACCESS[keyslot] = ~flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable keyslot reads. */
|
/* Disable keyslot reads. */
|
||||||
if (flags & 0x80) {
|
if (flags & 0x80) {
|
||||||
se->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
|
se->SE_CRYPTO_SECURITY_PERKEY &= ~(1 << keyslot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,12 +149,12 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
|||||||
/* Misc flags. */
|
/* Misc flags. */
|
||||||
if (flags & ~0x80) {
|
if (flags & ~0x80) {
|
||||||
/* TODO: Why are flags assigned this way? */
|
/* TODO: Why are flags assigned this way? */
|
||||||
se->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
|
se->SE_RSA_KEYTABLE_ACCESS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable keyslot reads. */
|
/* Disable keyslot reads. */
|
||||||
if (flags & 0x80) {
|
if (flags & 0x80) {
|
||||||
se->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
|
se->SE_RSA_SECURITY_PERKEY &= ~(1 << keyslot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,8 +167,8 @@ void clear_aes_keyslot(unsigned int keyslot) {
|
|||||||
|
|
||||||
/* Zero out the whole keyslot and IV. */
|
/* Zero out the whole keyslot and IV. */
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
for (unsigned int i = 0; i < 0x10; i++) {
|
||||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
|
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
|
||||||
se->AES_KEYTABLE_DATA = 0;
|
se->SE_CRYPTO_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,13 +182,13 @@ void clear_rsa_keyslot(unsigned int keyslot) {
|
|||||||
/* Zero out the whole keyslot. */
|
/* Zero out the whole keyslot. */
|
||||||
for (unsigned int i = 0; i < 0x40; i++) {
|
for (unsigned int i = 0; i < 0x40; i++) {
|
||||||
/* Select Keyslot Modulus[i] */
|
/* Select Keyslot Modulus[i] */
|
||||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
|
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
|
||||||
se->RSA_KEYTABLE_DATA = 0;
|
se->SE_RSA_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < 0x40; i++) {
|
for (unsigned int i = 0; i < 0x40; i++) {
|
||||||
/* Select Keyslot Expontent[i] */
|
/* Select Keyslot Expontent[i] */
|
||||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
||||||
se->RSA_KEYTABLE_DATA = 0;
|
se->SE_RSA_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,8 +200,8 @@ void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (key_size >> 2); i++) {
|
for (size_t i = 0; i < (key_size >> 2); i++) {
|
||||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
|
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
|
||||||
se->AES_KEYTABLE_DATA = read32le(key, 4 * i);
|
se->SE_CRYPTO_KEYTABLE_DATA = read32le(key, 4 * i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,13 +213,13 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (modulus_size >> 2); i++) {
|
for (size_t i = 0; i < (modulus_size >> 2); i++) {
|
||||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i;
|
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i;
|
||||||
se->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4);
|
se->SE_RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (exp_size >> 2); i++) {
|
for (size_t i = 0; i < (exp_size >> 2); i++) {
|
||||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
||||||
se->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4);
|
se->SE_RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_se_modulus_sizes[keyslot] = modulus_size;
|
g_se_modulus_sizes[keyslot] = modulus_size;
|
||||||
@@ -234,8 +234,8 @@ void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (iv_size >> 2); i++) {
|
for (size_t i = 0; i < (iv_size >> 2); i++) {
|
||||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
||||||
se->AES_KEYTABLE_DATA = read32le(iv, 4 * i);
|
se->SE_CRYPTO_KEYTABLE_DATA = read32le(iv, 4 * i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,14 +247,14 @@ void clear_aes_keyslot_iv(unsigned int keyslot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (0x10 >> 2); i++) {
|
for (size_t i = 0; i < (0x10 >> 2); i++) {
|
||||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
||||||
se->AES_KEYTABLE_DATA = 0;
|
se->SE_CRYPTO_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_se_ctr(const void *ctr) {
|
void set_se_ctr(const void *ctr) {
|
||||||
for (unsigned int i = 0; i < 4; i++) {
|
for (unsigned int i = 0; i < 4; i++) {
|
||||||
se_get_regs()->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4);
|
se_get_regs()->SE_CRYPTO_LINEAR_CTR[i] = read32le(ctr, i * 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,10 +265,10 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr
|
|||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB);
|
se->SE_CONFIG = (ALG_AES_DEC | DST_KEYTAB);
|
||||||
se->CRYPTO_REG = keyslot_src << 24;
|
se->SE_CRYPTO_CONFIG = keyslot_src << 24;
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8;
|
se->SE_CRYPTO_KEYTABLE_DST = keyslot_dst << 8;
|
||||||
|
|
||||||
flush_dcache_range(wrapped_key, (const uint8_t *)wrapped_key + wrapped_key_size);
|
flush_dcache_range(wrapped_key, (const uint8_t *)wrapped_key + wrapped_key_size);
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size);
|
trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size);
|
||||||
@@ -287,35 +287,35 @@ void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr,
|
|||||||
|
|
||||||
/* Setup Config register. */
|
/* Setup Config register. */
|
||||||
if (encrypt) {
|
if (encrypt) {
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY);
|
||||||
} else {
|
} else {
|
||||||
se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
|
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup Crypto register. */
|
/* Setup Crypto register. */
|
||||||
se->CRYPTO_REG = crypt_config | (keyslot << 24) | (encrypt << 8);
|
se->SE_CRYPTO_CONFIG = crypt_config | (keyslot << 24) | (encrypt << 8);
|
||||||
|
|
||||||
/* Mark this encryption as insecure -- this makes the SE not a secure busmaster. */
|
/* Mark this encryption as insecure -- this makes the SE not a secure busmaster. */
|
||||||
se->CRYPTO_REG |= 0x80000000;
|
se->SE_CRYPTO_CONFIG |= 0x80000000;
|
||||||
|
|
||||||
/* Appropriate number of blocks. */
|
/* Appropriate number of blocks. */
|
||||||
se->BLOCK_COUNT_REG = (size >> 4) - 1;
|
se->SE_CRYPTO_LAST_BLOCK = (size >> 4) - 1;
|
||||||
|
|
||||||
/* Set the callback, for after the async operation. */
|
/* Set the callback, for after the async operation. */
|
||||||
set_security_engine_callback(callback);
|
set_security_engine_callback(callback);
|
||||||
|
|
||||||
/* Enable SE Interrupt firing for async op. */
|
/* Enable SE Interrupt firing for async op. */
|
||||||
se->INT_ENABLE_REG = 0x10;
|
se->SE_INT_ENABLE = 0x10;
|
||||||
|
|
||||||
/* Setup Input/Output lists */
|
/* Setup Input/Output lists */
|
||||||
se->IN_LL_ADDR_REG = in_ll_paddr;
|
se->SE_IN_LL_ADDR = in_ll_paddr;
|
||||||
se->OUT_LL_ADDR_REG = out_ll_paddr;
|
se->SE_OUT_LL_ADDR = out_ll_paddr;
|
||||||
|
|
||||||
/* Set registers for operation. */
|
/* Set registers for operation. */
|
||||||
se->ERR_STATUS_REG = se->ERR_STATUS_REG;
|
se->SE_ERR_STATUS = se->SE_ERR_STATUS;
|
||||||
se->INT_STATUS_REG = se->INT_STATUS_REG;
|
se->SE_INT_STATUS = se->SE_INT_STATUS;
|
||||||
se->OPERATION_REG = 1;
|
se->SE_OPERATION = 1;
|
||||||
(void)(se->OPERATION_REG);
|
(void)(se->SE_OPERATION);
|
||||||
|
|
||||||
/* Ensure writes go through. */
|
/* Ensure writes go through. */
|
||||||
__dsb_ish();
|
__dsb_ish();
|
||||||
@@ -323,7 +323,7 @@ void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr,
|
|||||||
|
|
||||||
void se_aes_ctr_crypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *ctr, unsigned int (*callback)(void)) {
|
void se_aes_ctr_crypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *ctr, unsigned int (*callback)(void)) {
|
||||||
/* Unknown what this write does, but official code writes it for CTR mode. */
|
/* Unknown what this write does, but official code writes it for CTR mode. */
|
||||||
se_get_regs()->SPARE_0 = 1;
|
se_get_regs()->SE_SPARE = 1;
|
||||||
set_se_ctr(ctr);
|
set_se_ctr(ctr);
|
||||||
se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x81E, true, callback);
|
se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x81E, true, callback);
|
||||||
}
|
}
|
||||||
@@ -351,20 +351,20 @@ void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*cal
|
|||||||
stack_buf[i] = *((uint8_t *)buf + size - i - 1);
|
stack_buf[i] = *((uint8_t *)buf + size - i - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_RSA | DST_RSAREG);
|
se->SE_CONFIG = (ALG_RSA | DST_RSAREG);
|
||||||
se->RSA_CONFIG = keyslot << 24;
|
se->SE_RSA_CONFIG = keyslot << 24;
|
||||||
se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
|
se->SE_RSA_KEY_SIZE = (g_se_modulus_sizes[keyslot] >> 6) - 1;
|
||||||
se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
|
se->SE_RSA_EXP_SIZE = g_se_exp_sizes[keyslot] >> 2;
|
||||||
|
|
||||||
set_security_engine_callback(callback);
|
set_security_engine_callback(callback);
|
||||||
|
|
||||||
/* Enable SE Interrupt firing for async op. */
|
/* Enable SE interrupt firing for async op. */
|
||||||
se->INT_ENABLE_REG = 0x10;
|
se->SE_INT_ENABLE = 0x10;
|
||||||
|
|
||||||
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
|
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
|
||||||
trigger_se_rsa_op(stack_buf, size);
|
trigger_se_rsa_op(stack_buf, size);
|
||||||
|
|
||||||
while (!(se->INT_STATUS_REG & 2)) { /* Wait a while */ }
|
while (!(se->SE_INT_STATUS & 2)) { /* Wait a while */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
||||||
@@ -380,10 +380,10 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co
|
|||||||
stack_buf[i] = *((uint8_t *)src + src_size - i - 1);
|
stack_buf[i] = *((uint8_t *)src + src_size - i - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_RSA | DST_RSAREG);
|
se->SE_CONFIG = (ALG_RSA | DST_RSAREG);
|
||||||
se->RSA_CONFIG = keyslot << 24;
|
se->SE_RSA_CONFIG = keyslot << 24;
|
||||||
se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
|
se->SE_RSA_KEY_SIZE = (g_se_modulus_sizes[keyslot] >> 6) - 1;
|
||||||
se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
|
se->SE_RSA_EXP_SIZE = g_se_exp_sizes[keyslot] >> 2;
|
||||||
|
|
||||||
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
|
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size);
|
trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size);
|
||||||
@@ -401,7 +401,7 @@ void se_get_exp_mod_output(void *buf, size_t size) {
|
|||||||
|
|
||||||
/* Copy endian swapped output. */
|
/* Copy endian swapped output. */
|
||||||
while (num_dwords) {
|
while (num_dwords) {
|
||||||
*p_out = read32be(se_get_regs()->RSA_OUTPUT, offset);
|
*p_out = read32be(se_get_regs()->SE_RSA_OUTPUT, offset);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
p_out--;
|
p_out--;
|
||||||
num_dwords--;
|
num_dwords--;
|
||||||
@@ -472,13 +472,13 @@ void trigger_se_rsa_op(void *buf, size_t size) {
|
|||||||
ll_init(&in_ll, (void *)buf, size);
|
ll_init(&in_ll, (void *)buf, size);
|
||||||
|
|
||||||
/* Set the input LL. */
|
/* Set the input LL. */
|
||||||
se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll);
|
se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll);
|
||||||
|
|
||||||
/* Set registers for operation. */
|
/* Set registers for operation. */
|
||||||
se->ERR_STATUS_REG = se->ERR_STATUS_REG;
|
se->SE_ERR_STATUS = se->SE_ERR_STATUS;
|
||||||
se->INT_STATUS_REG = se->INT_STATUS_REG;
|
se->SE_INT_STATUS = se->SE_INT_STATUS;
|
||||||
se->OPERATION_REG = 1;
|
se->SE_OPERATION = 1;
|
||||||
(void)(se->OPERATION_REG);
|
(void)(se->SE_OPERATION);
|
||||||
|
|
||||||
/* Ensure writes go through. */
|
/* Ensure writes go through. */
|
||||||
__dsb_ish();
|
__dsb_ish();
|
||||||
@@ -495,18 +495,18 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v
|
|||||||
__dsb_sy();
|
__dsb_sy();
|
||||||
|
|
||||||
/* Set the LLs. */
|
/* Set the LLs. */
|
||||||
se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll);
|
se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll);
|
||||||
se->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll);
|
se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll);
|
||||||
|
|
||||||
/* Set registers for operation. */
|
/* Set registers for operation. */
|
||||||
se->ERR_STATUS_REG = se->ERR_STATUS_REG;
|
se->SE_ERR_STATUS = se->SE_ERR_STATUS;
|
||||||
se->INT_STATUS_REG = se->INT_STATUS_REG;
|
se->SE_INT_STATUS = se->SE_INT_STATUS;
|
||||||
se->OPERATION_REG = op;
|
se->SE_OPERATION = op;
|
||||||
(void)(se->OPERATION_REG);
|
(void)(se->SE_OPERATION);
|
||||||
|
|
||||||
__dsb_ish();
|
__dsb_ish();
|
||||||
|
|
||||||
while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
|
while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ }
|
||||||
|
|
||||||
se_check_for_error();
|
se_check_for_error();
|
||||||
}
|
}
|
||||||
@@ -526,7 +526,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src,
|
|||||||
flush_dcache_range(block, block + sizeof(block));
|
flush_dcache_range(block, block + sizeof(block));
|
||||||
|
|
||||||
/* Trigger AES operation. */
|
/* Trigger AES operation. */
|
||||||
se_get_regs()->BLOCK_COUNT_REG = 0;
|
se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
|
trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
|
||||||
|
|
||||||
/* Copy output data into dst. */
|
/* Copy output data into dst. */
|
||||||
@@ -553,15 +553,15 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo
|
|||||||
unsigned int num_blocks = src_size >> 4;
|
unsigned int num_blocks = src_size >> 4;
|
||||||
|
|
||||||
/* Unknown what this write does, but official code writes it for CTR mode. */
|
/* Unknown what this write does, but official code writes it for CTR mode. */
|
||||||
se->SPARE_0 = 1;
|
se->SE_SPARE = 1;
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | 0x91E;
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x91E;
|
||||||
set_se_ctr(ctr);
|
set_se_ctr(ctr);
|
||||||
|
|
||||||
/* Handle any aligned blocks. */
|
/* Handle any aligned blocks. */
|
||||||
size_t aligned_size = (size_t)num_blocks << 4;
|
size_t aligned_size = (size_t)num_blocks << 4;
|
||||||
if (aligned_size) {
|
if (aligned_size) {
|
||||||
se->BLOCK_COUNT_REG = num_blocks - 1;
|
se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1;
|
||||||
trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size);
|
trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,8 +587,8 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
|
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
|
||||||
se->CRYPTO_REG = keyslot << 24 | 0x100;
|
se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100;
|
||||||
flush_dcache_range((uint8_t *)src, (uint8_t *)src + 0x10);
|
flush_dcache_range((uint8_t *)src, (uint8_t *)src + 0x10);
|
||||||
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
||||||
flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + 0x10);
|
flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + 0x10);
|
||||||
@@ -611,8 +611,8 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size,
|
|||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
|
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY);
|
||||||
se->CRYPTO_REG = keyslot << 24;
|
se->SE_CRYPTO_CONFIG = keyslot << 24;
|
||||||
flush_dcache_range((uint8_t *)src, (uint8_t *)src + 0x10);
|
flush_dcache_range((uint8_t *)src, (uint8_t *)src + 0x10);
|
||||||
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
||||||
flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + 0x10);
|
flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + 0x10);
|
||||||
@@ -649,16 +649,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
|
|||||||
shift_left_xor_rb(derived_key);
|
shift_left_xor_rb(derived_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | (0x145);
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145);
|
||||||
clear_aes_keyslot_iv(keyslot);
|
clear_aes_keyslot_iv(keyslot);
|
||||||
|
|
||||||
unsigned int num_blocks = (data_size + 0xF) >> 4;
|
unsigned int num_blocks = (data_size + 0xF) >> 4;
|
||||||
/* Handle aligned blocks. */
|
/* Handle aligned blocks. */
|
||||||
if (num_blocks > 1) {
|
if (num_blocks > 1) {
|
||||||
se->BLOCK_COUNT_REG = num_blocks - 2;
|
se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2;
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
|
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
|
||||||
se->CRYPTO_REG |= 0x80;
|
se->SE_CRYPTO_CONFIG |= 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create final block. */
|
/* Create final block. */
|
||||||
@@ -675,13 +675,13 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Perform last operation. */
|
/* Perform last operation. */
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
flush_dcache_range(last_block, last_block + sizeof(last_block));
|
flush_dcache_range(last_block, last_block + sizeof(last_block));
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
|
trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
|
||||||
|
|
||||||
/* Copy output CMAC. */
|
/* Copy output CMAC. */
|
||||||
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
|
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
|
||||||
((uint32_t *)cmac)[i] = read32le(se->HASH_RESULT_REG, i << 2);
|
((uint32_t *)cmac)[i] = read32le(se->SE_HASH_RESULT, i << 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,10 +699,10 @@ void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, co
|
|||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | 0x144;
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144;
|
||||||
set_aes_keyslot_iv(keyslot, iv, 0x10);
|
set_aes_keyslot_iv(keyslot, iv, 0x10);
|
||||||
se->BLOCK_COUNT_REG = (src_size >> 4) - 1;
|
se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1;
|
||||||
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
|
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,23 +711,23 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
|
|||||||
volatile tegra_se_t *se = se_get_regs();
|
volatile tegra_se_t *se = se_get_regs();
|
||||||
|
|
||||||
/* Setup config for SHA256, size = BITS(src_size) */
|
/* Setup config for SHA256, size = BITS(src_size) */
|
||||||
se->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
|
se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
|
||||||
se->SHA_CONFIG_REG = 1;
|
se->SE_SHA_CONFIG = 1;
|
||||||
se->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3);
|
se->SE_SHA_MSG_LENGTH[0] = (uint32_t)(src_size << 3);
|
||||||
se->_0x208 = 0;
|
se->SE_SHA_MSG_LENGTH[1] = 0;
|
||||||
se->_0x20C = 0;
|
se->SE_SHA_MSG_LENGTH[2] = 0;
|
||||||
se->_0x210 = 0;
|
se->SE_SHA_MSG_LENGTH[3] = 0;
|
||||||
se->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3);
|
se->SE_SHA_MSG_LEFT[0] = (uint32_t)(src_size << 3);
|
||||||
se->_0x218 = 0;
|
se->SE_SHA_MSG_LEFT[1] = 0;
|
||||||
se->_0x21C = 0;
|
se->SE_SHA_MSG_LEFT[2] = 0;
|
||||||
se->_0x220 = 0;
|
se->SE_SHA_MSG_LEFT[3] = 0;
|
||||||
|
|
||||||
/* Trigger the operation. */
|
/* Trigger the operation. */
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, src, src_size);
|
trigger_se_blocking_op(OP_START, NULL, 0, src, src_size);
|
||||||
|
|
||||||
/* Copy output hash. */
|
/* Copy output hash. */
|
||||||
for (unsigned int i = 0; i < (0x20 >> 2); i++) {
|
for (unsigned int i = 0; i < (0x20 >> 2); i++) {
|
||||||
((uint32_t *)dst)[i] = read32be(se->HASH_RESULT_REG, i << 2);
|
((uint32_t *)dst)[i] = read32be(se->SE_HASH_RESULT, i << 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,12 +743,12 @@ void se_initialize_rng(unsigned int keyslot) {
|
|||||||
/* This will be discarded, when done. */
|
/* This will be discarded, when done. */
|
||||||
uint8_t output_buf[0x10];
|
uint8_t output_buf[0x10];
|
||||||
|
|
||||||
se->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */
|
se->SE_RNG_SRC_CONFIG = 3; /* Entropy enable + Entropy lock enable */
|
||||||
se->RNG_RESEED_INTERVAL_REG = 70001;
|
se->SE_RNG_RESEED_INTERVAL = 70001;
|
||||||
se->CONFIG_REG = (ALG_RNG | DST_MEMORY);
|
se->SE_CONFIG = (ALG_RNG | DST_MEMORY);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | 0x108;
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108;
|
||||||
se->RNG_CONFIG_REG = 5;
|
se->SE_RNG_CONFIG = 5;
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0);
|
trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -761,12 +761,12 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
|
|||||||
|
|
||||||
uint32_t num_blocks = size >> 4;
|
uint32_t num_blocks = size >> 4;
|
||||||
size_t aligned_size = num_blocks << 4;
|
size_t aligned_size = num_blocks << 4;
|
||||||
se->CONFIG_REG = (ALG_RNG | DST_MEMORY);
|
se->SE_CONFIG = (ALG_RNG | DST_MEMORY);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | 0x108;
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108;
|
||||||
se->RNG_CONFIG_REG = 4;
|
se->SE_RNG_CONFIG = 4;
|
||||||
|
|
||||||
if (num_blocks >= 1) {
|
if (num_blocks >= 1) {
|
||||||
se->BLOCK_COUNT_REG = num_blocks - 1;
|
se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1;
|
||||||
trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0);
|
trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0);
|
||||||
}
|
}
|
||||||
if (size > aligned_size) {
|
if (size > aligned_size) {
|
||||||
@@ -778,15 +778,15 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
|
|||||||
void se_set_in_context_save_mode(bool is_context_save_mode) {
|
void se_set_in_context_save_mode(bool is_context_save_mode) {
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
volatile tegra_se_t *se = se_get_regs();
|
||||||
|
|
||||||
uint32_t val = se->_0x0;
|
uint32_t val = se->SE_SE_SECURITY;
|
||||||
if (is_context_save_mode) {
|
if (is_context_save_mode) {
|
||||||
val |= 0x10000;
|
val |= 0x10000;
|
||||||
} else {
|
} else {
|
||||||
val &= 0xFFFEFFFF;
|
val &= 0xFFFEFFFF;
|
||||||
}
|
}
|
||||||
se->_0x0 = val;
|
se->SE_SE_SECURITY = val;
|
||||||
/* Perform a useless read from flags reg. */
|
/* Perform a useless read from flags reg. */
|
||||||
(void)(se->FLAGS_REG);
|
(void)(se->SE_STATUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) {
|
void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) {
|
||||||
@@ -797,26 +797,26 @@ void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Setup Config. */
|
/* Setup Config. */
|
||||||
se->CONFIG_REG = (ALG_RNG | DST_KEYTAB);
|
se->SE_CONFIG = (ALG_RNG | DST_KEYTAB);
|
||||||
se->CRYPTO_REG = (rng_keyslot << 24) | 0x108;
|
se->SE_CRYPTO_CONFIG = (rng_keyslot << 24) | 0x108;
|
||||||
se->RNG_CONFIG_REG = 4;
|
se->SE_RNG_CONFIG = 4;
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
|
|
||||||
/* Generate low part of key. */
|
/* Generate low part of key. */
|
||||||
se->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8);
|
se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8);
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
|
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
|
||||||
/* Generate high part of key. */
|
/* Generate high part of key. */
|
||||||
se->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8) | 1;
|
se->SE_CRYPTO_KEYTABLE_DST = (dst_keyslot << 8) | 1;
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
|
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_generate_srk(unsigned int srkgen_keyslot) {
|
void se_generate_srk(unsigned int srkgen_keyslot) {
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
volatile tegra_se_t *se = se_get_regs();
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_RNG | DST_SRK);
|
se->SE_CONFIG = (ALG_RNG | DST_SRK);
|
||||||
se->CRYPTO_REG = (srkgen_keyslot << 24) | 0x108;
|
se->SE_CRYPTO_CONFIG = (srkgen_keyslot << 24) | 0x108;
|
||||||
se->RNG_CONFIG_REG = 6;
|
se->SE_RNG_CONFIG = 6;
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
|
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -853,39 +853,39 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void
|
|||||||
flush_dcache_range(work_buf, work_buf + 0x10);
|
flush_dcache_range(work_buf, work_buf + 0x10);
|
||||||
|
|
||||||
/* Save random initial block. */
|
/* Save random initial block. */
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY);
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM);
|
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM);
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
se_encrypt_with_srk(dst, 0x10, work_buf, 0x10);
|
se_encrypt_with_srk(dst, 0x10, work_buf, 0x10);
|
||||||
|
|
||||||
/* Save Sticky Bits. */
|
/* Save Sticky Bits. */
|
||||||
for (unsigned int i = 0; i < 0x2; i++) {
|
for (unsigned int i = 0; i < 0x2; i++) {
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT);
|
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT);
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
se_encrypt_with_srk(dst + 0x10 + (i * 0x10), 0x10, NULL, 0);
|
se_encrypt_with_srk(dst + 0x10 + (i * 0x10), 0x10, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save AES Key Table. */
|
/* Save AES Key Table. */
|
||||||
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
|
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS);
|
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS);
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
se_encrypt_with_srk(dst + 0x30 + (i * 0x20), 0x10, NULL, 0);
|
se_encrypt_with_srk(dst + 0x30 + (i * 0x20), 0x10, NULL, 0);
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_HIGH_BITS);
|
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_HIGH_BITS);
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
se_encrypt_with_srk(dst + 0x40 + (i * 0x20), 0x10, NULL, 0);
|
se_encrypt_with_srk(dst + 0x40 + (i * 0x20), 0x10, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save AES Original IVs. */
|
/* Save AES Original IVs. */
|
||||||
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
|
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV);
|
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV);
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
se_encrypt_with_srk(dst + 0x230 + (i * 0x10), 0x10, NULL, 0);
|
se_encrypt_with_srk(dst + 0x230 + (i * 0x10), 0x10, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save AES Updated IVs */
|
/* Save AES Updated IVs */
|
||||||
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
|
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV);
|
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV);
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
se_encrypt_with_srk(dst + 0x330 + (i * 0x10), 0x10, NULL, 0);
|
se_encrypt_with_srk(dst + 0x330 + (i * 0x10), 0x10, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -894,8 +894,8 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void
|
|||||||
for (unsigned int rsa_key = 0; rsa_key < KEYSLOT_RSA_MAX; rsa_key++) {
|
for (unsigned int rsa_key = 0; rsa_key < KEYSLOT_RSA_MAX; rsa_key++) {
|
||||||
for (unsigned int mod_exp = 0; mod_exp < 2; mod_exp++) {
|
for (unsigned int mod_exp = 0; mod_exp < 2; mod_exp++) {
|
||||||
for (unsigned int sub_block = 0; sub_block < 0x10; sub_block++) {
|
for (unsigned int sub_block = 0; sub_block < 0x10; sub_block++) {
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_RSA) | ((2 * rsa_key + (1 - mod_exp)) << CTX_SAVE_RSA_KEY_INDEX_SHIFT) | (sub_block << CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT);
|
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_KEYTABLE_RSA) | ((2 * rsa_key + (1 - mod_exp)) << CTX_SAVE_RSA_KEY_INDEX_SHIFT) | (sub_block << CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT);
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
se_encrypt_with_srk(rsa_ctx_out, 0x10, NULL, 0);
|
se_encrypt_with_srk(rsa_ctx_out, 0x10, NULL, 0);
|
||||||
rsa_ctx_out += 0x10;
|
rsa_ctx_out += 0x10;
|
||||||
}
|
}
|
||||||
@@ -904,14 +904,14 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void
|
|||||||
|
|
||||||
/* Save "Known Pattern. " */
|
/* Save "Known Pattern. " */
|
||||||
static const uint8_t context_save_known_pattern[0x10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
|
static const uint8_t context_save_known_pattern[0x10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM);
|
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_MEM);
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
se_encrypt_with_srk(dst + 0x830, 0x10, context_save_known_pattern, 0x10);
|
se_encrypt_with_srk(dst + 0x830, 0x10, context_save_known_pattern, 0x10);
|
||||||
|
|
||||||
/* Save SRK into PMC registers. */
|
/* Save SRK into PMC registers. */
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_SRK);
|
se->SE_CTX_SAVE_CONFIG = (CTX_SAVE_SRC_SRK);
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
se_encrypt_with_srk(work_buf, 0, NULL, 0);
|
se_encrypt_with_srk(work_buf, 0, NULL, 0);
|
||||||
se->CONFIG_REG = 0;
|
se->SE_CONFIG = 0;
|
||||||
se_encrypt_with_srk(work_buf, 0, NULL, 0);
|
se_encrypt_with_srk(work_buf, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,71 +103,59 @@
|
|||||||
#define RSA_2048_BYTES 0x100
|
#define RSA_2048_BYTES 0x100
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t _0x0;
|
uint32_t SE_SE_SECURITY;
|
||||||
uint32_t _0x4;
|
uint32_t SE_TZRAM_SECURITY;
|
||||||
uint32_t OPERATION_REG;
|
uint32_t SE_OPERATION;
|
||||||
uint32_t INT_ENABLE_REG;
|
uint32_t SE_INT_ENABLE;
|
||||||
uint32_t INT_STATUS_REG;
|
uint32_t SE_INT_STATUS;
|
||||||
uint32_t CONFIG_REG;
|
uint32_t SE_CONFIG;
|
||||||
uint32_t IN_LL_ADDR_REG;
|
uint32_t SE_IN_LL_ADDR;
|
||||||
uint32_t _0x1C;
|
uint32_t SE_IN_CUR_BYTE_ADDR;
|
||||||
uint32_t _0x20;
|
uint32_t SE_IN_CUR_LL_ID;
|
||||||
uint32_t OUT_LL_ADDR_REG;
|
uint32_t SE_OUT_LL_ADDR;
|
||||||
uint32_t _0x28;
|
uint32_t SE_OUT_CUR_BYTE_ADDR;
|
||||||
uint32_t _0x2C;
|
uint32_t SE_OUT_CUR_LL_ID;
|
||||||
uint8_t HASH_RESULT_REG[0x20];
|
uint32_t SE_HASH_RESULT[0x10];
|
||||||
uint8_t _0x50[0x20];
|
uint32_t SE_CTX_SAVE_CONFIG;
|
||||||
uint32_t CONTEXT_SAVE_CONFIG_REG;
|
uint32_t _0x74[0x63];
|
||||||
uint8_t _0x74[0x18C];
|
uint32_t SE_SHA_CONFIG;
|
||||||
uint32_t SHA_CONFIG_REG;
|
uint32_t SE_SHA_MSG_LENGTH[0x4];
|
||||||
uint32_t SHA_MSG_LENGTH_REG;
|
uint32_t SE_SHA_MSG_LEFT[0x4];
|
||||||
uint32_t _0x208;
|
uint32_t _0x224[0x17];
|
||||||
uint32_t _0x20C;
|
uint32_t SE_CRYPTO_SECURITY_PERKEY;
|
||||||
uint32_t _0x210;
|
uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10];
|
||||||
uint32_t SHA_MSG_LEFT_REG;
|
uint32_t _0x2C4[0x10];
|
||||||
uint32_t _0x218;
|
uint32_t SE_CRYPTO_CONFIG;
|
||||||
uint32_t _0x21C;
|
uint32_t SE_CRYPTO_LINEAR_CTR[0x4];
|
||||||
uint32_t _0x220;
|
uint32_t SE_CRYPTO_LAST_BLOCK;
|
||||||
uint32_t _0x224;
|
uint32_t SE_CRYPTO_KEYTABLE_ADDR;
|
||||||
uint8_t _0x228[0x58];
|
uint32_t SE_CRYPTO_KEYTABLE_DATA;
|
||||||
uint32_t AES_KEY_READ_DISABLE_REG;
|
uint32_t _0x324[0x3];
|
||||||
uint32_t AES_KEYSLOT_FLAGS[0x10];
|
uint32_t SE_CRYPTO_KEYTABLE_DST;
|
||||||
uint8_t _0x2C4[0x3C];
|
uint32_t _0x334[0x3];
|
||||||
uint32_t _0x300;
|
uint32_t SE_RNG_CONFIG;
|
||||||
uint32_t CRYPTO_REG;
|
uint32_t SE_RNG_SRC_CONFIG;
|
||||||
uint32_t CRYPTO_CTR_REG[4];
|
uint32_t SE_RNG_RESEED_INTERVAL;
|
||||||
uint32_t BLOCK_COUNT_REG;
|
uint32_t _0x34C[0x2D];
|
||||||
uint32_t AES_KEYTABLE_ADDR;
|
uint32_t SE_RSA_CONFIG;
|
||||||
uint32_t AES_KEYTABLE_DATA;
|
uint32_t SE_RSA_KEY_SIZE;
|
||||||
uint32_t _0x324;
|
uint32_t SE_RSA_EXP_SIZE;
|
||||||
uint32_t _0x328;
|
uint32_t SE_RSA_SECURITY_PERKEY;
|
||||||
uint32_t _0x32C;
|
uint32_t SE_RSA_KEYTABLE_ACCESS[0x2];
|
||||||
uint32_t CRYPTO_KEYTABLE_DST_REG;
|
uint32_t _0x418[0x2];
|
||||||
uint8_t _0x334[0xC];
|
uint32_t SE_RSA_KEYTABLE_ADDR;
|
||||||
uint32_t RNG_CONFIG_REG;
|
uint32_t SE_RSA_KEYTABLE_DATA;
|
||||||
uint32_t RNG_SRC_CONFIG_REG;
|
uint32_t SE_RSA_OUTPUT[0x40];
|
||||||
uint32_t RNG_RESEED_INTERVAL_REG;
|
uint32_t _0x528[0xB6];
|
||||||
uint8_t _0x34C[0xB4];
|
uint32_t SE_STATUS;
|
||||||
uint32_t RSA_CONFIG;
|
uint32_t SE_ERR_STATUS;
|
||||||
uint32_t RSA_KEY_SIZE_REG;
|
uint32_t SE_MISC;
|
||||||
uint32_t RSA_EXP_SIZE_REG;
|
uint32_t SE_SPARE;
|
||||||
uint32_t RSA_KEY_READ_DISABLE_REG;
|
uint32_t SE_ENTROPY_DEBUG_COUNTER;
|
||||||
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 _0x814;
|
||||||
uint32_t _0x818;
|
uint32_t _0x818;
|
||||||
uint32_t _0x81C;
|
uint32_t _0x81C;
|
||||||
uint8_t _0x820[0x17E0];
|
uint32_t _0x820[0x5F8];
|
||||||
} tegra_se_t;
|
} tegra_se_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -186,6 +186,8 @@ void set_version_specific_smcs(void) {
|
|||||||
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
||||||
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
||||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||||
|
case ATMOSPHERE_TARGET_FIRMWARE_900:
|
||||||
|
case ATMOSPHERE_TARGET_FIRMWARE_910:
|
||||||
/* No more LoadSecureExpModKey. */
|
/* No more LoadSecureExpModKey. */
|
||||||
g_smc_user_table[0xE].handler = NULL;
|
g_smc_user_table[0xE].handler = NULL;
|
||||||
g_smc_user_table[0xC].id = 0xC300D60C;
|
g_smc_user_table[0xC].id = 0xC300D60C;
|
||||||
@@ -316,7 +318,7 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DEBUG_PANIC_ON_FAILURE
|
#if DEBUG_PANIC_ON_FAILURE
|
||||||
if (args->X[0] && (!is_aes_kek || args->X[3] <= ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG))
|
if (args->X[0] && (!is_aes_kek || args->X[3] <= ATMOSPHERE_TARGET_FIRMWARE_CURRENT))
|
||||||
{
|
{
|
||||||
MAKE_REG32(get_iram_address_for_debug() + 0x4FF0) = handler_id;
|
MAKE_REG32(get_iram_address_for_debug() + 0x4FF0) = handler_id;
|
||||||
MAKE_REG32(get_iram_address_for_debug() + 0x4FF4) = smc_id;
|
MAKE_REG32(get_iram_address_for_debug() + 0x4FF4) = smc_id;
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ static bool is_user_keyslot_valid(unsigned int keyslot) {
|
|||||||
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
case ATMOSPHERE_TARGET_FIRMWARE_700:
|
||||||
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
case ATMOSPHERE_TARGET_FIRMWARE_800:
|
||||||
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
case ATMOSPHERE_TARGET_FIRMWARE_810:
|
||||||
|
case ATMOSPHERE_TARGET_FIRMWARE_900:
|
||||||
|
case ATMOSPHERE_TARGET_FIRMWARE_910:
|
||||||
default:
|
default:
|
||||||
return keyslot <= 5;
|
return keyslot <= 5;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,13 +26,25 @@ static inline uintptr_t get_timers_base(void) {
|
|||||||
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_TMRs_WDTs);
|
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_TMRs_WDTs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uintptr_t get_rtc_base(void) {
|
||||||
|
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC);
|
||||||
|
}
|
||||||
|
|
||||||
#define TIMERS_BASE (get_timers_base())
|
#define TIMERS_BASE (get_timers_base())
|
||||||
#define MAKE_TIMERS_REG(n) MAKE_REG32(TIMERS_BASE + n)
|
#define MAKE_TIMERS_REG(n) MAKE_REG32(TIMERS_BASE + n)
|
||||||
|
|
||||||
#define TIMERUS_CNTR_1US_0 MAKE_TIMERS_REG(0x10)
|
#define TIMERUS_CNTR_1US_0 MAKE_TIMERS_REG(0x10)
|
||||||
|
#define TIMERUS_USEC_CFG_0 MAKE_TIMERS_REG(0x14)
|
||||||
#define SHARED_INTR_STATUS_0 MAKE_TIMERS_REG(0x1A0)
|
#define SHARED_INTR_STATUS_0 MAKE_TIMERS_REG(0x1A0)
|
||||||
#define SHARED_TIMER_SECURE_CFG_0 MAKE_TIMERS_REG(0x1A4)
|
#define SHARED_TIMER_SECURE_CFG_0 MAKE_TIMERS_REG(0x1A4)
|
||||||
|
|
||||||
|
#define RTC_BASE (get_rtc_base())
|
||||||
|
#define MAKE_RTC_REG(n) MAKE_REG32(RTC_BASE + n)
|
||||||
|
|
||||||
|
#define RTC_SECONDS MAKE_RTC_REG(0x08)
|
||||||
|
#define RTC_SHADOW_SECONDS MAKE_RTC_REG(0x0C)
|
||||||
|
#define RTC_MILLI_SECONDS MAKE_RTC_REG(0x10)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t CONFIG;
|
uint32_t CONFIG;
|
||||||
uint32_t STATUS;
|
uint32_t STATUS;
|
||||||
@@ -46,10 +58,54 @@ typedef struct {
|
|||||||
|
|
||||||
void wait(uint32_t microseconds);
|
void wait(uint32_t microseconds);
|
||||||
|
|
||||||
static inline uint32_t get_time(void) {
|
static inline uint32_t get_time_s(void) {
|
||||||
|
return RTC_SECONDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t get_time_ms(void) {
|
||||||
|
return (RTC_MILLI_SECONDS | (RTC_SHADOW_SECONDS << 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t get_time_us(void) {
|
||||||
return TIMERUS_CNTR_1US_0;
|
return TIMERUS_CNTR_1US_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((noreturn)) void watchdog_reboot(void);
|
/**
|
||||||
|
* Returns the time in microseconds.
|
||||||
|
*/
|
||||||
|
static inline uint32_t get_time(void) {
|
||||||
|
return get_time_us();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of microseconds that have passed since a given get_time().
|
||||||
|
*/
|
||||||
|
static inline uint32_t get_time_since(uint32_t base) {
|
||||||
|
return get_time_us() - base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delays for a given number of microseconds.
|
||||||
|
*/
|
||||||
|
static inline void udelay(uint32_t usecs) {
|
||||||
|
uint32_t start = get_time_us();
|
||||||
|
while (get_time_us() - start < usecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delays until a number of usecs have passed since an absolute start time.
|
||||||
|
*/
|
||||||
|
static inline void udelay_absolute(uint32_t start, uint32_t usecs) {
|
||||||
|
while (get_time_us() - start < usecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delays for a given number of milliseconds.
|
||||||
|
*/
|
||||||
|
static inline void mdelay(uint32_t msecs) {
|
||||||
|
uint32_t start = get_time_ms();
|
||||||
|
while (get_time_ms() - start < msecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((noreturn)) void watchdog_reboot(void);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@@ -29,7 +29,7 @@ __attribute__ ((noreturn)) void panic(uint32_t code) {
|
|||||||
if (APBDEV_PMC_SCRATCH200_0 == 0) {
|
if (APBDEV_PMC_SCRATCH200_0 == 0) {
|
||||||
APBDEV_PMC_SCRATCH200_0 = code;
|
APBDEV_PMC_SCRATCH200_0 = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* // Uncomment for Debugging.
|
/* // Uncomment for Debugging.
|
||||||
uint64_t temp_reg;
|
uint64_t temp_reg;
|
||||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM)) = APBDEV_PMC_SCRATCH200_0;
|
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM)) = APBDEV_PMC_SCRATCH200_0;
|
||||||
@@ -38,8 +38,8 @@ __attribute__ ((noreturn)) void panic(uint32_t code) {
|
|||||||
SAVE_SYSREG64(FAR_EL3, 0x20);
|
SAVE_SYSREG64(FAR_EL3, 0x20);
|
||||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x450ull) = 0x2;
|
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x450ull) = 0x2;
|
||||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10; */
|
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10; */
|
||||||
|
|
||||||
|
|
||||||
/* TODO: Custom Panic Driver, which displays to screen without rebooting. */
|
/* TODO: Custom Panic Driver, which displays to screen without rebooting. */
|
||||||
/* For now, just use NX BOOTLOADER's panic. */
|
/* For now, just use NX BOOTLOADER's panic. */
|
||||||
fuse_disable_programming();
|
fuse_disable_programming();
|
||||||
@@ -50,7 +50,7 @@ __attribute__ ((noreturn)) void panic(uint32_t code) {
|
|||||||
|
|
||||||
__attribute__ ((noreturn)) void generic_panic(void) {
|
__attribute__ ((noreturn)) void generic_panic(void) {
|
||||||
/* //Uncomment for Debugging.
|
/* //Uncomment for Debugging.
|
||||||
uint64_t temp_reg;
|
uint64_t temp_reg;
|
||||||
do { __asm__ __volatile__ ("mov %0, LR" : "=r"(temp_reg) :: "memory"); } while (false);
|
do { __asm__ __volatile__ ("mov %0, LR" : "=r"(temp_reg) :: "memory"); } while (false);
|
||||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM) + 0x28) = (uint32_t)((temp_reg >> 0) & 0xFFFFFFFFULL);
|
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM) + 0x28) = (uint32_t)((temp_reg >> 0) & 0xFFFFFFFFULL);
|
||||||
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM) + 0x28 + 4) = (uint32_t)((temp_reg >> 32) & 0xFFFFFFFFULL);
|
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM) + 0x28 + 4) = (uint32_t)((temp_reg >> 32) & 0xFFFFFFFFULL);
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ TARGET := $(notdir $(CURDIR))
|
|||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := src src/lib src/display
|
SOURCES := src src/lib src/display
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include
|
INCLUDES := include ../../libraries/libvapours/include
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
|
|||||||
@@ -13,171 +13,178 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
#include "pmc.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
|
|
||||||
/* Prototypes for internal commands. */
|
/* Prototypes for internal commands. */
|
||||||
void fuse_make_regs_visible(void);
|
|
||||||
|
|
||||||
void fuse_enable_power(void);
|
void fuse_enable_power(void);
|
||||||
void fuse_disable_power(void);
|
void fuse_disable_power(void);
|
||||||
void fuse_wait_idle(void);
|
void fuse_wait_idle(void);
|
||||||
|
|
||||||
/* Initialize the fuse driver */
|
/* Initialize the fuse driver */
|
||||||
void fuse_init(void) {
|
void fuse_init(void) {
|
||||||
fuse_make_regs_visible();
|
/* Make all fuse registers visible, disable the private key and disable programming. */
|
||||||
fuse_secondary_private_key_disable();
|
|
||||||
fuse_disable_programming();
|
|
||||||
|
|
||||||
/* TODO: Overrides (iROM patches) and various reads happen here */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make all fuse registers visible */
|
|
||||||
void fuse_make_regs_visible(void) {
|
|
||||||
clkrst_enable_fuse_regs(true);
|
clkrst_enable_fuse_regs(true);
|
||||||
|
fuse_disable_private_key();
|
||||||
|
fuse_disable_programming();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable power to the fuse hardware array */
|
/* Disable access to the private key and set the TZ sticky bit. */
|
||||||
|
void fuse_disable_private_key(void) {
|
||||||
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
fuse->FUSE_PRIVATEKEYDISABLE = 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disables all fuse programming. */
|
||||||
|
void fuse_disable_programming(void) {
|
||||||
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
fuse->FUSE_DISABLEREGPROGRAM = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable power to the fuse hardware array. */
|
||||||
void fuse_enable_power(void) {
|
void fuse_enable_power(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||||
fuse->FUSE_PWR_GOOD_SW = 1;
|
pmc->fuse_control &= ~(0x200); /* Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
|
||||||
udelay(1);
|
mdelay(1);
|
||||||
|
pmc->fuse_control |= 0x100; /* Set PMC_FUSE_CTRL_PS18_LATCH_SET. */
|
||||||
|
mdelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable power to the fuse hardware array */
|
/* Disable power to the fuse hardware array. */
|
||||||
void fuse_disable_power(void) {
|
void fuse_disable_power(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||||
fuse->FUSE_PWR_GOOD_SW = 0;
|
pmc->fuse_control &= ~(0x100); /* Clear PMC_FUSE_CTRL_PS18_LATCH_SET. */
|
||||||
udelay(1);
|
mdelay(1);
|
||||||
|
pmc->fuse_control |= 0x200; /* Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
|
||||||
|
mdelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for the fuse driver to go idle */
|
/* Wait for the fuse driver to go idle. */
|
||||||
void fuse_wait_idle(void) {
|
void fuse_wait_idle(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
uint32_t ctrl_val = 0;
|
uint32_t ctrl_val = 0;
|
||||||
|
|
||||||
/* Wait for STATE_IDLE */
|
/* Wait for STATE_IDLE */
|
||||||
while ((ctrl_val & (0xF0000)) != 0x40000)
|
while ((ctrl_val & (0xF0000)) != 0x40000)
|
||||||
{
|
ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
udelay(1);
|
|
||||||
ctrl_val = fuse->FUSE_CTRL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a fuse from the hardware array */
|
/* Read a fuse from the hardware array. */
|
||||||
uint32_t fuse_hw_read(uint32_t addr) {
|
uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
/* Program the target address */
|
/* Program the target address. */
|
||||||
fuse->FUSE_REG_ADDR = addr;
|
fuse->FUSE_FUSEADDR = addr;
|
||||||
|
|
||||||
/* Enable read operation in control register */
|
/* Enable read operation in control register. */
|
||||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x1; /* Set FUSE_READ command */
|
ctrl_val |= 0x1; /* Set READ command. */
|
||||||
fuse->FUSE_CTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
return fuse->FUSE_REG_READ;
|
return fuse->FUSE_FUSERDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write a fuse in the hardware array */
|
/* Write a fuse in the hardware array. */
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
/* Program the target address and value */
|
/* Program the target address and value. */
|
||||||
fuse->FUSE_REG_ADDR = addr;
|
fuse->FUSE_FUSEADDR = addr;
|
||||||
fuse->FUSE_REG_WRITE = value;
|
fuse->FUSE_FUSEWDATA = value;
|
||||||
|
|
||||||
/* Enable write operation in control register */
|
/* Enable write operation in control register. */
|
||||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x2; /* Set FUSE_WRITE command */
|
ctrl_val |= 0x2; /* Set WRITE command. */
|
||||||
fuse->FUSE_CTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sense the fuse hardware array into the shadow cache */
|
/* Sense the fuse hardware array into the shadow cache. */
|
||||||
void fuse_hw_sense(void) {
|
void fuse_hw_sense(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
/* Enable sense operation in control register */
|
/* Enable sense operation in control register */
|
||||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x3; /* Set FUSE_SENSE command */
|
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
||||||
fuse->FUSE_CTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disables all fuse programming. */
|
/* Read the SKU info register from the shadow cache. */
|
||||||
void fuse_disable_programming(void) {
|
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
|
||||||
fuse->FUSE_DIS_PGM = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */
|
|
||||||
void fuse_secondary_private_key_disable(void) {
|
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
|
||||||
fuse->FUSE_PRIVATEKEYDISABLE = 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Read the SKU info register from the shadow cache */
|
|
||||||
uint32_t fuse_get_sku_info(void) {
|
uint32_t fuse_get_sku_info(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
return fuse_chip->FUSE_SKU_INFO;
|
return fuse_chip->FUSE_SKU_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the bootrom patch version from a register in the shadow cache */
|
/* Read the bootrom patch version from a register in the shadow cache. */
|
||||||
uint32_t fuse_get_bootrom_patch_version(void) {
|
uint32_t fuse_get_bootrom_patch_version(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
return fuse_chip->FUSE_SOC_SPEEDO_1;
|
return fuse_chip->FUSE_SOC_SPEEDO_1_CALIB;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a spare bit register from the shadow cache */
|
/* Read a spare bit register from the shadow cache */
|
||||||
uint32_t fuse_get_spare_bit(uint32_t idx) {
|
uint32_t fuse_get_spare_bit(uint32_t idx) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
if (idx < 32) {
|
||||||
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (idx >= 32) {
|
return fuse_chip->FUSE_SPARE_BIT[idx];
|
||||||
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fuse_chip->FUSE_SPARE_BIT[idx];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a reserved ODM register from the shadow cache */
|
/* Read a reserved ODM register from the shadow cache. */
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t idx) {
|
uint32_t fuse_get_reserved_odm(uint32_t idx) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
if (idx < 8) {
|
||||||
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (idx >= 8) {
|
return fuse_chip->FUSE_RESERVED_ODM[idx];
|
||||||
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM[idx];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Device ID using values in the shadow cache */
|
/* Get the DRAM ID using values in the shadow cache. */
|
||||||
|
uint32_t fuse_get_dram_id(void) {
|
||||||
|
return ((fuse_get_reserved_odm(4) >> 3) & 0x7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Derive the Device ID using values in the shadow cache. */
|
||||||
uint64_t fuse_get_device_id(void) {
|
uint64_t fuse_get_device_id(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
|
|
||||||
uint64_t device_id = 0;
|
uint64_t device_id = 0;
|
||||||
uint64_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
|
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint64_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
|
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint64_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
|
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code = fuse_chip->FUSE_LOT_CODE_0;
|
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
||||||
uint64_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
|
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
|
|
||||||
uint64_t derived_lot_code = 0;
|
uint64_t derived_lot_code = 0;
|
||||||
for (unsigned int i = 0; i < 5; i++) {
|
for (unsigned int i = 0; i < 5; i++) {
|
||||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||||
@@ -189,45 +196,41 @@ uint64_t fuse_get_device_id(void) {
|
|||||||
device_id |= wafer_id << 18;
|
device_id |= wafer_id << 18;
|
||||||
device_id |= derived_lot_code << 24;
|
device_id |= derived_lot_code << 24;
|
||||||
device_id |= fab_code << 50;
|
device_id |= fab_code << 50;
|
||||||
|
|
||||||
return device_id;
|
return device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the DRAM ID using values in the shadow cache */
|
/* Derive the Hardware Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_dram_id(void) {
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
return (fuse_chip->FUSE_RESERVED_ODM[4] >> 3) & 0x7;
|
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the Hardware Type using values in the shadow cache */
|
/* Firmware from versions 1.0.0 to 3.0.2. */
|
||||||
uint32_t fuse_get_hardware_type(void) {
|
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
|
|
||||||
/* This function is very different between 4.x and < 4.x */
|
|
||||||
uint32_t hardware_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((fuse_chip->FUSE_RESERVED_ODM[4] >> 2) & 1);
|
|
||||||
|
|
||||||
/* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) {
|
|
||||||
static const uint32_t types[] = {0,1,4,3};
|
|
||||||
|
|
||||||
hardware_type |= (fuse_chip->FUSE_RESERVED_ODM[4] >> 14) & 0x3C;
|
|
||||||
hardware_type--;
|
|
||||||
return hardware_type > 3 ? 4 : types[hardware_type];
|
|
||||||
} else {*/
|
|
||||||
if (hardware_type >= 1) {
|
if (hardware_type >= 1) {
|
||||||
return hardware_type > 2 ? 3 : hardware_type - 1;
|
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
||||||
} else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) {
|
} else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
// }
|
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
||||||
|
static const uint32_t types[] = {0,1,4,3};
|
||||||
|
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
||||||
|
hardware_type--;
|
||||||
|
return (hardware_type > 3) ? 4 : types[hardware_type];
|
||||||
|
} else { /* Firmware versions from 7.0.0 onwards. */
|
||||||
|
/* Always return 0 in retail. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Retail Type using values in the shadow cache */
|
/* Derive the Retail Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_retail_type(void) {
|
uint32_t fuse_get_retail_type(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
/* Retail Type = IS_RETAIL | UNIT_TYPE. */
|
||||||
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
/* Retail type = IS_RETAIL | UNIT_TYPE */
|
uint32_t retail_type = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3));
|
||||||
uint32_t retail_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 4) | (fuse_chip->FUSE_RESERVED_ODM[4] & 3);
|
|
||||||
if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */
|
if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */
|
||||||
return 1;
|
return 1;
|
||||||
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
|
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
|
||||||
@@ -241,17 +244,17 @@ void fuse_get_hardware_info(void *dst) {
|
|||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
uint32_t hw_info[0x4];
|
uint32_t hw_info[0x4];
|
||||||
|
|
||||||
uint32_t unk_hw_fuse = fuse_chip->_0x120 & 0x3F;
|
uint32_t ops_reserved = fuse_chip->FUSE_OPT_OPS_RESERVED & 0x3F;
|
||||||
uint32_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
|
uint32_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint32_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
|
uint32_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint32_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
|
uint32_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code_0 = fuse_chip->FUSE_LOT_CODE_0;
|
uint32_t lot_code_0 = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
||||||
uint32_t lot_code_1 = fuse_chip->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
|
uint32_t lot_code_1 = fuse_chip->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF;
|
||||||
uint32_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
|
uint32_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
uint32_t vendor_code = fuse_chip->FUSE_VENDOR_CODE & 0xF;
|
uint32_t vendor_code = fuse_chip->FUSE_OPT_VENDOR_CODE & 0xF;
|
||||||
|
|
||||||
/* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
|
/* Hardware Info = OPS_RESERVED || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
|
||||||
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse));
|
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (ops_reserved));
|
||||||
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
|
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
|
||||||
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
|
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
|
||||||
hw_info[3] = (uint32_t)(vendor_code);
|
hw_info[3] = (uint32_t)(vendor_code);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_FUSE_H
|
#ifndef FUSEE_FUSE_H
|
||||||
#define FUSEE_FUSE_H
|
#define FUSEE_FUSE_H
|
||||||
|
|
||||||
@@ -23,154 +23,167 @@
|
|||||||
#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
|
#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t FUSE_CTRL;
|
uint32_t FUSE_FUSECTRL;
|
||||||
uint32_t FUSE_REG_ADDR;
|
uint32_t FUSE_FUSEADDR;
|
||||||
uint32_t FUSE_REG_READ;
|
uint32_t FUSE_FUSERDATA;
|
||||||
uint32_t FUSE_REG_WRITE;
|
uint32_t FUSE_FUSEWDATA;
|
||||||
uint32_t FUSE_TIME_RD1;
|
uint32_t FUSE_FUSETIME_RD1;
|
||||||
uint32_t FUSE_TIME_RD2;
|
uint32_t FUSE_FUSETIME_RD2;
|
||||||
uint32_t FUSE_TIME_PGM1;
|
uint32_t FUSE_FUSETIME_PGM1;
|
||||||
uint32_t FUSE_TIME_PGM2;
|
uint32_t FUSE_FUSETIME_PGM2;
|
||||||
uint32_t FUSE_PRIV2INTFC;
|
uint32_t FUSE_PRIV2INTFC_START;
|
||||||
uint32_t FUSE_FUSEBYPASS;
|
uint32_t FUSE_FUSEBYPASS;
|
||||||
uint32_t FUSE_PRIVATEKEYDISABLE;
|
uint32_t FUSE_PRIVATEKEYDISABLE;
|
||||||
uint32_t FUSE_DIS_PGM;
|
uint32_t FUSE_DISABLEREGPROGRAM;
|
||||||
uint32_t FUSE_WRITE_ACCESS;
|
uint32_t FUSE_WRITE_ACCESS_SW;
|
||||||
uint32_t FUSE_PWR_GOOD_SW;
|
uint32_t FUSE_PWR_GOOD_SW;
|
||||||
uint32_t _0x38[0x32];
|
uint32_t _0x38;
|
||||||
|
uint32_t FUSE_PRIV2RESHIFT;
|
||||||
|
uint32_t _0x40[0x3];
|
||||||
|
uint32_t FUSE_FUSETIME_RD3;
|
||||||
|
uint32_t _0x50[0xC];
|
||||||
|
uint32_t FUSE_PRIVATE_KEY0_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY1_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY2_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY3_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY4_NONZERO;
|
||||||
|
uint32_t _0x90[0x1C];
|
||||||
} tegra_fuse_t;
|
} tegra_fuse_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t FUSE_PRODUCTION_MODE;
|
uint32_t FUSE_PRODUCTION_MODE;
|
||||||
uint32_t _0x4;
|
uint32_t FUSE_JTAG_SECUREID_VALID;
|
||||||
uint32_t _0x8;
|
uint32_t FUSE_ODM_LOCK;
|
||||||
uint32_t _0xC;
|
uint32_t FUSE_OPT_OPENGL_EN;
|
||||||
uint32_t FUSE_SKU_INFO;
|
uint32_t FUSE_SKU_INFO;
|
||||||
uint32_t FUSE_CPU_SPEEDO_0;
|
uint32_t FUSE_CPU_SPEEDO_0_CALIB;
|
||||||
uint32_t FUSE_CPU_IDDQ;
|
uint32_t FUSE_CPU_IDDQ_CALIB;
|
||||||
uint32_t _0x1C;
|
uint32_t FUSE_DAC_CRT_CALIB;
|
||||||
uint32_t _0x20;
|
uint32_t FUSE_DAC_HDTV_CALIB;
|
||||||
uint32_t _0x24;
|
uint32_t FUSE_DAC_SDTV_CALIB;
|
||||||
uint32_t FUSE_FT_REV;
|
uint32_t FUSE_OPT_FT_REV;
|
||||||
uint32_t FUSE_CPU_SPEEDO_1;
|
uint32_t FUSE_CPU_SPEEDO_1_CALIB;
|
||||||
uint32_t FUSE_CPU_SPEEDO_2;
|
uint32_t FUSE_CPU_SPEEDO_2_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_0;
|
uint32_t FUSE_SOC_SPEEDO_0_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_1;
|
uint32_t FUSE_SOC_SPEEDO_1_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_2;
|
uint32_t FUSE_SOC_SPEEDO_2_CALIB;
|
||||||
uint32_t FUSE_SOC_IDDQ;
|
uint32_t FUSE_SOC_IDDQ_CALIB;
|
||||||
uint32_t _0x44;
|
uint32_t FUSE_RESERVED_PRODUCTION_WP;
|
||||||
uint32_t FUSE_FA;
|
uint32_t FUSE_FA;
|
||||||
uint32_t _0x4C;
|
uint32_t FUSE_RESERVED_PRODUCTION;
|
||||||
uint32_t _0x50;
|
uint32_t FUSE_HDMI_LANE0_CALIB;
|
||||||
uint32_t _0x54;
|
uint32_t FUSE_HDMI_LANE1_CALIB;
|
||||||
uint32_t _0x58;
|
uint32_t FUSE_HDMI_LANE2_CALIB;
|
||||||
uint32_t _0x5C;
|
uint32_t FUSE_HDMI_LANE3_CALIB;
|
||||||
uint32_t _0x60;
|
uint32_t FUSE_ENCRYPTION_RATE;
|
||||||
uint32_t FUSE_PUBLIC_KEY[0x8];
|
uint32_t FUSE_PUBLIC_KEY[0x8];
|
||||||
uint32_t FUSE_TSENSOR_1;
|
uint32_t FUSE_TSENSOR1_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_2;
|
uint32_t FUSE_TSENSOR2_CALIB;
|
||||||
uint32_t _0x8C;
|
uint32_t FUSE_VSENSOR_CALIB;
|
||||||
uint32_t FUSE_CP_REV;
|
uint32_t FUSE_OPT_CP_REV;
|
||||||
uint32_t _0x94;
|
uint32_t FUSE_OPT_PFG;
|
||||||
uint32_t FUSE_TSENSOR_0;
|
uint32_t FUSE_TSENSOR0_CALIB;
|
||||||
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG;
|
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE;
|
||||||
uint32_t FUSE_SECURITY_MODE;
|
uint32_t FUSE_SECURITY_MODE;
|
||||||
uint32_t FUSE_PRIVATE_KEY[0x4];
|
uint32_t FUSE_PRIVATE_KEY[0x5];
|
||||||
uint32_t FUSE_DEVICE_KEY;
|
uint32_t FUSE_ARM_JTAG_DIS;
|
||||||
uint32_t _0xB8;
|
uint32_t FUSE_BOOT_DEVICE_INFO;
|
||||||
uint32_t _0xBC;
|
|
||||||
uint32_t FUSE_RESERVED_SW;
|
uint32_t FUSE_RESERVED_SW;
|
||||||
uint32_t FUSE_VP8_ENABLE;
|
uint32_t FUSE_OPT_VP9_DISABLE;
|
||||||
uint32_t FUSE_RESERVED_ODM[0x8];
|
uint32_t FUSE_RESERVED_ODM[0x8];
|
||||||
uint32_t _0xE8;
|
uint32_t FUSE_OBS_DIS;
|
||||||
uint32_t _0xEC;
|
uint32_t FUSE_NOR_INFO;
|
||||||
uint32_t FUSE_SKU_USB_CALIB;
|
uint32_t FUSE_USB_CALIB;
|
||||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
||||||
uint32_t _0xF8;
|
uint32_t FUSE_KFUSE_PRIVKEY_CTRL;
|
||||||
uint32_t _0xFC;
|
uint32_t FUSE_PACKAGE_INFO;
|
||||||
uint32_t FUSE_VENDOR_CODE;
|
uint32_t FUSE_OPT_VENDOR_CODE;
|
||||||
uint32_t FUSE_FAB_CODE;
|
uint32_t FUSE_OPT_FAB_CODE;
|
||||||
uint32_t FUSE_LOT_CODE_0;
|
uint32_t FUSE_OPT_LOT_CODE_0;
|
||||||
uint32_t FUSE_LOT_CODE_1;
|
uint32_t FUSE_OPT_LOT_CODE_1;
|
||||||
uint32_t FUSE_WAFER_ID;
|
uint32_t FUSE_OPT_WAFER_ID;
|
||||||
uint32_t FUSE_X_COORDINATE;
|
uint32_t FUSE_OPT_X_COORDINATE;
|
||||||
uint32_t FUSE_Y_COORDINATE;
|
uint32_t FUSE_OPT_Y_COORDINATE;
|
||||||
uint32_t _0x11C;
|
uint32_t FUSE_OPT_SEC_DEBUG_EN;
|
||||||
uint32_t _0x120;
|
uint32_t FUSE_OPT_OPS_RESERVED;
|
||||||
uint32_t FUSE_SATA_CALIB;
|
uint32_t FUSE_SATA_CALIB;
|
||||||
uint32_t FUSE_GPU_IDDQ;
|
uint32_t FUSE_GPU_IDDQ_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_3;
|
uint32_t FUSE_TSENSOR3_CALIB;
|
||||||
uint32_t _0x130;
|
uint32_t FUSE_SKU_BOND_OUT_L;
|
||||||
uint32_t _0x134;
|
uint32_t FUSE_SKU_BOND_OUT_H;
|
||||||
uint32_t _0x138;
|
uint32_t FUSE_SKU_BOND_OUT_U;
|
||||||
uint32_t _0x13C;
|
uint32_t FUSE_SKU_BOND_OUT_V;
|
||||||
uint32_t _0x140;
|
uint32_t FUSE_SKU_BOND_OUT_W;
|
||||||
uint32_t _0x144;
|
uint32_t FUSE_OPT_SAMPLE_TYPE;
|
||||||
uint32_t FUSE_OPT_SUBREVISION;
|
uint32_t FUSE_OPT_SUBREVISION;
|
||||||
uint32_t _0x14C;
|
uint32_t FUSE_OPT_SW_RESERVED_0;
|
||||||
uint32_t _0x150;
|
uint32_t FUSE_OPT_SW_RESERVED_1;
|
||||||
uint32_t FUSE_TSENSOR_4;
|
uint32_t FUSE_TSENSOR4_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_5;
|
uint32_t FUSE_TSENSOR5_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_6;
|
uint32_t FUSE_TSENSOR6_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_7;
|
uint32_t FUSE_TSENSOR7_CALIB;
|
||||||
uint32_t FUSE_OPT_PRIV_SEC_DIS;
|
uint32_t FUSE_OPT_PRIV_SEC_EN;
|
||||||
uint32_t FUSE_PKC_DISABLE;
|
uint32_t FUSE_PKC_DISABLE;
|
||||||
uint32_t _0x16C;
|
uint32_t _0x16C;
|
||||||
uint32_t _0x170;
|
uint32_t _0x170;
|
||||||
uint32_t _0x174;
|
uint32_t _0x174;
|
||||||
uint32_t _0x178;
|
uint32_t _0x178;
|
||||||
uint32_t _0x17C;
|
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
||||||
uint32_t FUSE_TSENSOR_COMMON;
|
uint32_t FUSE_TSENSOR_COMMON;
|
||||||
uint32_t _0x184;
|
uint32_t FUSE_OPT_CP_BIN;
|
||||||
uint32_t _0x188;
|
uint32_t FUSE_OPT_GPU_DISABLE;
|
||||||
uint32_t _0x18C;
|
uint32_t FUSE_OPT_FT_BIN;
|
||||||
uint32_t _0x190;
|
uint32_t FUSE_OPT_DONE_MAP;
|
||||||
uint32_t _0x194;
|
uint32_t _0x194;
|
||||||
uint32_t _0x198;
|
uint32_t FUSE_APB2JTAG_DISABLE;
|
||||||
uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
|
uint32_t FUSE_ODM_INFO;
|
||||||
uint32_t _0x1A0;
|
uint32_t _0x1A0;
|
||||||
uint32_t _0x1A4;
|
uint32_t _0x1A4;
|
||||||
uint32_t _0x1A8;
|
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
|
||||||
uint32_t _0x1AC;
|
uint32_t _0x1AC;
|
||||||
uint32_t _0x1B0;
|
uint32_t _0x1B0;
|
||||||
uint32_t _0x1B4;
|
uint32_t _0x1B4;
|
||||||
uint32_t _0x1B8;
|
uint32_t _0x1B8;
|
||||||
uint32_t _0x1BC;
|
uint32_t _0x1BC;
|
||||||
uint32_t _0x1D0;
|
uint32_t FUSE_WOA_SKU_FLAG;
|
||||||
uint32_t FUSE_TSENSOR_8;
|
uint32_t FUSE_ECO_RESERVE_1;
|
||||||
|
uint32_t FUSE_GCPLEX_CONFIG_FUSE;
|
||||||
|
uint32_t FUSE_PRODUCTION_MONTH;
|
||||||
|
uint32_t FUSE_RAM_REPAIR_INDICATOR;
|
||||||
|
uint32_t FUSE_TSENSOR9_CALIB;
|
||||||
uint32_t _0x1D8;
|
uint32_t _0x1D8;
|
||||||
uint32_t _0x1DC;
|
uint32_t FUSE_VMIN_CALIBRATION;
|
||||||
uint32_t _0x1E0;
|
uint32_t FUSE_AGING_SENSOR_CALIBRATION;
|
||||||
uint32_t _0x1E4;
|
uint32_t FUSE_DEBUG_AUTHENTICATION;
|
||||||
uint32_t _0x1E8;
|
uint32_t FUSE_SECURE_PROVISION_INDEX;
|
||||||
uint32_t _0x1EC;
|
uint32_t FUSE_SECURE_PROVISION_INFO;
|
||||||
uint32_t _0x1F0;
|
uint32_t FUSE_OPT_GPU_DISABLE_CP1;
|
||||||
uint32_t _0x1F4;
|
uint32_t FUSE_SPARE_ENDIS;
|
||||||
uint32_t _0x1F8;
|
uint32_t FUSE_ECO_RESERVE_0;
|
||||||
uint32_t _0x1FC;
|
uint32_t _0x1FC;
|
||||||
uint32_t _0x200;
|
uint32_t _0x200;
|
||||||
uint32_t FUSE_RESERVED_CALIB;
|
uint32_t FUSE_RESERVED_CALIB0;
|
||||||
uint32_t _0x208;
|
uint32_t FUSE_RESERVED_CALIB1;
|
||||||
uint32_t _0x20C;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE;
|
||||||
uint32_t _0x210;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1;
|
||||||
uint32_t _0x214;
|
uint32_t FUSE_OPT_CPU_DISABLE;
|
||||||
uint32_t _0x218;
|
uint32_t FUSE_OPT_CPU_DISABLE_CP1;
|
||||||
uint32_t FUSE_TSENSOR_9;
|
uint32_t FUSE_TSENSOR10_CALIB;
|
||||||
uint32_t _0x220;
|
uint32_t FUSE_TSENSOR10_CALIB_AUX;
|
||||||
uint32_t _0x224;
|
uint32_t FUSE_OPT_RAM_SVOP_DP;
|
||||||
uint32_t _0x228;
|
uint32_t FUSE_OPT_RAM_SVOP_PDP;
|
||||||
uint32_t _0x22C;
|
uint32_t FUSE_OPT_RAM_SVOP_REG;
|
||||||
uint32_t _0x230;
|
uint32_t FUSE_OPT_RAM_SVOP_SP;
|
||||||
uint32_t _0x234;
|
uint32_t FUSE_OPT_RAM_SVOP_SMPDP;
|
||||||
uint32_t _0x238;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2;
|
||||||
uint32_t _0x23C;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE;
|
||||||
uint32_t _0x240;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1;
|
||||||
uint32_t _0x244;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2;
|
||||||
uint32_t _0x248;
|
uint32_t FUSE_OPT_CPU_DISABLE_CP2;
|
||||||
uint32_t _0x24C;
|
uint32_t FUSE_OPT_GPU_DISABLE_CP2;
|
||||||
uint32_t FUSE_USB_CALIB_EXT;
|
uint32_t FUSE_USB_CALIB_EXT;
|
||||||
uint32_t _0x254;
|
uint32_t FUSE_RESERVED_FIELD;
|
||||||
uint32_t _0x258;
|
uint32_t FUSE_OPT_ECC_EN;
|
||||||
uint32_t _0x25C;
|
uint32_t _0x25C;
|
||||||
uint32_t _0x260;
|
uint32_t _0x260;
|
||||||
uint32_t _0x264;
|
uint32_t _0x264;
|
||||||
@@ -179,35 +192,36 @@ typedef struct {
|
|||||||
uint32_t _0x270;
|
uint32_t _0x270;
|
||||||
uint32_t _0x274;
|
uint32_t _0x274;
|
||||||
uint32_t _0x278;
|
uint32_t _0x278;
|
||||||
uint32_t _0x27C;
|
uint32_t FUSE_SPARE_REALIGNMENT_REG;
|
||||||
uint32_t FUSE_SPARE_BIT[0x20];
|
uint32_t FUSE_SPARE_BIT[0x20];
|
||||||
} tegra_fuse_chip_t;
|
} tegra_fuse_chip_t;
|
||||||
|
|
||||||
static inline volatile tegra_fuse_t *fuse_get_regs(void) {
|
static inline volatile tegra_fuse_t *fuse_get_regs(void)
|
||||||
|
{
|
||||||
return (volatile tegra_fuse_t *)FUSE_BASE;
|
return (volatile tegra_fuse_t *)FUSE_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) {
|
static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void)
|
||||||
|
{
|
||||||
return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE;
|
return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuse_init(void);
|
void fuse_init(void);
|
||||||
|
|
||||||
uint32_t fuse_hw_read(uint32_t addr);
|
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr);
|
|
||||||
void fuse_hw_sense(void);
|
|
||||||
void fuse_disable_programming(void);
|
void fuse_disable_programming(void);
|
||||||
void fuse_secondary_private_key_disable(void);
|
void fuse_disable_private_key(void);
|
||||||
|
|
||||||
uint32_t fuse_get_sku_info(void);
|
uint32_t fuse_get_sku_info(void);
|
||||||
uint32_t fuse_get_spare_bit(uint32_t idx);
|
uint32_t fuse_get_spare_bit(uint32_t idx);
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t idx);
|
uint32_t fuse_get_reserved_odm(uint32_t idx);
|
||||||
|
|
||||||
uint32_t fuse_get_bootrom_patch_version(void);
|
uint32_t fuse_get_bootrom_patch_version(void);
|
||||||
uint64_t fuse_get_device_id(void);
|
uint64_t fuse_get_device_id(void);
|
||||||
uint32_t fuse_get_dram_id(void);
|
uint32_t fuse_get_dram_id(void);
|
||||||
uint32_t fuse_get_hardware_type(void);
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware);
|
||||||
uint32_t fuse_get_retail_type(void);
|
uint32_t fuse_get_retail_type(void);
|
||||||
void fuse_get_hardware_info(void *dst);
|
void fuse_get_hardware_info(void *dst);
|
||||||
|
|
||||||
|
uint32_t fuse_hw_read(uint32_t addr);
|
||||||
|
void fuse_hw_write(uint32_t value, uint32_t addr);
|
||||||
|
void fuse_hw_sense(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -37,6 +37,13 @@
|
|||||||
#define MC_SMMU_TLB_FLUSH 0x30
|
#define MC_SMMU_TLB_FLUSH 0x30
|
||||||
#define MC_SMMU_PTC_FLUSH 0x34
|
#define MC_SMMU_PTC_FLUSH 0x34
|
||||||
#define MC_SMMU_ASID_SECURITY 0x38
|
#define MC_SMMU_ASID_SECURITY 0x38
|
||||||
|
#define MC_SMMU_ASID_SECURITY_1 0x3c
|
||||||
|
#define MC_SMMU_ASID_SECURITY_2 0x9e0
|
||||||
|
#define MC_SMMU_ASID_SECURITY_3 0x9e4
|
||||||
|
#define MC_SMMU_ASID_SECURITY_4 0x9e8
|
||||||
|
#define MC_SMMU_ASID_SECURITY_5 0x9ec
|
||||||
|
#define MC_SMMU_ASID_SECURITY_6 0x9f0
|
||||||
|
#define MC_SMMU_ASID_SECURITY_7 0x9f4
|
||||||
#define MC_SMMU_AFI_ASID 0x238
|
#define MC_SMMU_AFI_ASID 0x238
|
||||||
#define MC_SMMU_AVPC_ASID 0x23c
|
#define MC_SMMU_AVPC_ASID 0x23c
|
||||||
#define MC_SMMU_TSEC_ASID 0x294
|
#define MC_SMMU_TSEC_ASID 0x294
|
||||||
|
|||||||
626
fusee/fusee-mtc/src/pmc.h
Normal file
626
fusee/fusee-mtc/src/pmc.h
Normal file
@@ -0,0 +1,626 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FUSEE_PMC_H
|
||||||
|
#define FUSEE_PMC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define PMC_BASE 0x7000E400
|
||||||
|
#define MAKE_PMC_REG(n) MAKE_REG32(PMC_BASE + n)
|
||||||
|
|
||||||
|
#define PMC_CONTROL_SDMMC1 (1 << 12)
|
||||||
|
#define PMC_CONTROL_SDMMC3 (1 << 13)
|
||||||
|
#define PMC_CONTROL_SDMMC4 (1 << 14)
|
||||||
|
|
||||||
|
#define APBDEV_PMC_CONTROL MAKE_PMC_REG(0x00)
|
||||||
|
#define APBDEV_PM_0 MAKE_PMC_REG(0x14)
|
||||||
|
#define APBDEV_PMC_DPD_ENABLE_0 MAKE_PMC_REG(0x24)
|
||||||
|
#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x30)
|
||||||
|
#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x38)
|
||||||
|
#define APBDEV_PMC_NO_IOPOWER_0 MAKE_PMC_REG(0x44)
|
||||||
|
#define APBDEV_PMC_SCRATCH0_0 MAKE_PMC_REG(0x50)
|
||||||
|
#define APBDEV_PMC_SCRATCH1_0 MAKE_PMC_REG(0x54)
|
||||||
|
#define APBDEV_PMC_SCRATCH20_0 MAKE_PMC_REG(0xA0)
|
||||||
|
#define APBDEV_PMC_PWR_DET_VAL_0 MAKE_PMC_REG(0xE4)
|
||||||
|
#define APBDEV_PMC_DDR_PWR_0 MAKE_PMC_REG(0xE8)
|
||||||
|
#define APBDEV_PMC_CRYPTO_OP_0 MAKE_PMC_REG(0xF4)
|
||||||
|
#define APBDEV_PMC_WAKE2_STATUS_0 MAKE_PMC_REG(0x168)
|
||||||
|
#define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4)
|
||||||
|
#define APBDEV_PMC_RST_STATUS_0 MAKE_PMC_REG(0x1B4)
|
||||||
|
#define APBDEV_PMC_IO_DPD_REQ_0 MAKE_PMC_REG(0x1B8)
|
||||||
|
#define APBDEV_PMC_IO_DPD2_REQ_0 MAKE_PMC_REG(0x1C0)
|
||||||
|
#define APBDEV_PMC_VDDP_SEL_0 MAKE_PMC_REG(0x1CC)
|
||||||
|
#define APBDEV_PMC_SCRATCH49_0 MAKE_PMC_REG(0x244)
|
||||||
|
#define APBDEV_PMC_TSC_MULT_0 MAKE_PMC_REG(0x2B4)
|
||||||
|
#define APBDEV_PMC_REG_SHORT_0 MAKE_PMC_REG(0x2CC)
|
||||||
|
#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_SCRATCH49_0 MAKE_PMC_REG(0x3A4)
|
||||||
|
#define APBDEV_PMC_CNTRL2_0 MAKE_PMC_REG(0x440)
|
||||||
|
#define APBDEV_PMC_IO_DPD4_REQ_0 MAKE_PMC_REG(0x464)
|
||||||
|
#define APBDEV_PMC_UTMIP_PAD_CFG1_0 MAKE_PMC_REG(0x4C4)
|
||||||
|
#define APBDEV_PMC_UTMIP_PAD_CFG3_0 MAKE_PMC_REG(0x4CC)
|
||||||
|
#define APBDEV_PMC_DDR_CNTRL_0 MAKE_PMC_REG(0x4E4)
|
||||||
|
#define APBDEV_PMC_SCRATCH43_0 MAKE_PMC_REG(0x22C)
|
||||||
|
#define APBDEV_PMC_SCRATCH188_0 MAKE_PMC_REG(0x810)
|
||||||
|
#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818)
|
||||||
|
#define APBDEV_PMC_SCRATCH200_0 MAKE_PMC_REG(0x840)
|
||||||
|
|
||||||
|
#define APBDEV_PMC_SCRATCH45_0 MAKE_PMC_REG(0x234)
|
||||||
|
#define APBDEV_PMC_SCRATCH46_0 MAKE_PMC_REG(0x238)
|
||||||
|
#define APBDEV_PMC_SCRATCH33_0 MAKE_PMC_REG(0x120)
|
||||||
|
#define APBDEV_PMC_SCRATCH40_0 MAKE_PMC_REG(0x13C)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t cntrl;
|
||||||
|
uint32_t sec_disable;
|
||||||
|
uint32_t pmc_swrst;
|
||||||
|
uint32_t wake_mask;
|
||||||
|
uint32_t wake_lvl;
|
||||||
|
uint32_t wake_status;
|
||||||
|
uint32_t sw_wake_status;
|
||||||
|
uint32_t dpd_pads_oride;
|
||||||
|
uint32_t dpd_sample;
|
||||||
|
uint32_t dpd_enable;
|
||||||
|
uint32_t pwrgate_timer_off;
|
||||||
|
uint32_t clamp_status;
|
||||||
|
uint32_t pwrgate_toggle;
|
||||||
|
uint32_t remove_clamping;
|
||||||
|
uint32_t pwrgate_status;
|
||||||
|
uint32_t pwrgood_timer;
|
||||||
|
uint32_t blink_timer;
|
||||||
|
uint32_t no_iopower;
|
||||||
|
uint32_t pwr_det;
|
||||||
|
uint32_t pwr_det_latch;
|
||||||
|
uint32_t scratch0;
|
||||||
|
uint32_t scratch1;
|
||||||
|
uint32_t scratch2;
|
||||||
|
uint32_t scratch3;
|
||||||
|
uint32_t scratch4;
|
||||||
|
uint32_t scratch5;
|
||||||
|
uint32_t scratch6;
|
||||||
|
uint32_t scratch7;
|
||||||
|
uint32_t scratch8;
|
||||||
|
uint32_t scratch9;
|
||||||
|
uint32_t scratch10;
|
||||||
|
uint32_t scratch11;
|
||||||
|
uint32_t scratch12;
|
||||||
|
uint32_t scratch13;
|
||||||
|
uint32_t scratch14;
|
||||||
|
uint32_t scratch15;
|
||||||
|
uint32_t scratch16;
|
||||||
|
uint32_t scratch17;
|
||||||
|
uint32_t scratch18;
|
||||||
|
uint32_t scratch19;
|
||||||
|
uint32_t scratch20;
|
||||||
|
uint32_t scratch21;
|
||||||
|
uint32_t scratch22;
|
||||||
|
uint32_t scratch23;
|
||||||
|
uint32_t secure_scratch0;
|
||||||
|
uint32_t secure_scratch1;
|
||||||
|
uint32_t secure_scratch2;
|
||||||
|
uint32_t secure_scratch3;
|
||||||
|
uint32_t secure_scratch4;
|
||||||
|
uint32_t secure_scratch5;
|
||||||
|
uint32_t cpupwrgood_timer;
|
||||||
|
uint32_t cpupwroff_timer;
|
||||||
|
uint32_t pg_mask;
|
||||||
|
uint32_t pg_mask_1;
|
||||||
|
uint32_t auto_wake_lvl;
|
||||||
|
uint32_t auto_wake_lvl_mask;
|
||||||
|
uint32_t wake_delay;
|
||||||
|
uint32_t pwr_det_val;
|
||||||
|
uint32_t ddr_pwr;
|
||||||
|
uint32_t usb_debounce_del;
|
||||||
|
uint32_t usb_ao;
|
||||||
|
uint32_t crypto_op;
|
||||||
|
uint32_t pllp_wb0_override;
|
||||||
|
uint32_t scratch24;
|
||||||
|
uint32_t scratch25;
|
||||||
|
uint32_t scratch26;
|
||||||
|
uint32_t scratch27;
|
||||||
|
uint32_t scratch28;
|
||||||
|
uint32_t scratch29;
|
||||||
|
uint32_t scratch30;
|
||||||
|
uint32_t scratch31;
|
||||||
|
uint32_t scratch32;
|
||||||
|
uint32_t scratch33;
|
||||||
|
uint32_t scratch34;
|
||||||
|
uint32_t scratch35;
|
||||||
|
uint32_t scratch36;
|
||||||
|
uint32_t scratch37;
|
||||||
|
uint32_t scratch38;
|
||||||
|
uint32_t scratch39;
|
||||||
|
uint32_t scratch40;
|
||||||
|
uint32_t scratch41;
|
||||||
|
uint32_t scratch42;
|
||||||
|
uint32_t bo_mirror0;
|
||||||
|
uint32_t bo_mirror1;
|
||||||
|
uint32_t bo_mirror2;
|
||||||
|
uint32_t sys_33v_en;
|
||||||
|
uint32_t bo_mirror_access;
|
||||||
|
uint32_t gate;
|
||||||
|
uint32_t wake2_mask;
|
||||||
|
uint32_t wake2_lvl;
|
||||||
|
uint32_t wake2_stat;
|
||||||
|
uint32_t sw_wake2_stat;
|
||||||
|
uint32_t auto_wake2_lvl_mask;
|
||||||
|
uint32_t pg_mask2;
|
||||||
|
uint32_t pg_mask_ce1;
|
||||||
|
uint32_t pg_mask_ce2;
|
||||||
|
uint32_t pg_mask_ce3;
|
||||||
|
uint32_t pwrgate_timer_ce0;
|
||||||
|
uint32_t pwrgate_timer_ce1;
|
||||||
|
uint32_t pwrgate_timer_ce2;
|
||||||
|
uint32_t pwrgate_timer_ce3;
|
||||||
|
uint32_t pwrgate_timer_ce4;
|
||||||
|
uint32_t pwrgate_timer_ce5;
|
||||||
|
uint32_t pwrgate_timer_ce6;
|
||||||
|
uint32_t pcx_edpd_cntrl;
|
||||||
|
uint32_t osc_edpd_over;
|
||||||
|
uint32_t clk_out_cntrl;
|
||||||
|
uint32_t sata_pwrgate;
|
||||||
|
uint32_t sensor_ctrl;
|
||||||
|
uint32_t reset_status;
|
||||||
|
uint32_t io_dpd_req;
|
||||||
|
uint32_t io_dpd_stat;
|
||||||
|
uint32_t io_dpd2_req;
|
||||||
|
uint32_t io_dpd2_stat;
|
||||||
|
uint32_t sel_dpd_tim;
|
||||||
|
uint32_t vddp_sel;
|
||||||
|
uint32_t ddr_cfg;
|
||||||
|
uint32_t e_no_vttgen;
|
||||||
|
uint32_t _reserved0;
|
||||||
|
uint32_t pllm_wb0_ovrride_frq;
|
||||||
|
uint32_t test_pwrgate;
|
||||||
|
uint32_t pwrgate_timer_mult;
|
||||||
|
uint32_t dsi_sel_dpd;
|
||||||
|
uint32_t utmip_uhsic_triggers;
|
||||||
|
uint32_t utmip_uhsic_saved_st;
|
||||||
|
uint32_t utmip_pad_cfg;
|
||||||
|
uint32_t utmip_term_pad_cfg;
|
||||||
|
uint32_t utmip_uhsic_sleep_cfg;
|
||||||
|
uint32_t utmip_uhsic_sleepwalk_cfg;
|
||||||
|
uint32_t utmip_sleepwalk_p[3];
|
||||||
|
uint32_t uhsic_sleepwalk_p0;
|
||||||
|
uint32_t utmip_uhsic_status;
|
||||||
|
uint32_t utmip_uhsic_fake;
|
||||||
|
uint32_t bo_mirror3[2];
|
||||||
|
uint32_t secure_scratch6;
|
||||||
|
uint32_t secure_scratch7;
|
||||||
|
uint32_t scratch43;
|
||||||
|
uint32_t scratch44;
|
||||||
|
uint32_t scratch45;
|
||||||
|
uint32_t scratch46;
|
||||||
|
uint32_t scratch47;
|
||||||
|
uint32_t scratch48;
|
||||||
|
uint32_t scratch49;
|
||||||
|
uint32_t scratch50;
|
||||||
|
uint32_t scratch51;
|
||||||
|
uint32_t scratch52;
|
||||||
|
uint32_t scratch53;
|
||||||
|
uint32_t scratch54;
|
||||||
|
uint32_t scratch55;
|
||||||
|
uint32_t scratch0_eco;
|
||||||
|
uint32_t por_dpd_ctrl;
|
||||||
|
uint32_t scratch2_eco;
|
||||||
|
uint32_t utmip_uhsic_line_wakeup;
|
||||||
|
uint32_t utmip_bias_master_cntrl;
|
||||||
|
uint32_t utmip_master_config;
|
||||||
|
uint32_t td_pwrgate_inter_part_timer;
|
||||||
|
uint32_t utmip_uhsic2_triggers;
|
||||||
|
uint32_t utmip_uhsic2_saved_state;
|
||||||
|
uint32_t utmip_uhsic2_sleep_cfg;
|
||||||
|
uint32_t utmip_uhsic2_sleepwalk_cfg;
|
||||||
|
uint32_t uhsic2_sleepwalk_p1;
|
||||||
|
uint32_t utmip_uhsic2_status;
|
||||||
|
uint32_t utmip_uhsic2_fake;
|
||||||
|
uint32_t utmip_uhsic2_line_wakeup;
|
||||||
|
uint32_t utmip_master2_config;
|
||||||
|
uint32_t utmip_uhsic_rpd_cfg;
|
||||||
|
uint32_t pg_mask_ce0;
|
||||||
|
uint32_t pg_mask3[2];
|
||||||
|
uint32_t pllm_wb0_override2;
|
||||||
|
uint32_t tsc_mult;
|
||||||
|
uint32_t cpu_vsense_override;
|
||||||
|
uint32_t glb_amap_cfg;
|
||||||
|
uint32_t sticky_bits;
|
||||||
|
uint32_t sec_disable2;
|
||||||
|
uint32_t weak_bias;
|
||||||
|
uint32_t reg_short;
|
||||||
|
uint32_t pg_mask_andor;
|
||||||
|
uint32_t _reserved1[11];
|
||||||
|
uint32_t secure_scratch8;
|
||||||
|
uint32_t secure_scratch9;
|
||||||
|
uint32_t secure_scratch10;
|
||||||
|
uint32_t secure_scratch11;
|
||||||
|
uint32_t secure_scratch12;
|
||||||
|
uint32_t secure_scratch13;
|
||||||
|
uint32_t secure_scratch14;
|
||||||
|
uint32_t secure_scratch15;
|
||||||
|
uint32_t secure_scratch16;
|
||||||
|
uint32_t secure_scratch17;
|
||||||
|
uint32_t secure_scratch18;
|
||||||
|
uint32_t secure_scratch19;
|
||||||
|
uint32_t secure_scratch20;
|
||||||
|
uint32_t secure_scratch21;
|
||||||
|
uint32_t secure_scratch22;
|
||||||
|
uint32_t secure_scratch23;
|
||||||
|
uint32_t secure_scratch24;
|
||||||
|
uint32_t secure_scratch25;
|
||||||
|
uint32_t secure_scratch26;
|
||||||
|
uint32_t secure_scratch27;
|
||||||
|
uint32_t secure_scratch28;
|
||||||
|
uint32_t secure_scratch29;
|
||||||
|
uint32_t secure_scratch30;
|
||||||
|
uint32_t secure_scratch31;
|
||||||
|
uint32_t secure_scratch32;
|
||||||
|
uint32_t secure_scratch33;
|
||||||
|
uint32_t secure_scratch34;
|
||||||
|
uint32_t secure_scratch35;
|
||||||
|
uint32_t secure_scratch36;
|
||||||
|
uint32_t secure_scratch37;
|
||||||
|
uint32_t secure_scratch38;
|
||||||
|
uint32_t secure_scratch39;
|
||||||
|
uint32_t secure_scratch40;
|
||||||
|
uint32_t secure_scratch41;
|
||||||
|
uint32_t secure_scratch42;
|
||||||
|
uint32_t secure_scratch43;
|
||||||
|
uint32_t secure_scratch44;
|
||||||
|
uint32_t secure_scratch45;
|
||||||
|
uint32_t secure_scratch46;
|
||||||
|
uint32_t secure_scratch47;
|
||||||
|
uint32_t secure_scratch48;
|
||||||
|
uint32_t secure_scratch49;
|
||||||
|
uint32_t secure_scratch50;
|
||||||
|
uint32_t secure_scratch51;
|
||||||
|
uint32_t secure_scratch52;
|
||||||
|
uint32_t secure_scratch53;
|
||||||
|
uint32_t secure_scratch54;
|
||||||
|
uint32_t secure_scratch55;
|
||||||
|
uint32_t secure_scratch56;
|
||||||
|
uint32_t secure_scratch57;
|
||||||
|
uint32_t secure_scratch58;
|
||||||
|
uint32_t secure_scratch59;
|
||||||
|
uint32_t secure_scratch60;
|
||||||
|
uint32_t secure_scratch61;
|
||||||
|
uint32_t secure_scratch62;
|
||||||
|
uint32_t secure_scratch63;
|
||||||
|
uint32_t secure_scratch64;
|
||||||
|
uint32_t secure_scratch65;
|
||||||
|
uint32_t secure_scratch66;
|
||||||
|
uint32_t secure_scratch67;
|
||||||
|
uint32_t secure_scratch68;
|
||||||
|
uint32_t secure_scratch69;
|
||||||
|
uint32_t secure_scratch70;
|
||||||
|
uint32_t secure_scratch71;
|
||||||
|
uint32_t secure_scratch72;
|
||||||
|
uint32_t secure_scratch73;
|
||||||
|
uint32_t secure_scratch74;
|
||||||
|
uint32_t secure_scratch75;
|
||||||
|
uint32_t secure_scratch76;
|
||||||
|
uint32_t secure_scratch77;
|
||||||
|
uint32_t secure_scratch78;
|
||||||
|
uint32_t secure_scratch79;
|
||||||
|
uint32_t _reserved2[8];
|
||||||
|
uint32_t cntrl2;
|
||||||
|
uint32_t _reserved3[2];
|
||||||
|
uint32_t event_counter;
|
||||||
|
uint32_t fuse_control;
|
||||||
|
uint32_t scratch1_eco;
|
||||||
|
uint32_t _reserved4;
|
||||||
|
uint32_t io_dpd3_req;
|
||||||
|
uint32_t io_dpd3_status;
|
||||||
|
uint32_t io_dpd4_req;
|
||||||
|
uint32_t io_dpd4_status;
|
||||||
|
uint32_t _reserved5[30];
|
||||||
|
uint32_t ddr_cntrl;
|
||||||
|
uint32_t _reserved6[70];
|
||||||
|
uint32_t scratch56;
|
||||||
|
uint32_t scratch57;
|
||||||
|
uint32_t scratch58;
|
||||||
|
uint32_t scratch59;
|
||||||
|
uint32_t scratch60;
|
||||||
|
uint32_t scratch61;
|
||||||
|
uint32_t scratch62;
|
||||||
|
uint32_t scratch63;
|
||||||
|
uint32_t scratch64;
|
||||||
|
uint32_t scratch65;
|
||||||
|
uint32_t scratch66;
|
||||||
|
uint32_t scratch67;
|
||||||
|
uint32_t scratch68;
|
||||||
|
uint32_t scratch69;
|
||||||
|
uint32_t scratch70;
|
||||||
|
uint32_t scratch71;
|
||||||
|
uint32_t scratch72;
|
||||||
|
uint32_t scratch73;
|
||||||
|
uint32_t scratch74;
|
||||||
|
uint32_t scratch75;
|
||||||
|
uint32_t scratch76;
|
||||||
|
uint32_t scratch77;
|
||||||
|
uint32_t scratch78;
|
||||||
|
uint32_t scratch79;
|
||||||
|
uint32_t scratch80;
|
||||||
|
uint32_t scratch81;
|
||||||
|
uint32_t scratch82;
|
||||||
|
uint32_t scratch83;
|
||||||
|
uint32_t scratch84;
|
||||||
|
uint32_t scratch85;
|
||||||
|
uint32_t scratch86;
|
||||||
|
uint32_t scratch87;
|
||||||
|
uint32_t scratch88;
|
||||||
|
uint32_t scratch89;
|
||||||
|
uint32_t scratch90;
|
||||||
|
uint32_t scratch91;
|
||||||
|
uint32_t scratch92;
|
||||||
|
uint32_t scratch93;
|
||||||
|
uint32_t scratch94;
|
||||||
|
uint32_t scratch95;
|
||||||
|
uint32_t scratch96;
|
||||||
|
uint32_t scratch97;
|
||||||
|
uint32_t scratch98;
|
||||||
|
uint32_t scratch99;
|
||||||
|
uint32_t scratch100;
|
||||||
|
uint32_t scratch101;
|
||||||
|
uint32_t scratch102;
|
||||||
|
uint32_t scratch103;
|
||||||
|
uint32_t scratch104;
|
||||||
|
uint32_t scratch105;
|
||||||
|
uint32_t scratch106;
|
||||||
|
uint32_t scratch107;
|
||||||
|
uint32_t scratch108;
|
||||||
|
uint32_t scratch109;
|
||||||
|
uint32_t scratch110;
|
||||||
|
uint32_t scratch111;
|
||||||
|
uint32_t scratch112;
|
||||||
|
uint32_t scratch113;
|
||||||
|
uint32_t scratch114;
|
||||||
|
uint32_t scratch115;
|
||||||
|
uint32_t scratch116;
|
||||||
|
uint32_t scratch117;
|
||||||
|
uint32_t scratch118;
|
||||||
|
uint32_t scratch119;
|
||||||
|
uint32_t scratch120;
|
||||||
|
uint32_t scratch121;
|
||||||
|
uint32_t scratch122;
|
||||||
|
uint32_t scratch123;
|
||||||
|
uint32_t scratch124;
|
||||||
|
uint32_t scratch125;
|
||||||
|
uint32_t scratch126;
|
||||||
|
uint32_t scratch127;
|
||||||
|
uint32_t scratch128;
|
||||||
|
uint32_t scratch129;
|
||||||
|
uint32_t scratch130;
|
||||||
|
uint32_t scratch131;
|
||||||
|
uint32_t scratch132;
|
||||||
|
uint32_t scratch133;
|
||||||
|
uint32_t scratch134;
|
||||||
|
uint32_t scratch135;
|
||||||
|
uint32_t scratch136;
|
||||||
|
uint32_t scratch137;
|
||||||
|
uint32_t scratch138;
|
||||||
|
uint32_t scratch139;
|
||||||
|
uint32_t scratch140;
|
||||||
|
uint32_t scratch141;
|
||||||
|
uint32_t scratch142;
|
||||||
|
uint32_t scratch143;
|
||||||
|
uint32_t scratch144;
|
||||||
|
uint32_t scratch145;
|
||||||
|
uint32_t scratch146;
|
||||||
|
uint32_t scratch147;
|
||||||
|
uint32_t scratch148;
|
||||||
|
uint32_t scratch149;
|
||||||
|
uint32_t scratch150;
|
||||||
|
uint32_t scratch151;
|
||||||
|
uint32_t scratch152;
|
||||||
|
uint32_t scratch153;
|
||||||
|
uint32_t scratch154;
|
||||||
|
uint32_t scratch155;
|
||||||
|
uint32_t scratch156;
|
||||||
|
uint32_t scratch157;
|
||||||
|
uint32_t scratch158;
|
||||||
|
uint32_t scratch159;
|
||||||
|
uint32_t scratch160;
|
||||||
|
uint32_t scratch161;
|
||||||
|
uint32_t scratch162;
|
||||||
|
uint32_t scratch163;
|
||||||
|
uint32_t scratch164;
|
||||||
|
uint32_t scratch165;
|
||||||
|
uint32_t scratch166;
|
||||||
|
uint32_t scratch167;
|
||||||
|
uint32_t scratch168;
|
||||||
|
uint32_t scratch169;
|
||||||
|
uint32_t scratch170;
|
||||||
|
uint32_t scratch171;
|
||||||
|
uint32_t scratch172;
|
||||||
|
uint32_t scratch173;
|
||||||
|
uint32_t scratch174;
|
||||||
|
uint32_t scratch175;
|
||||||
|
uint32_t scratch176;
|
||||||
|
uint32_t scratch177;
|
||||||
|
uint32_t scratch178;
|
||||||
|
uint32_t scratch179;
|
||||||
|
uint32_t scratch180;
|
||||||
|
uint32_t scratch181;
|
||||||
|
uint32_t scratch182;
|
||||||
|
uint32_t scratch183;
|
||||||
|
uint32_t scratch184;
|
||||||
|
uint32_t scratch185;
|
||||||
|
uint32_t scratch186;
|
||||||
|
uint32_t scratch187;
|
||||||
|
uint32_t scratch188;
|
||||||
|
uint32_t scratch189;
|
||||||
|
uint32_t scratch190;
|
||||||
|
uint32_t scratch191;
|
||||||
|
uint32_t scratch192;
|
||||||
|
uint32_t scratch193;
|
||||||
|
uint32_t scratch194;
|
||||||
|
uint32_t scratch195;
|
||||||
|
uint32_t scratch196;
|
||||||
|
uint32_t scratch197;
|
||||||
|
uint32_t scratch198;
|
||||||
|
uint32_t scratch199;
|
||||||
|
uint32_t scratch200;
|
||||||
|
uint32_t scratch201;
|
||||||
|
uint32_t scratch202;
|
||||||
|
uint32_t scratch203;
|
||||||
|
uint32_t scratch204;
|
||||||
|
uint32_t scratch205;
|
||||||
|
uint32_t scratch206;
|
||||||
|
uint32_t scratch207;
|
||||||
|
uint32_t scratch208;
|
||||||
|
uint32_t scratch209;
|
||||||
|
uint32_t scratch210;
|
||||||
|
uint32_t scratch211;
|
||||||
|
uint32_t scratch212;
|
||||||
|
uint32_t scratch213;
|
||||||
|
uint32_t scratch214;
|
||||||
|
uint32_t scratch215;
|
||||||
|
uint32_t scratch216;
|
||||||
|
uint32_t scratch217;
|
||||||
|
uint32_t scratch218;
|
||||||
|
uint32_t scratch219;
|
||||||
|
uint32_t scratch220;
|
||||||
|
uint32_t scratch221;
|
||||||
|
uint32_t scratch222;
|
||||||
|
uint32_t scratch223;
|
||||||
|
uint32_t scratch224;
|
||||||
|
uint32_t scratch225;
|
||||||
|
uint32_t scratch226;
|
||||||
|
uint32_t scratch227;
|
||||||
|
uint32_t scratch228;
|
||||||
|
uint32_t scratch229;
|
||||||
|
uint32_t scratch230;
|
||||||
|
uint32_t scratch231;
|
||||||
|
uint32_t scratch232;
|
||||||
|
uint32_t scratch233;
|
||||||
|
uint32_t scratch234;
|
||||||
|
uint32_t scratch235;
|
||||||
|
uint32_t scratch236;
|
||||||
|
uint32_t scratch237;
|
||||||
|
uint32_t scratch238;
|
||||||
|
uint32_t scratch239;
|
||||||
|
uint32_t scratch240;
|
||||||
|
uint32_t scratch241;
|
||||||
|
uint32_t scratch242;
|
||||||
|
uint32_t scratch243;
|
||||||
|
uint32_t scratch244;
|
||||||
|
uint32_t scratch245;
|
||||||
|
uint32_t scratch246;
|
||||||
|
uint32_t scratch247;
|
||||||
|
uint32_t scratch248;
|
||||||
|
uint32_t scratch249;
|
||||||
|
uint32_t scratch250;
|
||||||
|
uint32_t scratch251;
|
||||||
|
uint32_t scratch252;
|
||||||
|
uint32_t scratch253;
|
||||||
|
uint32_t scratch254;
|
||||||
|
uint32_t scratch255;
|
||||||
|
uint32_t scratch256;
|
||||||
|
uint32_t scratch257;
|
||||||
|
uint32_t scratch258;
|
||||||
|
uint32_t scratch259;
|
||||||
|
uint32_t scratch260;
|
||||||
|
uint32_t scratch261;
|
||||||
|
uint32_t scratch262;
|
||||||
|
uint32_t scratch263;
|
||||||
|
uint32_t scratch264;
|
||||||
|
uint32_t scratch265;
|
||||||
|
uint32_t scratch266;
|
||||||
|
uint32_t scratch267;
|
||||||
|
uint32_t scratch268;
|
||||||
|
uint32_t scratch269;
|
||||||
|
uint32_t scratch270;
|
||||||
|
uint32_t scratch271;
|
||||||
|
uint32_t scratch272;
|
||||||
|
uint32_t scratch273;
|
||||||
|
uint32_t scratch274;
|
||||||
|
uint32_t scratch275;
|
||||||
|
uint32_t scratch276;
|
||||||
|
uint32_t scratch277;
|
||||||
|
uint32_t scratch278;
|
||||||
|
uint32_t scratch279;
|
||||||
|
uint32_t scratch280;
|
||||||
|
uint32_t scratch281;
|
||||||
|
uint32_t scratch282;
|
||||||
|
uint32_t scratch283;
|
||||||
|
uint32_t scratch284;
|
||||||
|
uint32_t scratch285;
|
||||||
|
uint32_t scratch286;
|
||||||
|
uint32_t scratch287;
|
||||||
|
uint32_t scratch288;
|
||||||
|
uint32_t scratch289;
|
||||||
|
uint32_t scratch290;
|
||||||
|
uint32_t scratch291;
|
||||||
|
uint32_t scratch292;
|
||||||
|
uint32_t scratch293;
|
||||||
|
uint32_t scratch294;
|
||||||
|
uint32_t scratch295;
|
||||||
|
uint32_t scratch296;
|
||||||
|
uint32_t scratch297;
|
||||||
|
uint32_t scratch298;
|
||||||
|
uint32_t scratch299;
|
||||||
|
uint32_t _reserved7[50];
|
||||||
|
uint32_t secure_scratch80;
|
||||||
|
uint32_t secure_scratch81;
|
||||||
|
uint32_t secure_scratch82;
|
||||||
|
uint32_t secure_scratch83;
|
||||||
|
uint32_t secure_scratch84;
|
||||||
|
uint32_t secure_scratch85;
|
||||||
|
uint32_t secure_scratch86;
|
||||||
|
uint32_t secure_scratch87;
|
||||||
|
uint32_t secure_scratch88;
|
||||||
|
uint32_t secure_scratch89;
|
||||||
|
uint32_t secure_scratch90;
|
||||||
|
uint32_t secure_scratch91;
|
||||||
|
uint32_t secure_scratch92;
|
||||||
|
uint32_t secure_scratch93;
|
||||||
|
uint32_t secure_scratch94;
|
||||||
|
uint32_t secure_scratch95;
|
||||||
|
uint32_t secure_scratch96;
|
||||||
|
uint32_t secure_scratch97;
|
||||||
|
uint32_t secure_scratch98;
|
||||||
|
uint32_t secure_scratch99;
|
||||||
|
uint32_t secure_scratch100;
|
||||||
|
uint32_t secure_scratch101;
|
||||||
|
uint32_t secure_scratch102;
|
||||||
|
uint32_t secure_scratch103;
|
||||||
|
uint32_t secure_scratch104;
|
||||||
|
uint32_t secure_scratch105;
|
||||||
|
uint32_t secure_scratch106;
|
||||||
|
uint32_t secure_scratch107;
|
||||||
|
uint32_t secure_scratch108;
|
||||||
|
uint32_t secure_scratch109;
|
||||||
|
uint32_t secure_scratch110;
|
||||||
|
uint32_t secure_scratch111;
|
||||||
|
uint32_t secure_scratch112;
|
||||||
|
uint32_t secure_scratch113;
|
||||||
|
uint32_t secure_scratch114;
|
||||||
|
uint32_t secure_scratch115;
|
||||||
|
uint32_t secure_scratch116;
|
||||||
|
uint32_t secure_scratch117;
|
||||||
|
uint32_t secure_scratch118;
|
||||||
|
uint32_t secure_scratch119;
|
||||||
|
} tegra_pmc_t;
|
||||||
|
|
||||||
|
static inline volatile tegra_pmc_t *pmc_get_regs(void)
|
||||||
|
{
|
||||||
|
return (volatile tegra_pmc_t *)PMC_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -29,7 +29,7 @@ TARGET := $(notdir $(CURDIR))
|
|||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := src src/sdmmc src/lib src/lib/fatfs src/display
|
SOURCES := src src/sdmmc src/lib src/lib/fatfs src/display
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include ../../common/include
|
INCLUDES := include ../../libraries/libvapours/include
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
|
|||||||
@@ -13,171 +13,178 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
#include "pmc.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
|
|
||||||
/* Prototypes for internal commands. */
|
/* Prototypes for internal commands. */
|
||||||
void fuse_make_regs_visible(void);
|
|
||||||
|
|
||||||
void fuse_enable_power(void);
|
void fuse_enable_power(void);
|
||||||
void fuse_disable_power(void);
|
void fuse_disable_power(void);
|
||||||
void fuse_wait_idle(void);
|
void fuse_wait_idle(void);
|
||||||
|
|
||||||
/* Initialize the fuse driver */
|
/* Initialize the fuse driver */
|
||||||
void fuse_init(void) {
|
void fuse_init(void) {
|
||||||
fuse_make_regs_visible();
|
/* Make all fuse registers visible, disable the private key and disable programming. */
|
||||||
fuse_secondary_private_key_disable();
|
|
||||||
fuse_disable_programming();
|
|
||||||
|
|
||||||
/* TODO: Overrides (iROM patches) and various reads happen here */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make all fuse registers visible */
|
|
||||||
void fuse_make_regs_visible(void) {
|
|
||||||
clkrst_enable_fuse_regs(true);
|
clkrst_enable_fuse_regs(true);
|
||||||
|
fuse_disable_private_key();
|
||||||
|
fuse_disable_programming();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable power to the fuse hardware array */
|
/* Disable access to the private key and set the TZ sticky bit. */
|
||||||
|
void fuse_disable_private_key(void) {
|
||||||
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
fuse->FUSE_PRIVATEKEYDISABLE = 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disables all fuse programming. */
|
||||||
|
void fuse_disable_programming(void) {
|
||||||
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
fuse->FUSE_DISABLEREGPROGRAM = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable power to the fuse hardware array. */
|
||||||
void fuse_enable_power(void) {
|
void fuse_enable_power(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||||
fuse->FUSE_PWR_GOOD_SW = 1;
|
pmc->fuse_control &= ~(0x200); /* Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
|
||||||
udelay(1);
|
mdelay(1);
|
||||||
|
pmc->fuse_control |= 0x100; /* Set PMC_FUSE_CTRL_PS18_LATCH_SET. */
|
||||||
|
mdelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable power to the fuse hardware array */
|
/* Disable power to the fuse hardware array. */
|
||||||
void fuse_disable_power(void) {
|
void fuse_disable_power(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||||
fuse->FUSE_PWR_GOOD_SW = 0;
|
pmc->fuse_control &= ~(0x100); /* Clear PMC_FUSE_CTRL_PS18_LATCH_SET. */
|
||||||
udelay(1);
|
mdelay(1);
|
||||||
|
pmc->fuse_control |= 0x200; /* Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
|
||||||
|
mdelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for the fuse driver to go idle */
|
/* Wait for the fuse driver to go idle. */
|
||||||
void fuse_wait_idle(void) {
|
void fuse_wait_idle(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
uint32_t ctrl_val = 0;
|
uint32_t ctrl_val = 0;
|
||||||
|
|
||||||
/* Wait for STATE_IDLE */
|
/* Wait for STATE_IDLE */
|
||||||
while ((ctrl_val & (0xF0000)) != 0x40000)
|
while ((ctrl_val & (0xF0000)) != 0x40000)
|
||||||
{
|
ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
udelay(1);
|
|
||||||
ctrl_val = fuse->FUSE_CTRL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a fuse from the hardware array */
|
/* Read a fuse from the hardware array. */
|
||||||
uint32_t fuse_hw_read(uint32_t addr) {
|
uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
/* Program the target address */
|
/* Program the target address. */
|
||||||
fuse->FUSE_REG_ADDR = addr;
|
fuse->FUSE_FUSEADDR = addr;
|
||||||
|
|
||||||
/* Enable read operation in control register */
|
/* Enable read operation in control register. */
|
||||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x1; /* Set FUSE_READ command */
|
ctrl_val |= 0x1; /* Set READ command. */
|
||||||
fuse->FUSE_CTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
return fuse->FUSE_REG_READ;
|
return fuse->FUSE_FUSERDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write a fuse in the hardware array */
|
/* Write a fuse in the hardware array. */
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
/* Program the target address and value */
|
/* Program the target address and value. */
|
||||||
fuse->FUSE_REG_ADDR = addr;
|
fuse->FUSE_FUSEADDR = addr;
|
||||||
fuse->FUSE_REG_WRITE = value;
|
fuse->FUSE_FUSEWDATA = value;
|
||||||
|
|
||||||
/* Enable write operation in control register */
|
/* Enable write operation in control register. */
|
||||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x2; /* Set FUSE_WRITE command */
|
ctrl_val |= 0x2; /* Set WRITE command. */
|
||||||
fuse->FUSE_CTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sense the fuse hardware array into the shadow cache */
|
/* Sense the fuse hardware array into the shadow cache. */
|
||||||
void fuse_hw_sense(void) {
|
void fuse_hw_sense(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
/* Enable sense operation in control register */
|
/* Enable sense operation in control register */
|
||||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x3; /* Set FUSE_SENSE command */
|
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
||||||
fuse->FUSE_CTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disables all fuse programming. */
|
/* Read the SKU info register from the shadow cache. */
|
||||||
void fuse_disable_programming(void) {
|
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
|
||||||
fuse->FUSE_DIS_PGM = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */
|
|
||||||
void fuse_secondary_private_key_disable(void) {
|
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
|
||||||
fuse->FUSE_PRIVATEKEYDISABLE = 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Read the SKU info register from the shadow cache */
|
|
||||||
uint32_t fuse_get_sku_info(void) {
|
uint32_t fuse_get_sku_info(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
return fuse_chip->FUSE_SKU_INFO;
|
return fuse_chip->FUSE_SKU_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the bootrom patch version from a register in the shadow cache */
|
/* Read the bootrom patch version from a register in the shadow cache. */
|
||||||
uint32_t fuse_get_bootrom_patch_version(void) {
|
uint32_t fuse_get_bootrom_patch_version(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
return fuse_chip->FUSE_SOC_SPEEDO_1;
|
return fuse_chip->FUSE_SOC_SPEEDO_1_CALIB;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a spare bit register from the shadow cache */
|
/* Read a spare bit register from the shadow cache */
|
||||||
uint32_t fuse_get_spare_bit(uint32_t idx) {
|
uint32_t fuse_get_spare_bit(uint32_t idx) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
if (idx < 32) {
|
||||||
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (idx >= 32) {
|
return fuse_chip->FUSE_SPARE_BIT[idx];
|
||||||
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fuse_chip->FUSE_SPARE_BIT[idx];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a reserved ODM register from the shadow cache */
|
/* Read a reserved ODM register from the shadow cache. */
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t idx) {
|
uint32_t fuse_get_reserved_odm(uint32_t idx) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
if (idx < 8) {
|
||||||
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (idx >= 8) {
|
return fuse_chip->FUSE_RESERVED_ODM[idx];
|
||||||
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM[idx];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Device ID using values in the shadow cache */
|
/* Get the DRAM ID using values in the shadow cache. */
|
||||||
|
uint32_t fuse_get_dram_id(void) {
|
||||||
|
return ((fuse_get_reserved_odm(4) >> 3) & 0x7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Derive the Device ID using values in the shadow cache. */
|
||||||
uint64_t fuse_get_device_id(void) {
|
uint64_t fuse_get_device_id(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
|
|
||||||
uint64_t device_id = 0;
|
uint64_t device_id = 0;
|
||||||
uint64_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
|
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint64_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
|
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint64_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
|
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code = fuse_chip->FUSE_LOT_CODE_0;
|
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
||||||
uint64_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
|
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
|
|
||||||
uint64_t derived_lot_code = 0;
|
uint64_t derived_lot_code = 0;
|
||||||
for (unsigned int i = 0; i < 5; i++) {
|
for (unsigned int i = 0; i < 5; i++) {
|
||||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||||
@@ -189,45 +196,41 @@ uint64_t fuse_get_device_id(void) {
|
|||||||
device_id |= wafer_id << 18;
|
device_id |= wafer_id << 18;
|
||||||
device_id |= derived_lot_code << 24;
|
device_id |= derived_lot_code << 24;
|
||||||
device_id |= fab_code << 50;
|
device_id |= fab_code << 50;
|
||||||
|
|
||||||
return device_id;
|
return device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the DRAM ID using values in the shadow cache */
|
/* Derive the Hardware Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_dram_id(void) {
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
return (fuse_chip->FUSE_RESERVED_ODM[4] >> 3) & 0x7;
|
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the Hardware Type using values in the shadow cache */
|
/* Firmware from versions 1.0.0 to 3.0.2. */
|
||||||
uint32_t fuse_get_hardware_type(void) {
|
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
|
|
||||||
/* This function is very different between 4.x and < 4.x */
|
|
||||||
uint32_t hardware_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((fuse_chip->FUSE_RESERVED_ODM[4] >> 2) & 1);
|
|
||||||
|
|
||||||
/* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) {
|
|
||||||
static const uint32_t types[] = {0,1,4,3};
|
|
||||||
|
|
||||||
hardware_type |= (fuse_chip->FUSE_RESERVED_ODM[4] >> 14) & 0x3C;
|
|
||||||
hardware_type--;
|
|
||||||
return hardware_type > 3 ? 4 : types[hardware_type];
|
|
||||||
} else {*/
|
|
||||||
if (hardware_type >= 1) {
|
if (hardware_type >= 1) {
|
||||||
return hardware_type > 2 ? 3 : hardware_type - 1;
|
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
||||||
} else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) {
|
} else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
// }
|
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
||||||
|
static const uint32_t types[] = {0,1,4,3};
|
||||||
|
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
||||||
|
hardware_type--;
|
||||||
|
return (hardware_type > 3) ? 4 : types[hardware_type];
|
||||||
|
} else { /* Firmware versions from 7.0.0 onwards. */
|
||||||
|
/* Always return 0 in retail. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Retail Type using values in the shadow cache */
|
/* Derive the Retail Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_retail_type(void) {
|
uint32_t fuse_get_retail_type(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
/* Retail Type = IS_RETAIL | UNIT_TYPE. */
|
||||||
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
/* Retail type = IS_RETAIL | UNIT_TYPE */
|
uint32_t retail_type = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3));
|
||||||
uint32_t retail_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 4) | (fuse_chip->FUSE_RESERVED_ODM[4] & 3);
|
|
||||||
if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */
|
if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */
|
||||||
return 1;
|
return 1;
|
||||||
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
|
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
|
||||||
@@ -241,17 +244,17 @@ void fuse_get_hardware_info(void *dst) {
|
|||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
uint32_t hw_info[0x4];
|
uint32_t hw_info[0x4];
|
||||||
|
|
||||||
uint32_t unk_hw_fuse = fuse_chip->_0x120 & 0x3F;
|
uint32_t ops_reserved = fuse_chip->FUSE_OPT_OPS_RESERVED & 0x3F;
|
||||||
uint32_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
|
uint32_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint32_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
|
uint32_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint32_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
|
uint32_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code_0 = fuse_chip->FUSE_LOT_CODE_0;
|
uint32_t lot_code_0 = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
||||||
uint32_t lot_code_1 = fuse_chip->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
|
uint32_t lot_code_1 = fuse_chip->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF;
|
||||||
uint32_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
|
uint32_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
uint32_t vendor_code = fuse_chip->FUSE_VENDOR_CODE & 0xF;
|
uint32_t vendor_code = fuse_chip->FUSE_OPT_VENDOR_CODE & 0xF;
|
||||||
|
|
||||||
/* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
|
/* Hardware Info = OPS_RESERVED || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
|
||||||
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse));
|
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (ops_reserved));
|
||||||
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
|
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
|
||||||
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
|
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
|
||||||
hw_info[3] = (uint32_t)(vendor_code);
|
hw_info[3] = (uint32_t)(vendor_code);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_FUSE_H
|
#ifndef FUSEE_FUSE_H
|
||||||
#define FUSEE_FUSE_H
|
#define FUSEE_FUSE_H
|
||||||
|
|
||||||
@@ -23,154 +23,167 @@
|
|||||||
#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
|
#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t FUSE_CTRL;
|
uint32_t FUSE_FUSECTRL;
|
||||||
uint32_t FUSE_REG_ADDR;
|
uint32_t FUSE_FUSEADDR;
|
||||||
uint32_t FUSE_REG_READ;
|
uint32_t FUSE_FUSERDATA;
|
||||||
uint32_t FUSE_REG_WRITE;
|
uint32_t FUSE_FUSEWDATA;
|
||||||
uint32_t FUSE_TIME_RD1;
|
uint32_t FUSE_FUSETIME_RD1;
|
||||||
uint32_t FUSE_TIME_RD2;
|
uint32_t FUSE_FUSETIME_RD2;
|
||||||
uint32_t FUSE_TIME_PGM1;
|
uint32_t FUSE_FUSETIME_PGM1;
|
||||||
uint32_t FUSE_TIME_PGM2;
|
uint32_t FUSE_FUSETIME_PGM2;
|
||||||
uint32_t FUSE_PRIV2INTFC;
|
uint32_t FUSE_PRIV2INTFC_START;
|
||||||
uint32_t FUSE_FUSEBYPASS;
|
uint32_t FUSE_FUSEBYPASS;
|
||||||
uint32_t FUSE_PRIVATEKEYDISABLE;
|
uint32_t FUSE_PRIVATEKEYDISABLE;
|
||||||
uint32_t FUSE_DIS_PGM;
|
uint32_t FUSE_DISABLEREGPROGRAM;
|
||||||
uint32_t FUSE_WRITE_ACCESS;
|
uint32_t FUSE_WRITE_ACCESS_SW;
|
||||||
uint32_t FUSE_PWR_GOOD_SW;
|
uint32_t FUSE_PWR_GOOD_SW;
|
||||||
uint32_t _0x38[0x32];
|
uint32_t _0x38;
|
||||||
|
uint32_t FUSE_PRIV2RESHIFT;
|
||||||
|
uint32_t _0x40[0x3];
|
||||||
|
uint32_t FUSE_FUSETIME_RD3;
|
||||||
|
uint32_t _0x50[0xC];
|
||||||
|
uint32_t FUSE_PRIVATE_KEY0_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY1_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY2_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY3_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY4_NONZERO;
|
||||||
|
uint32_t _0x90[0x1C];
|
||||||
} tegra_fuse_t;
|
} tegra_fuse_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t FUSE_PRODUCTION_MODE;
|
uint32_t FUSE_PRODUCTION_MODE;
|
||||||
uint32_t _0x4;
|
uint32_t FUSE_JTAG_SECUREID_VALID;
|
||||||
uint32_t _0x8;
|
uint32_t FUSE_ODM_LOCK;
|
||||||
uint32_t _0xC;
|
uint32_t FUSE_OPT_OPENGL_EN;
|
||||||
uint32_t FUSE_SKU_INFO;
|
uint32_t FUSE_SKU_INFO;
|
||||||
uint32_t FUSE_CPU_SPEEDO_0;
|
uint32_t FUSE_CPU_SPEEDO_0_CALIB;
|
||||||
uint32_t FUSE_CPU_IDDQ;
|
uint32_t FUSE_CPU_IDDQ_CALIB;
|
||||||
uint32_t _0x1C;
|
uint32_t FUSE_DAC_CRT_CALIB;
|
||||||
uint32_t _0x20;
|
uint32_t FUSE_DAC_HDTV_CALIB;
|
||||||
uint32_t _0x24;
|
uint32_t FUSE_DAC_SDTV_CALIB;
|
||||||
uint32_t FUSE_FT_REV;
|
uint32_t FUSE_OPT_FT_REV;
|
||||||
uint32_t FUSE_CPU_SPEEDO_1;
|
uint32_t FUSE_CPU_SPEEDO_1_CALIB;
|
||||||
uint32_t FUSE_CPU_SPEEDO_2;
|
uint32_t FUSE_CPU_SPEEDO_2_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_0;
|
uint32_t FUSE_SOC_SPEEDO_0_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_1;
|
uint32_t FUSE_SOC_SPEEDO_1_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_2;
|
uint32_t FUSE_SOC_SPEEDO_2_CALIB;
|
||||||
uint32_t FUSE_SOC_IDDQ;
|
uint32_t FUSE_SOC_IDDQ_CALIB;
|
||||||
uint32_t _0x44;
|
uint32_t FUSE_RESERVED_PRODUCTION_WP;
|
||||||
uint32_t FUSE_FA;
|
uint32_t FUSE_FA;
|
||||||
uint32_t _0x4C;
|
uint32_t FUSE_RESERVED_PRODUCTION;
|
||||||
uint32_t _0x50;
|
uint32_t FUSE_HDMI_LANE0_CALIB;
|
||||||
uint32_t _0x54;
|
uint32_t FUSE_HDMI_LANE1_CALIB;
|
||||||
uint32_t _0x58;
|
uint32_t FUSE_HDMI_LANE2_CALIB;
|
||||||
uint32_t _0x5C;
|
uint32_t FUSE_HDMI_LANE3_CALIB;
|
||||||
uint32_t _0x60;
|
uint32_t FUSE_ENCRYPTION_RATE;
|
||||||
uint32_t FUSE_PUBLIC_KEY[0x8];
|
uint32_t FUSE_PUBLIC_KEY[0x8];
|
||||||
uint32_t FUSE_TSENSOR_1;
|
uint32_t FUSE_TSENSOR1_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_2;
|
uint32_t FUSE_TSENSOR2_CALIB;
|
||||||
uint32_t _0x8C;
|
uint32_t FUSE_VSENSOR_CALIB;
|
||||||
uint32_t FUSE_CP_REV;
|
uint32_t FUSE_OPT_CP_REV;
|
||||||
uint32_t _0x94;
|
uint32_t FUSE_OPT_PFG;
|
||||||
uint32_t FUSE_TSENSOR_0;
|
uint32_t FUSE_TSENSOR0_CALIB;
|
||||||
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG;
|
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE;
|
||||||
uint32_t FUSE_SECURITY_MODE;
|
uint32_t FUSE_SECURITY_MODE;
|
||||||
uint32_t FUSE_PRIVATE_KEY[0x4];
|
uint32_t FUSE_PRIVATE_KEY[0x5];
|
||||||
uint32_t FUSE_DEVICE_KEY;
|
uint32_t FUSE_ARM_JTAG_DIS;
|
||||||
uint32_t _0xB8;
|
uint32_t FUSE_BOOT_DEVICE_INFO;
|
||||||
uint32_t _0xBC;
|
|
||||||
uint32_t FUSE_RESERVED_SW;
|
uint32_t FUSE_RESERVED_SW;
|
||||||
uint32_t FUSE_VP8_ENABLE;
|
uint32_t FUSE_OPT_VP9_DISABLE;
|
||||||
uint32_t FUSE_RESERVED_ODM[0x8];
|
uint32_t FUSE_RESERVED_ODM[0x8];
|
||||||
uint32_t _0xE8;
|
uint32_t FUSE_OBS_DIS;
|
||||||
uint32_t _0xEC;
|
uint32_t FUSE_NOR_INFO;
|
||||||
uint32_t FUSE_SKU_USB_CALIB;
|
uint32_t FUSE_USB_CALIB;
|
||||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
||||||
uint32_t _0xF8;
|
uint32_t FUSE_KFUSE_PRIVKEY_CTRL;
|
||||||
uint32_t _0xFC;
|
uint32_t FUSE_PACKAGE_INFO;
|
||||||
uint32_t FUSE_VENDOR_CODE;
|
uint32_t FUSE_OPT_VENDOR_CODE;
|
||||||
uint32_t FUSE_FAB_CODE;
|
uint32_t FUSE_OPT_FAB_CODE;
|
||||||
uint32_t FUSE_LOT_CODE_0;
|
uint32_t FUSE_OPT_LOT_CODE_0;
|
||||||
uint32_t FUSE_LOT_CODE_1;
|
uint32_t FUSE_OPT_LOT_CODE_1;
|
||||||
uint32_t FUSE_WAFER_ID;
|
uint32_t FUSE_OPT_WAFER_ID;
|
||||||
uint32_t FUSE_X_COORDINATE;
|
uint32_t FUSE_OPT_X_COORDINATE;
|
||||||
uint32_t FUSE_Y_COORDINATE;
|
uint32_t FUSE_OPT_Y_COORDINATE;
|
||||||
uint32_t _0x11C;
|
uint32_t FUSE_OPT_SEC_DEBUG_EN;
|
||||||
uint32_t _0x120;
|
uint32_t FUSE_OPT_OPS_RESERVED;
|
||||||
uint32_t FUSE_SATA_CALIB;
|
uint32_t FUSE_SATA_CALIB;
|
||||||
uint32_t FUSE_GPU_IDDQ;
|
uint32_t FUSE_GPU_IDDQ_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_3;
|
uint32_t FUSE_TSENSOR3_CALIB;
|
||||||
uint32_t _0x130;
|
uint32_t FUSE_SKU_BOND_OUT_L;
|
||||||
uint32_t _0x134;
|
uint32_t FUSE_SKU_BOND_OUT_H;
|
||||||
uint32_t _0x138;
|
uint32_t FUSE_SKU_BOND_OUT_U;
|
||||||
uint32_t _0x13C;
|
uint32_t FUSE_SKU_BOND_OUT_V;
|
||||||
uint32_t _0x140;
|
uint32_t FUSE_SKU_BOND_OUT_W;
|
||||||
uint32_t _0x144;
|
uint32_t FUSE_OPT_SAMPLE_TYPE;
|
||||||
uint32_t FUSE_OPT_SUBREVISION;
|
uint32_t FUSE_OPT_SUBREVISION;
|
||||||
uint32_t _0x14C;
|
uint32_t FUSE_OPT_SW_RESERVED_0;
|
||||||
uint32_t _0x150;
|
uint32_t FUSE_OPT_SW_RESERVED_1;
|
||||||
uint32_t FUSE_TSENSOR_4;
|
uint32_t FUSE_TSENSOR4_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_5;
|
uint32_t FUSE_TSENSOR5_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_6;
|
uint32_t FUSE_TSENSOR6_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_7;
|
uint32_t FUSE_TSENSOR7_CALIB;
|
||||||
uint32_t FUSE_OPT_PRIV_SEC_DIS;
|
uint32_t FUSE_OPT_PRIV_SEC_EN;
|
||||||
uint32_t FUSE_PKC_DISABLE;
|
uint32_t FUSE_PKC_DISABLE;
|
||||||
uint32_t _0x16C;
|
uint32_t _0x16C;
|
||||||
uint32_t _0x170;
|
uint32_t _0x170;
|
||||||
uint32_t _0x174;
|
uint32_t _0x174;
|
||||||
uint32_t _0x178;
|
uint32_t _0x178;
|
||||||
uint32_t _0x17C;
|
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
||||||
uint32_t FUSE_TSENSOR_COMMON;
|
uint32_t FUSE_TSENSOR_COMMON;
|
||||||
uint32_t _0x184;
|
uint32_t FUSE_OPT_CP_BIN;
|
||||||
uint32_t _0x188;
|
uint32_t FUSE_OPT_GPU_DISABLE;
|
||||||
uint32_t _0x18C;
|
uint32_t FUSE_OPT_FT_BIN;
|
||||||
uint32_t _0x190;
|
uint32_t FUSE_OPT_DONE_MAP;
|
||||||
uint32_t _0x194;
|
uint32_t _0x194;
|
||||||
uint32_t _0x198;
|
uint32_t FUSE_APB2JTAG_DISABLE;
|
||||||
uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
|
uint32_t FUSE_ODM_INFO;
|
||||||
uint32_t _0x1A0;
|
uint32_t _0x1A0;
|
||||||
uint32_t _0x1A4;
|
uint32_t _0x1A4;
|
||||||
uint32_t _0x1A8;
|
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
|
||||||
uint32_t _0x1AC;
|
uint32_t _0x1AC;
|
||||||
uint32_t _0x1B0;
|
uint32_t _0x1B0;
|
||||||
uint32_t _0x1B4;
|
uint32_t _0x1B4;
|
||||||
uint32_t _0x1B8;
|
uint32_t _0x1B8;
|
||||||
uint32_t _0x1BC;
|
uint32_t _0x1BC;
|
||||||
uint32_t _0x1D0;
|
uint32_t FUSE_WOA_SKU_FLAG;
|
||||||
uint32_t FUSE_TSENSOR_8;
|
uint32_t FUSE_ECO_RESERVE_1;
|
||||||
|
uint32_t FUSE_GCPLEX_CONFIG_FUSE;
|
||||||
|
uint32_t FUSE_PRODUCTION_MONTH;
|
||||||
|
uint32_t FUSE_RAM_REPAIR_INDICATOR;
|
||||||
|
uint32_t FUSE_TSENSOR9_CALIB;
|
||||||
uint32_t _0x1D8;
|
uint32_t _0x1D8;
|
||||||
uint32_t _0x1DC;
|
uint32_t FUSE_VMIN_CALIBRATION;
|
||||||
uint32_t _0x1E0;
|
uint32_t FUSE_AGING_SENSOR_CALIBRATION;
|
||||||
uint32_t _0x1E4;
|
uint32_t FUSE_DEBUG_AUTHENTICATION;
|
||||||
uint32_t _0x1E8;
|
uint32_t FUSE_SECURE_PROVISION_INDEX;
|
||||||
uint32_t _0x1EC;
|
uint32_t FUSE_SECURE_PROVISION_INFO;
|
||||||
uint32_t _0x1F0;
|
uint32_t FUSE_OPT_GPU_DISABLE_CP1;
|
||||||
uint32_t _0x1F4;
|
uint32_t FUSE_SPARE_ENDIS;
|
||||||
uint32_t _0x1F8;
|
uint32_t FUSE_ECO_RESERVE_0;
|
||||||
uint32_t _0x1FC;
|
uint32_t _0x1FC;
|
||||||
uint32_t _0x200;
|
uint32_t _0x200;
|
||||||
uint32_t FUSE_RESERVED_CALIB;
|
uint32_t FUSE_RESERVED_CALIB0;
|
||||||
uint32_t _0x208;
|
uint32_t FUSE_RESERVED_CALIB1;
|
||||||
uint32_t _0x20C;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE;
|
||||||
uint32_t _0x210;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1;
|
||||||
uint32_t _0x214;
|
uint32_t FUSE_OPT_CPU_DISABLE;
|
||||||
uint32_t _0x218;
|
uint32_t FUSE_OPT_CPU_DISABLE_CP1;
|
||||||
uint32_t FUSE_TSENSOR_9;
|
uint32_t FUSE_TSENSOR10_CALIB;
|
||||||
uint32_t _0x220;
|
uint32_t FUSE_TSENSOR10_CALIB_AUX;
|
||||||
uint32_t _0x224;
|
uint32_t FUSE_OPT_RAM_SVOP_DP;
|
||||||
uint32_t _0x228;
|
uint32_t FUSE_OPT_RAM_SVOP_PDP;
|
||||||
uint32_t _0x22C;
|
uint32_t FUSE_OPT_RAM_SVOP_REG;
|
||||||
uint32_t _0x230;
|
uint32_t FUSE_OPT_RAM_SVOP_SP;
|
||||||
uint32_t _0x234;
|
uint32_t FUSE_OPT_RAM_SVOP_SMPDP;
|
||||||
uint32_t _0x238;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2;
|
||||||
uint32_t _0x23C;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE;
|
||||||
uint32_t _0x240;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1;
|
||||||
uint32_t _0x244;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2;
|
||||||
uint32_t _0x248;
|
uint32_t FUSE_OPT_CPU_DISABLE_CP2;
|
||||||
uint32_t _0x24C;
|
uint32_t FUSE_OPT_GPU_DISABLE_CP2;
|
||||||
uint32_t FUSE_USB_CALIB_EXT;
|
uint32_t FUSE_USB_CALIB_EXT;
|
||||||
uint32_t _0x254;
|
uint32_t FUSE_RESERVED_FIELD;
|
||||||
uint32_t _0x258;
|
uint32_t FUSE_OPT_ECC_EN;
|
||||||
uint32_t _0x25C;
|
uint32_t _0x25C;
|
||||||
uint32_t _0x260;
|
uint32_t _0x260;
|
||||||
uint32_t _0x264;
|
uint32_t _0x264;
|
||||||
@@ -179,35 +192,36 @@ typedef struct {
|
|||||||
uint32_t _0x270;
|
uint32_t _0x270;
|
||||||
uint32_t _0x274;
|
uint32_t _0x274;
|
||||||
uint32_t _0x278;
|
uint32_t _0x278;
|
||||||
uint32_t _0x27C;
|
uint32_t FUSE_SPARE_REALIGNMENT_REG;
|
||||||
uint32_t FUSE_SPARE_BIT[0x20];
|
uint32_t FUSE_SPARE_BIT[0x20];
|
||||||
} tegra_fuse_chip_t;
|
} tegra_fuse_chip_t;
|
||||||
|
|
||||||
static inline volatile tegra_fuse_t *fuse_get_regs(void) {
|
static inline volatile tegra_fuse_t *fuse_get_regs(void)
|
||||||
|
{
|
||||||
return (volatile tegra_fuse_t *)FUSE_BASE;
|
return (volatile tegra_fuse_t *)FUSE_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) {
|
static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void)
|
||||||
|
{
|
||||||
return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE;
|
return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuse_init(void);
|
void fuse_init(void);
|
||||||
|
|
||||||
uint32_t fuse_hw_read(uint32_t addr);
|
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr);
|
|
||||||
void fuse_hw_sense(void);
|
|
||||||
void fuse_disable_programming(void);
|
void fuse_disable_programming(void);
|
||||||
void fuse_secondary_private_key_disable(void);
|
void fuse_disable_private_key(void);
|
||||||
|
|
||||||
uint32_t fuse_get_sku_info(void);
|
uint32_t fuse_get_sku_info(void);
|
||||||
uint32_t fuse_get_spare_bit(uint32_t idx);
|
uint32_t fuse_get_spare_bit(uint32_t idx);
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t idx);
|
uint32_t fuse_get_reserved_odm(uint32_t idx);
|
||||||
|
|
||||||
uint32_t fuse_get_bootrom_patch_version(void);
|
uint32_t fuse_get_bootrom_patch_version(void);
|
||||||
uint64_t fuse_get_device_id(void);
|
uint64_t fuse_get_device_id(void);
|
||||||
uint32_t fuse_get_dram_id(void);
|
uint32_t fuse_get_dram_id(void);
|
||||||
uint32_t fuse_get_hardware_type(void);
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware);
|
||||||
uint32_t fuse_get_retail_type(void);
|
uint32_t fuse_get_retail_type(void);
|
||||||
void fuse_get_hardware_info(void *dst);
|
void fuse_get_hardware_info(void *dst);
|
||||||
|
|
||||||
|
uint32_t fuse_hw_read(uint32_t addr);
|
||||||
|
void fuse_hw_write(uint32_t value, uint32_t addr);
|
||||||
|
void fuse_hw_sense(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -162,16 +162,16 @@ void config_se_brom()
|
|||||||
set_aes_keyslot(0xE, sbk, 0x10);
|
set_aes_keyslot(0xE, sbk, 0x10);
|
||||||
|
|
||||||
/* Lock SBK from being read. */
|
/* Lock SBK from being read. */
|
||||||
se->AES_KEYSLOT_FLAGS[0xE] = 0x7E;
|
se->SE_CRYPTO_KEYTABLE_ACCESS[0xE] = 0x7E;
|
||||||
|
|
||||||
/* This memset needs to happen here, else TZRAM will behave weirdly later on. */
|
/* This memset needs to happen here, else TZRAM will behave weirdly later on. */
|
||||||
memset((void *)0x7C010000, 0, 0x10000);
|
memset((void *)0x7C010000, 0, 0x10000);
|
||||||
|
|
||||||
pmc->crypto_op = 0;
|
pmc->crypto_op = 0;
|
||||||
se->INT_STATUS_REG = 0x1F;
|
se->SE_INT_STATUS = 0x1F;
|
||||||
|
|
||||||
/* Lock SSK (although it's not set and unused anyways). */
|
/* Lock SSK (although it's not set and unused anyways). */
|
||||||
se->AES_KEYSLOT_FLAGS[0xF] = 0x7E;
|
se->SE_CRYPTO_KEYTABLE_ACCESS[0xF] = 0x7E;
|
||||||
|
|
||||||
/* Clear the boot reason to avoid problems later */
|
/* Clear the boot reason to avoid problems later */
|
||||||
pmc->scratch200 = 0;
|
pmc->scratch200 = 0;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "exception_handlers.h"
|
#include "exception_handlers.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
@@ -37,35 +37,40 @@ static char g_bct0_buffer[BCTO_MAX_SIZE];
|
|||||||
|
|
||||||
#define CONFIG_LOG_LEVEL_KEY "log_level"
|
#define CONFIG_LOG_LEVEL_KEY "log_level"
|
||||||
|
|
||||||
#define DEFAULT_BCT0_FOR_DEBUG \
|
#define DEFAULT_BCT0 \
|
||||||
"BCT0\n"\
|
"BCT0\n"\
|
||||||
"[stage1]\n"\
|
"[stage1]\n"\
|
||||||
"stage2_path = atmosphere/fusee-secondary.bin\n"\
|
"stage2_path = atmosphere/fusee-secondary.bin\n"\
|
||||||
"stage2_mtc_path = atmosphere/fusee-mtc.bin\n"\
|
"stage2_mtc_path = atmosphere/fusee-mtc.bin\n"\
|
||||||
"stage2_addr = 0xF0000000\n"\
|
"stage2_addr = 0xF0000000\n"\
|
||||||
"stage2_entrypoint = 0xF0000000\n"
|
"stage2_entrypoint = 0xF0000000\n"\
|
||||||
|
"[exosphere]\n"\
|
||||||
|
"debugmode = 1\n"\
|
||||||
|
"debugmode_user = 0\n"\
|
||||||
|
"disable_user_exception_handlers = 0\n"\
|
||||||
|
"[stratosphere]\n"
|
||||||
|
|
||||||
static const char *load_config(void) {
|
static const char *load_config(void) {
|
||||||
if (!read_from_file(g_bct0_buffer, BCTO_MAX_SIZE, "atmosphere/BCT.ini")) {
|
if (!read_from_file(g_bct0_buffer, BCTO_MAX_SIZE, "atmosphere/config/BCT.ini")) {
|
||||||
print(SCREEN_LOG_LEVEL_DEBUG, "Failed to read BCT0 from SD!\n");
|
print(SCREEN_LOG_LEVEL_DEBUG, "Failed to read BCT0 from SD!\n");
|
||||||
print(SCREEN_LOG_LEVEL_DEBUG, "Using default BCT0!\n");
|
print(SCREEN_LOG_LEVEL_DEBUG, "Using default BCT0!\n");
|
||||||
memcpy(g_bct0_buffer, DEFAULT_BCT0_FOR_DEBUG, sizeof(DEFAULT_BCT0_FOR_DEBUG));
|
memcpy(g_bct0_buffer, DEFAULT_BCT0, sizeof(DEFAULT_BCT0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(g_bct0_buffer, "BCT0", 4) != 0) {
|
if (memcmp(g_bct0_buffer, "BCT0", 4) != 0) {
|
||||||
fatal_error("Unexpected magic in BCT.ini!\n");
|
fatal_error("Unexpected magic in BCT.ini!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return pointer to first line of the ini. */
|
/* Return pointer to first line of the ini. */
|
||||||
const char *bct0 = g_bct0_buffer;
|
const char *bct0 = g_bct0_buffer;
|
||||||
while (*bct0 && *bct0 != '\n') {
|
while (*bct0 && *bct0 != '\n') {
|
||||||
bct0++;
|
bct0++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bct0) {
|
if (!bct0) {
|
||||||
fatal_error("BCT.ini has no newline!\n");
|
fatal_error("BCT.ini has no newline!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return bct0;
|
return bct0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +92,7 @@ static int config_ini_handler(void *user, const char *section, const char *name,
|
|||||||
|
|
||||||
static void setup_display(void) {
|
static void setup_display(void) {
|
||||||
g_framebuffer = (void *)0xC0000000;
|
g_framebuffer = (void *)0xC0000000;
|
||||||
|
|
||||||
/* Zero-fill the framebuffer and register it as printk provider. */
|
/* Zero-fill the framebuffer and register it as printk provider. */
|
||||||
video_init(g_framebuffer);
|
video_init(g_framebuffer);
|
||||||
|
|
||||||
@@ -105,7 +110,7 @@ static void setup_display(void) {
|
|||||||
static void cleanup_display(void) {
|
static void cleanup_display(void) {
|
||||||
/* Turn off the backlight. */
|
/* Turn off the backlight. */
|
||||||
display_backlight(false);
|
display_backlight(false);
|
||||||
|
|
||||||
/* Terminate the display. */
|
/* Terminate the display. */
|
||||||
display_end();
|
display_end();
|
||||||
}
|
}
|
||||||
@@ -116,7 +121,7 @@ static void setup_env(void) {
|
|||||||
|
|
||||||
/* Set up the exception handlers. */
|
/* Set up the exception handlers. */
|
||||||
setup_exception_handlers();
|
setup_exception_handlers();
|
||||||
|
|
||||||
/* Mount the SD card. */
|
/* Mount the SD card. */
|
||||||
mount_sd();
|
mount_sd();
|
||||||
}
|
}
|
||||||
@@ -137,13 +142,13 @@ int main(void) {
|
|||||||
stage2_args_t *stage2_args;
|
stage2_args_t *stage2_args;
|
||||||
uint32_t stage2_version = 0;
|
uint32_t stage2_version = 0;
|
||||||
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
|
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
|
||||||
|
|
||||||
/* Initialize the boot environment. */
|
/* Initialize the boot environment. */
|
||||||
setup_env();
|
setup_env();
|
||||||
|
|
||||||
/* Check for panics. */
|
/* Check for panics. */
|
||||||
check_and_display_panic();
|
check_and_display_panic();
|
||||||
|
|
||||||
/* Load the BCT0 configuration ini off of the SD. */
|
/* Load the BCT0 configuration ini off of the SD. */
|
||||||
bct0 = load_config();
|
bct0 = load_config();
|
||||||
|
|
||||||
@@ -151,19 +156,19 @@ int main(void) {
|
|||||||
if (ini_parse_string(bct0, config_ini_handler, &log_level) < 0) {
|
if (ini_parse_string(bct0, config_ini_handler, &log_level) < 0) {
|
||||||
fatal_error("Failed to parse BCT.ini!\n");
|
fatal_error("Failed to parse BCT.ini!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Override the global logging level. */
|
/* Override the global logging level. */
|
||||||
log_set_log_level(log_level);
|
log_set_log_level(log_level);
|
||||||
|
|
||||||
if (log_level != SCREEN_LOG_LEVEL_NONE) {
|
if (log_level != SCREEN_LOG_LEVEL_NONE) {
|
||||||
/* Initialize the display for debugging. */
|
/* Initialize the display for debugging. */
|
||||||
setup_display();
|
setup_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Say hello. */
|
/* Say hello. */
|
||||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n");
|
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n");
|
||||||
print(SCREEN_LOG_LEVEL_DEBUG, "Using color linear framebuffer at 0x%p!\n", g_framebuffer);
|
print(SCREEN_LOG_LEVEL_DEBUG, "Using color linear framebuffer at 0x%p!\n", g_framebuffer);
|
||||||
|
|
||||||
/* Load the loader payload into DRAM. */
|
/* Load the loader payload into DRAM. */
|
||||||
load_stage2(bct0);
|
load_stage2(bct0);
|
||||||
|
|
||||||
@@ -175,14 +180,14 @@ int main(void) {
|
|||||||
memcpy(&stage2_args->log_level, &log_level, sizeof(log_level));
|
memcpy(&stage2_args->log_level, &log_level, sizeof(log_level));
|
||||||
strcpy(stage2_args->bct0, bct0);
|
strcpy(stage2_args->bct0, bct0);
|
||||||
g_chainloader_argc = 2;
|
g_chainloader_argc = 2;
|
||||||
|
|
||||||
/* Terminate the boot environment. */
|
/* Terminate the boot environment. */
|
||||||
cleanup_env();
|
cleanup_env();
|
||||||
|
|
||||||
if (log_level != SCREEN_LOG_LEVEL_NONE) {
|
if (log_level != SCREEN_LOG_LEVEL_NONE) {
|
||||||
/* Wait a while for debugging. */
|
/* Wait a while for debugging. */
|
||||||
mdelay(1000);
|
mdelay(1000);
|
||||||
|
|
||||||
/* Terminate the display for debugging. */
|
/* Terminate the display for debugging. */
|
||||||
cleanup_display();
|
cleanup_display();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,13 @@
|
|||||||
#define MC_SMMU_TLB_FLUSH 0x30
|
#define MC_SMMU_TLB_FLUSH 0x30
|
||||||
#define MC_SMMU_PTC_FLUSH 0x34
|
#define MC_SMMU_PTC_FLUSH 0x34
|
||||||
#define MC_SMMU_ASID_SECURITY 0x38
|
#define MC_SMMU_ASID_SECURITY 0x38
|
||||||
|
#define MC_SMMU_ASID_SECURITY_1 0x3c
|
||||||
|
#define MC_SMMU_ASID_SECURITY_2 0x9e0
|
||||||
|
#define MC_SMMU_ASID_SECURITY_3 0x9e4
|
||||||
|
#define MC_SMMU_ASID_SECURITY_4 0x9e8
|
||||||
|
#define MC_SMMU_ASID_SECURITY_5 0x9ec
|
||||||
|
#define MC_SMMU_ASID_SECURITY_6 0x9f0
|
||||||
|
#define MC_SMMU_ASID_SECURITY_7 0x9f4
|
||||||
#define MC_SMMU_AFI_ASID 0x238
|
#define MC_SMMU_AFI_ASID 0x238
|
||||||
#define MC_SMMU_AVPC_ASID 0x23c
|
#define MC_SMMU_AVPC_ASID 0x23c
|
||||||
#define MC_SMMU_TSEC_ASID 0x294
|
#define MC_SMMU_TSEC_ASID 0x294
|
||||||
|
|||||||
@@ -39,20 +39,20 @@ void NOINLINE ll_init(volatile se_ll_t *ll, void *buffer, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void se_check_error_status_reg(void) {
|
void se_check_error_status_reg(void) {
|
||||||
if (se_get_regs()->ERR_STATUS_REG) {
|
if (se_get_regs()->SE_ERR_STATUS) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_check_for_error(void) {
|
void se_check_for_error(void) {
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
volatile tegra_se_t *se = se_get_regs();
|
||||||
if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) {
|
if (se->SE_INT_STATUS & 0x10000 || se->SE_STATUS & 3 || se->SE_ERR_STATUS) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_verify_flags_cleared(void) {
|
void se_verify_flags_cleared(void) {
|
||||||
if (se_get_regs()->FLAGS_REG & 3) {
|
if (se_get_regs()->SE_STATUS & 3) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,12 +67,12 @@ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
|||||||
|
|
||||||
/* Misc flags. */
|
/* Misc flags. */
|
||||||
if (flags & ~0x80) {
|
if (flags & ~0x80) {
|
||||||
se->AES_KEYSLOT_FLAGS[keyslot] = ~flags;
|
se->SE_CRYPTO_KEYTABLE_ACCESS[keyslot] = ~flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable keyslot reads. */
|
/* Disable keyslot reads. */
|
||||||
if (flags & 0x80) {
|
if (flags & 0x80) {
|
||||||
se->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
|
se->SE_CRYPTO_SECURITY_PERKEY &= ~(1 << keyslot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,12 +87,12 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
|||||||
/* Misc flags. */
|
/* Misc flags. */
|
||||||
if (flags & ~0x80) {
|
if (flags & ~0x80) {
|
||||||
/* TODO: Why are flags assigned this way? */
|
/* TODO: Why are flags assigned this way? */
|
||||||
se->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
|
se->SE_RSA_KEYTABLE_ACCESS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable keyslot reads. */
|
/* Disable keyslot reads. */
|
||||||
if (flags & 0x80) {
|
if (flags & 0x80) {
|
||||||
se->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
|
se->SE_RSA_SECURITY_PERKEY &= ~(1 << keyslot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,8 +105,8 @@ void clear_aes_keyslot(unsigned int keyslot) {
|
|||||||
|
|
||||||
/* Zero out the whole keyslot and IV. */
|
/* Zero out the whole keyslot and IV. */
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
for (unsigned int i = 0; i < 0x10; i++) {
|
||||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
|
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
|
||||||
se->AES_KEYTABLE_DATA = 0;
|
se->SE_CRYPTO_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,13 +120,13 @@ void clear_rsa_keyslot(unsigned int keyslot) {
|
|||||||
/* Zero out the whole keyslot. */
|
/* Zero out the whole keyslot. */
|
||||||
for (unsigned int i = 0; i < 0x40; i++) {
|
for (unsigned int i = 0; i < 0x40; i++) {
|
||||||
/* Select Keyslot Modulus[i] */
|
/* Select Keyslot Modulus[i] */
|
||||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
|
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
|
||||||
se->RSA_KEYTABLE_DATA = 0;
|
se->SE_RSA_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < 0x40; i++) {
|
for (unsigned int i = 0; i < 0x40; i++) {
|
||||||
/* Select Keyslot Expontent[i] */
|
/* Select Keyslot Expontent[i] */
|
||||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
||||||
se->RSA_KEYTABLE_DATA = 0;
|
se->SE_RSA_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,8 +138,8 @@ void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (key_size >> 2); i++) {
|
for (size_t i = 0; i < (key_size >> 2); i++) {
|
||||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
|
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | i;
|
||||||
se->AES_KEYTABLE_DATA = read32le(key, 4 * i);
|
se->SE_CRYPTO_KEYTABLE_DATA = read32le(key, 4 * i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,13 +151,13 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (modulus_size >> 2); i++) {
|
for (size_t i = 0; i < (modulus_size >> 2); i++) {
|
||||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i;
|
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i;
|
||||||
se->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4);
|
se->SE_RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (exp_size >> 2); i++) {
|
for (size_t i = 0; i < (exp_size >> 2); i++) {
|
||||||
se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
se->SE_RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
||||||
se->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4);
|
se->SE_RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_se_modulus_sizes[keyslot] = modulus_size;
|
g_se_modulus_sizes[keyslot] = modulus_size;
|
||||||
@@ -172,8 +172,8 @@ void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (iv_size >> 2); i++) {
|
for (size_t i = 0; i < (iv_size >> 2); i++) {
|
||||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
||||||
se->AES_KEYTABLE_DATA = read32le(iv, 4 * i);
|
se->SE_CRYPTO_KEYTABLE_DATA = read32le(iv, 4 * i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,14 +185,14 @@ void clear_aes_keyslot_iv(unsigned int keyslot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (0x10 >> 2); i++) {
|
for (size_t i = 0; i < (0x10 >> 2); i++) {
|
||||||
se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
se->SE_CRYPTO_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
||||||
se->AES_KEYTABLE_DATA = 0;
|
se->SE_CRYPTO_KEYTABLE_DATA = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_se_ctr(const void *ctr) {
|
void set_se_ctr(const void *ctr) {
|
||||||
for (unsigned int i = 0; i < 4; i++) {
|
for (unsigned int i = 0; i < 4; i++) {
|
||||||
se_get_regs()->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4);
|
se_get_regs()->SE_CRYPTO_LINEAR_CTR[i] = read32le(ctr, i * 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,10 +203,10 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr
|
|||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB);
|
se->SE_CONFIG = (ALG_AES_DEC | DST_KEYTAB);
|
||||||
se->CRYPTO_REG = keyslot_src << 24;
|
se->SE_CRYPTO_CONFIG = keyslot_src << 24;
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8;
|
se->SE_CRYPTO_KEYTABLE_DST = keyslot_dst << 8;
|
||||||
|
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size);
|
trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size);
|
||||||
}
|
}
|
||||||
@@ -224,10 +224,10 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co
|
|||||||
stack_buf[i] = *((uint8_t *)src + src_size - i - 1);
|
stack_buf[i] = *((uint8_t *)src + src_size - i - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_RSA | DST_RSAREG);
|
se->SE_CONFIG = (ALG_RSA | DST_RSAREG);
|
||||||
se->RSA_CONFIG = keyslot << 24;
|
se->SE_RSA_CONFIG = keyslot << 24;
|
||||||
se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
|
se->SE_RSA_KEY_SIZE = (g_se_modulus_sizes[keyslot] >> 6) - 1;
|
||||||
se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
|
se->SE_RSA_EXP_SIZE = g_se_exp_sizes[keyslot] >> 2;
|
||||||
|
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size);
|
trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size);
|
||||||
se_get_exp_mod_output(dst, dst_size);
|
se_get_exp_mod_output(dst, dst_size);
|
||||||
@@ -245,7 +245,7 @@ void se_get_exp_mod_output(void *buf, size_t size) {
|
|||||||
|
|
||||||
/* Copy endian swapped output. */
|
/* Copy endian swapped output. */
|
||||||
while (num_dwords) {
|
while (num_dwords) {
|
||||||
*p_out = read32be(se_get_regs()->RSA_OUTPUT, offset);
|
*p_out = read32be(se_get_regs()->SE_RSA_OUTPUT, offset);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
p_out--;
|
p_out--;
|
||||||
num_dwords--;
|
num_dwords--;
|
||||||
@@ -314,15 +314,15 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v
|
|||||||
ll_init(&out_ll, dst, dst_size);
|
ll_init(&out_ll, dst, dst_size);
|
||||||
|
|
||||||
/* Set the LLs. */
|
/* Set the LLs. */
|
||||||
se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll);
|
se->SE_IN_LL_ADDR = (uint32_t) get_physical_address(&in_ll);
|
||||||
se->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll);
|
se->SE_OUT_LL_ADDR = (uint32_t) get_physical_address(&out_ll);
|
||||||
|
|
||||||
/* Set registers for operation. */
|
/* Set registers for operation. */
|
||||||
se->ERR_STATUS_REG = se->ERR_STATUS_REG;
|
se->SE_ERR_STATUS = se->SE_ERR_STATUS;
|
||||||
se->INT_STATUS_REG = se->INT_STATUS_REG;
|
se->SE_INT_STATUS = se->SE_INT_STATUS;
|
||||||
se->OPERATION_REG = op;
|
se->SE_OPERATION = op;
|
||||||
|
|
||||||
while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
|
while (!(se->SE_INT_STATUS & 0x10)) { /* Wait a while */ }
|
||||||
se_check_for_error();
|
se_check_for_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +340,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Trigger AES operation. */
|
/* Trigger AES operation. */
|
||||||
se_get_regs()->BLOCK_COUNT_REG = 0;
|
se_get_regs()->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
|
trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
|
||||||
|
|
||||||
/* Copy output data into dst. */
|
/* Copy output data into dst. */
|
||||||
@@ -358,15 +358,15 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo
|
|||||||
unsigned int num_blocks = src_size >> 4;
|
unsigned int num_blocks = src_size >> 4;
|
||||||
|
|
||||||
/* Unknown what this write does, but official code writes it for CTR mode. */
|
/* Unknown what this write does, but official code writes it for CTR mode. */
|
||||||
se->SPARE_0 = 1;
|
se->SE_SPARE = 1;
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | 0x91E;
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x91E;
|
||||||
set_se_ctr(ctr);
|
set_se_ctr(ctr);
|
||||||
|
|
||||||
/* Handle any aligned blocks. */
|
/* Handle any aligned blocks. */
|
||||||
size_t aligned_size = (size_t)num_blocks << 4;
|
size_t aligned_size = (size_t)num_blocks << 4;
|
||||||
if (aligned_size) {
|
if (aligned_size) {
|
||||||
se->BLOCK_COUNT_REG = num_blocks - 1;
|
se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1;
|
||||||
trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size);
|
trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,8 +388,8 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
|
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
|
||||||
se->CRYPTO_REG = keyslot << 24 | 0x100;
|
se->SE_CRYPTO_CONFIG = keyslot << 24 | 0x100;
|
||||||
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,8 +408,8 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size,
|
|||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
|
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY);
|
||||||
se->CRYPTO_REG = keyslot << 24;
|
se->SE_CRYPTO_CONFIG = keyslot << 24;
|
||||||
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,13 +472,13 @@ void aes_128_xts_nintendo_crypt_sector(unsigned int keyslot_1, unsigned int keys
|
|||||||
|
|
||||||
/* Encrypt/Decrypt. */
|
/* Encrypt/Decrypt. */
|
||||||
if (encrypt) {
|
if (encrypt) {
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY);
|
||||||
se->CRYPTO_REG = keyslot_1 << 24 | 0x100;
|
se->SE_CRYPTO_CONFIG = keyslot_1 << 24 | 0x100;
|
||||||
} else {
|
} else {
|
||||||
se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
|
se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY);
|
||||||
se->CRYPTO_REG = keyslot_1 << 24;
|
se->SE_CRYPTO_CONFIG = keyslot_1 << 24;
|
||||||
}
|
}
|
||||||
se->BLOCK_COUNT_REG = (size >> 4) - 1;
|
se->SE_CRYPTO_LAST_BLOCK = (size >> 4) - 1;
|
||||||
trigger_se_blocking_op(OP_START, dst, size, src, size);
|
trigger_se_blocking_op(OP_START, dst, size, src, size);
|
||||||
|
|
||||||
/* XOR. */
|
/* XOR. */
|
||||||
@@ -524,16 +524,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
|
|||||||
shift_left_xor_rb(derived_key);
|
shift_left_xor_rb(derived_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | (0x145);
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | (0x145);
|
||||||
clear_aes_keyslot_iv(keyslot);
|
clear_aes_keyslot_iv(keyslot);
|
||||||
|
|
||||||
unsigned int num_blocks = (data_size + 0xF) >> 4;
|
unsigned int num_blocks = (data_size + 0xF) >> 4;
|
||||||
/* Handle aligned blocks. */
|
/* Handle aligned blocks. */
|
||||||
if (num_blocks > 1) {
|
if (num_blocks > 1) {
|
||||||
se->BLOCK_COUNT_REG = num_blocks - 2;
|
se->SE_CRYPTO_LAST_BLOCK = num_blocks - 2;
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
|
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
|
||||||
se->CRYPTO_REG |= 0x80;
|
se->SE_CRYPTO_CONFIG |= 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create final block. */
|
/* Create final block. */
|
||||||
@@ -550,12 +550,12 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Perform last operation. */
|
/* Perform last operation. */
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
|
trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
|
||||||
|
|
||||||
/* Copy output CMAC. */
|
/* Copy output CMAC. */
|
||||||
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
|
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
|
||||||
((uint32_t *)cmac)[i] = read32le(se->HASH_RESULT_REG, i << 2);
|
((uint32_t *)cmac)[i] = read32le(se->SE_HASH_RESULT, i << 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,10 +573,10 @@ void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, co
|
|||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16);
|
se->SE_CONFIG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | 0x144;
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x144;
|
||||||
set_aes_keyslot_iv(keyslot, iv, 0x10);
|
set_aes_keyslot_iv(keyslot, iv, 0x10);
|
||||||
se->BLOCK_COUNT_REG = (src_size >> 4) - 1;
|
se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1;
|
||||||
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
|
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,23 +585,23 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
|
|||||||
volatile tegra_se_t *se = se_get_regs();
|
volatile tegra_se_t *se = se_get_regs();
|
||||||
|
|
||||||
/* Setup config for SHA256, size = BITS(src_size) */
|
/* Setup config for SHA256, size = BITS(src_size) */
|
||||||
se->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
|
se->SE_CONFIG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
|
||||||
se->SHA_CONFIG_REG = 1;
|
se->SE_SHA_CONFIG = 1;
|
||||||
se->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3);
|
se->SE_SHA_MSG_LENGTH[0] = (uint32_t)(src_size << 3);
|
||||||
se->_0x208 = 0;
|
se->SE_SHA_MSG_LENGTH[1] = 0;
|
||||||
se->_0x20C = 0;
|
se->SE_SHA_MSG_LENGTH[2] = 0;
|
||||||
se->_0x210 = 0;
|
se->SE_SHA_MSG_LENGTH[3] = 0;
|
||||||
se->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3);
|
se->SE_SHA_MSG_LEFT[0] = (uint32_t)(src_size << 3);
|
||||||
se->_0x218 = 0;
|
se->SE_SHA_MSG_LEFT[1] = 0;
|
||||||
se->_0x21C = 0;
|
se->SE_SHA_MSG_LEFT[2] = 0;
|
||||||
se->_0x220 = 0;
|
se->SE_SHA_MSG_LEFT[3] = 0;
|
||||||
|
|
||||||
/* Trigger the operation. */
|
/* Trigger the operation. */
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, src, src_size);
|
trigger_se_blocking_op(OP_START, NULL, 0, src, src_size);
|
||||||
|
|
||||||
/* Copy output hash. */
|
/* Copy output hash. */
|
||||||
for (unsigned int i = 0; i < (0x20 >> 2); i++) {
|
for (unsigned int i = 0; i < (0x20 >> 2); i++) {
|
||||||
((uint32_t *)dst)[i] = read32be(se->HASH_RESULT_REG, i << 2);
|
((uint32_t *)dst)[i] = read32be(se->SE_HASH_RESULT, i << 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,12 +617,12 @@ void se_initialize_rng(unsigned int keyslot) {
|
|||||||
/* This will be discarded, when done. */
|
/* This will be discarded, when done. */
|
||||||
uint8_t ALIGN(16) output_buf[0x10];
|
uint8_t ALIGN(16) output_buf[0x10];
|
||||||
|
|
||||||
se->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */
|
se->SE_RNG_SRC_CONFIG = 3; /* Entropy enable + Entropy lock enable */
|
||||||
se->RNG_RESEED_INTERVAL_REG = 70001;
|
se->SE_RNG_RESEED_INTERVAL = 70001;
|
||||||
se->CONFIG_REG = (ALG_RNG | DST_MEMORY);
|
se->SE_CONFIG = (ALG_RNG | DST_MEMORY);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | 0x108;
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108;
|
||||||
se->RNG_CONFIG_REG = 5;
|
se->SE_RNG_CONFIG = 5;
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0);
|
trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,12 +635,12 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
|
|||||||
|
|
||||||
uint32_t num_blocks = size >> 4;
|
uint32_t num_blocks = size >> 4;
|
||||||
size_t aligned_size = num_blocks << 4;
|
size_t aligned_size = num_blocks << 4;
|
||||||
se->CONFIG_REG = (ALG_RNG | DST_MEMORY);
|
se->SE_CONFIG = (ALG_RNG | DST_MEMORY);
|
||||||
se->CRYPTO_REG = (keyslot << 24) | 0x108;
|
se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x108;
|
||||||
se->RNG_CONFIG_REG = 4;
|
se->SE_RNG_CONFIG = 4;
|
||||||
|
|
||||||
if (num_blocks >= 1) {
|
if (num_blocks >= 1) {
|
||||||
se->BLOCK_COUNT_REG = num_blocks - 1;
|
se->SE_CRYPTO_LAST_BLOCK = num_blocks - 1;
|
||||||
trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0);
|
trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0);
|
||||||
}
|
}
|
||||||
if (size > aligned_size) {
|
if (size > aligned_size) {
|
||||||
|
|||||||
@@ -92,71 +92,59 @@
|
|||||||
#define RSA_2048_BYTES 0x100
|
#define RSA_2048_BYTES 0x100
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t _0x0;
|
uint32_t SE_SE_SECURITY;
|
||||||
uint32_t _0x4;
|
uint32_t SE_TZRAM_SECURITY;
|
||||||
uint32_t OPERATION_REG;
|
uint32_t SE_OPERATION;
|
||||||
uint32_t INT_ENABLE_REG;
|
uint32_t SE_INT_ENABLE;
|
||||||
uint32_t INT_STATUS_REG;
|
uint32_t SE_INT_STATUS;
|
||||||
uint32_t CONFIG_REG;
|
uint32_t SE_CONFIG;
|
||||||
uint32_t IN_LL_ADDR_REG;
|
uint32_t SE_IN_LL_ADDR;
|
||||||
uint32_t _0x1C;
|
uint32_t SE_IN_CUR_BYTE_ADDR;
|
||||||
uint32_t _0x20;
|
uint32_t SE_IN_CUR_LL_ID;
|
||||||
uint32_t OUT_LL_ADDR_REG;
|
uint32_t SE_OUT_LL_ADDR;
|
||||||
uint32_t _0x28;
|
uint32_t SE_OUT_CUR_BYTE_ADDR;
|
||||||
uint32_t _0x2C;
|
uint32_t SE_OUT_CUR_LL_ID;
|
||||||
uint8_t HASH_RESULT_REG[0x20];
|
uint32_t SE_HASH_RESULT[0x10];
|
||||||
uint8_t _0x50[0x20];
|
uint32_t SE_CTX_SAVE_CONFIG;
|
||||||
uint32_t CONTEXT_SAVE_CONFIG_REG;
|
uint32_t _0x74[0x63];
|
||||||
uint8_t _0x74[0x18C];
|
uint32_t SE_SHA_CONFIG;
|
||||||
uint32_t SHA_CONFIG_REG;
|
uint32_t SE_SHA_MSG_LENGTH[0x4];
|
||||||
uint32_t SHA_MSG_LENGTH_REG;
|
uint32_t SE_SHA_MSG_LEFT[0x4];
|
||||||
uint32_t _0x208;
|
uint32_t _0x224[0x17];
|
||||||
uint32_t _0x20C;
|
uint32_t SE_CRYPTO_SECURITY_PERKEY;
|
||||||
uint32_t _0x210;
|
uint32_t SE_CRYPTO_KEYTABLE_ACCESS[0x10];
|
||||||
uint32_t SHA_MSG_LEFT_REG;
|
uint32_t _0x2C4[0x10];
|
||||||
uint32_t _0x218;
|
uint32_t SE_CRYPTO_CONFIG;
|
||||||
uint32_t _0x21C;
|
uint32_t SE_CRYPTO_LINEAR_CTR[0x4];
|
||||||
uint32_t _0x220;
|
uint32_t SE_CRYPTO_LAST_BLOCK;
|
||||||
uint32_t _0x224;
|
uint32_t SE_CRYPTO_KEYTABLE_ADDR;
|
||||||
uint8_t _0x228[0x58];
|
uint32_t SE_CRYPTO_KEYTABLE_DATA;
|
||||||
uint32_t AES_KEY_READ_DISABLE_REG;
|
uint32_t _0x324[0x3];
|
||||||
uint32_t AES_KEYSLOT_FLAGS[0x10];
|
uint32_t SE_CRYPTO_KEYTABLE_DST;
|
||||||
uint8_t _0x2C4[0x3C];
|
uint32_t _0x334[0x3];
|
||||||
uint32_t _0x300;
|
uint32_t SE_RNG_CONFIG;
|
||||||
uint32_t CRYPTO_REG;
|
uint32_t SE_RNG_SRC_CONFIG;
|
||||||
uint32_t CRYPTO_CTR_REG[4];
|
uint32_t SE_RNG_RESEED_INTERVAL;
|
||||||
uint32_t BLOCK_COUNT_REG;
|
uint32_t _0x34C[0x2D];
|
||||||
uint32_t AES_KEYTABLE_ADDR;
|
uint32_t SE_RSA_CONFIG;
|
||||||
uint32_t AES_KEYTABLE_DATA;
|
uint32_t SE_RSA_KEY_SIZE;
|
||||||
uint32_t _0x324;
|
uint32_t SE_RSA_EXP_SIZE;
|
||||||
uint32_t _0x328;
|
uint32_t SE_RSA_SECURITY_PERKEY;
|
||||||
uint32_t _0x32C;
|
uint32_t SE_RSA_KEYTABLE_ACCESS[0x2];
|
||||||
uint32_t CRYPTO_KEYTABLE_DST_REG;
|
uint32_t _0x418[0x2];
|
||||||
uint8_t _0x334[0xC];
|
uint32_t SE_RSA_KEYTABLE_ADDR;
|
||||||
uint32_t RNG_CONFIG_REG;
|
uint32_t SE_RSA_KEYTABLE_DATA;
|
||||||
uint32_t RNG_SRC_CONFIG_REG;
|
uint32_t SE_RSA_OUTPUT[0x40];
|
||||||
uint32_t RNG_RESEED_INTERVAL_REG;
|
uint32_t _0x528[0xB6];
|
||||||
uint8_t _0x34C[0xB4];
|
uint32_t SE_STATUS;
|
||||||
uint32_t RSA_CONFIG;
|
uint32_t SE_ERR_STATUS;
|
||||||
uint32_t RSA_KEY_SIZE_REG;
|
uint32_t SE_MISC;
|
||||||
uint32_t RSA_EXP_SIZE_REG;
|
uint32_t SE_SPARE;
|
||||||
uint32_t RSA_KEY_READ_DISABLE_REG;
|
uint32_t SE_ENTROPY_DEBUG_COUNTER;
|
||||||
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 _0x814;
|
||||||
uint32_t _0x818;
|
uint32_t _0x818;
|
||||||
uint32_t _0x81C;
|
uint32_t _0x81C;
|
||||||
uint8_t _0x820[0x17E0];
|
uint32_t _0x820[0x5F8];
|
||||||
} tegra_se_t;
|
} tegra_se_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ TARGET := $(notdir $(CURDIR))
|
|||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := src src/sdmmc src/lib src/lib/fatfs src/display
|
SOURCES := src src/sdmmc src/lib src/lib/fatfs src/display
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include ../../common/include
|
INCLUDES := include ../../libraries/libvapours/include
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
@@ -89,7 +89,7 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|||||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
||||||
$(AMS)/exosphere $(AMS)/exosphere/lp0fw $(AMS)/exosphere/rebootstub \
|
$(AMS)/exosphere $(AMS)/exosphere/lp0fw $(AMS)/exosphere/rebootstub \
|
||||||
$(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/sept/sept-primary \
|
$(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/sept/sept-primary \
|
||||||
$(AMS)/sept/sept-secondary $(AMS)/emummc $(KIPDIRS)
|
$(AMS)/sept/sept-secondary $(AMS)/emummc $(AMS)/mesosphere/kernel_ldr $(KIPDIRS)
|
||||||
|
|
||||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ KIPFILES := loader.kip pm.kip sm.kip ams_mitm.kip spl.kip boot.kip
|
|||||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin \
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin \
|
||||||
exosphere.bin lp0fw.bin rebootstub.bin thermosphere.bin splash_screen.bmp \
|
exosphere.bin lp0fw.bin rebootstub.bin thermosphere.bin splash_screen.bmp \
|
||||||
sept-primary.bin sept-secondary_00.enc sept-secondary_01.enc emummc.kip \
|
sept-primary.bin sept-secondary_00.enc sept-secondary_01.enc emummc.kip \
|
||||||
$(KIPFILES)
|
kernel_ldr.bin $(KIPFILES)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# use CXX for linking C++ projects, CC for standard C
|
# use CXX for linking C++ projects, CC for standard C
|
||||||
@@ -128,7 +128,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
|||||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||||
|
|
||||||
.PHONY: $(BUILD) clean all
|
.PHONY: $(BUILD) clean all
|
||||||
.PHONY: check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_stratosphere
|
.PHONY: check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_stratosphere check_libraries
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
all: $(BUILD)
|
all: $(BUILD)
|
||||||
@@ -148,11 +148,17 @@ check_emummc:
|
|||||||
check_thermosphere:
|
check_thermosphere:
|
||||||
@$(MAKE) -C $(AMS)/thermosphere all
|
@$(MAKE) -C $(AMS)/thermosphere all
|
||||||
|
|
||||||
check_stratosphere:
|
check_stratosphere: check_libraries
|
||||||
@$(MAKE) -C $(AMS)/stratosphere all
|
@$(MAKE) -C $(AMS)/stratosphere all
|
||||||
|
|
||||||
|
check_mesosphere: check_libraries
|
||||||
|
@$(MAKE) -C $(AMS)/mesosphere all
|
||||||
|
|
||||||
$(BUILD): check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_stratosphere
|
check_libraries:
|
||||||
|
@$(MAKE) -C $(AMS)/libraries all
|
||||||
|
|
||||||
|
|
||||||
|
$(BUILD): check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_libraries check_stratosphere check_mesosphere
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
@@ -162,6 +168,8 @@ clean:
|
|||||||
@$(MAKE) -C $(AMS)/fusee/fusee-primary clean
|
@$(MAKE) -C $(AMS)/fusee/fusee-primary clean
|
||||||
@$(MAKE) -C $(AMS)/exosphere clean
|
@$(MAKE) -C $(AMS)/exosphere clean
|
||||||
@$(MAKE) -C $(AMS)/thermosphere clean
|
@$(MAKE) -C $(AMS)/thermosphere clean
|
||||||
|
@$(MAKE) -C $(AMS)/libraries clean
|
||||||
|
@$(MAKE) -C $(AMS)/mesosphere clean
|
||||||
@$(MAKE) -C $(AMS)/stratosphere clean
|
@$(MAKE) -C $(AMS)/stratosphere clean
|
||||||
@$(MAKE) -C $(AMS)/sept clean
|
@$(MAKE) -C $(AMS)/sept clean
|
||||||
@$(MAKE) -C $(AMS)/emummc clean
|
@$(MAKE) -C $(AMS)/emummc clean
|
||||||
|
|||||||
@@ -250,4 +250,6 @@ SECTIONS
|
|||||||
PROVIDE(__thermosphere_bin_size__ = thermosphere_bin_end - thermosphere_bin);
|
PROVIDE(__thermosphere_bin_size__ = thermosphere_bin_end - thermosphere_bin);
|
||||||
PROVIDE(__emummc_kip_start__ = emummc_kip - __start__);
|
PROVIDE(__emummc_kip_start__ = emummc_kip - __start__);
|
||||||
PROVIDE(__emummc_kip_size__ = emummc_kip_end - emummc_kip);
|
PROVIDE(__emummc_kip_size__ = emummc_kip_end - emummc_kip);
|
||||||
|
PROVIDE(__kernel_ldr_bin_start__ = kernel_ldr_bin - __start__);
|
||||||
|
PROVIDE(__kernel_ldr_bin_size__ = kernel_ldr_bin_end - kernel_ldr_bin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#define EXOSPHERE_EMUMMC_CONFIG_H
|
#define EXOSPHERE_EMUMMC_CONFIG_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <atmosphere.h>
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
/* "EFS0" */
|
/* "EFS0" */
|
||||||
#define MAGIC_EMUMMC_CONFIG (0x30534645)
|
#define MAGIC_EMUMMC_CONFIG (0x30534645)
|
||||||
@@ -76,6 +76,12 @@ typedef enum {
|
|||||||
FS_VER_8_1_0,
|
FS_VER_8_1_0,
|
||||||
FS_VER_8_1_0_EXFAT,
|
FS_VER_8_1_0_EXFAT,
|
||||||
|
|
||||||
|
FS_VER_9_0_0,
|
||||||
|
FS_VER_9_0_0_EXFAT,
|
||||||
|
|
||||||
|
FS_VER_9_1_0,
|
||||||
|
FS_VER_9_1_0_EXFAT,
|
||||||
|
|
||||||
FS_VER_MAX,
|
FS_VER_MAX,
|
||||||
} emummc_fs_ver_t;
|
} emummc_fs_ver_t;
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,12 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_EXOSPHERE_CONFIG_H
|
#ifndef FUSEE_EXOSPHERE_CONFIG_H
|
||||||
#define FUSEE_EXOSPHERE_CONFIG_H
|
#define FUSEE_EXOSPHERE_CONFIG_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <atmosphere.h>
|
#include <vapours/ams_version.h>
|
||||||
#include "emummc_cfg.h"
|
#include "emummc_cfg.h"
|
||||||
|
|
||||||
/* This serves to set configuration for *exosphere itself*, separate from the SecMon Exosphere mimics. */
|
/* This serves to set configuration for *exosphere itself*, separate from the SecMon Exosphere mimics. */
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
|
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
|
||||||
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
|
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
|
||||||
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
|
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
|
||||||
|
#define EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS (1 << 4u)
|
||||||
#define EXOSPHERE_FLAGS_DEFAULT (EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV)
|
#define EXOSPHERE_FLAGS_DEFAULT (EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -48,5 +49,6 @@ _Static_assert(sizeof(exosphere_config_t) == 0x20 + sizeof(exo_emummc_config_t),
|
|||||||
#define EXOSPHERE_DEBUGMODE_PRIV_KEY "debugmode"
|
#define EXOSPHERE_DEBUGMODE_PRIV_KEY "debugmode"
|
||||||
#define EXOSPHERE_DEBUGMODE_USER_KEY "debugmode_user"
|
#define EXOSPHERE_DEBUGMODE_USER_KEY "debugmode_user"
|
||||||
#define EXOSPHERE_DISABLE_USERMODE_EXCEPTION_HANDLERS_KEY "disable_user_exception_handlers"
|
#define EXOSPHERE_DISABLE_USERMODE_EXCEPTION_HANDLERS_KEY "disable_user_exception_handlers"
|
||||||
|
#define EXOSPHERE_ENABLE_USERMODE_PMU_ACCESS_KEY "enable_user_pmu_access"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -13,171 +13,178 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vapours/ams_version.h>
|
||||||
|
|
||||||
#include "car.h"
|
#include "car.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
#include "pmc.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
|
|
||||||
/* Prototypes for internal commands. */
|
/* Prototypes for internal commands. */
|
||||||
void fuse_make_regs_visible(void);
|
|
||||||
|
|
||||||
void fuse_enable_power(void);
|
void fuse_enable_power(void);
|
||||||
void fuse_disable_power(void);
|
void fuse_disable_power(void);
|
||||||
void fuse_wait_idle(void);
|
void fuse_wait_idle(void);
|
||||||
|
|
||||||
/* Initialize the fuse driver */
|
/* Initialize the fuse driver */
|
||||||
void fuse_init(void) {
|
void fuse_init(void) {
|
||||||
fuse_make_regs_visible();
|
/* Make all fuse registers visible, disable the private key and disable programming. */
|
||||||
fuse_secondary_private_key_disable();
|
|
||||||
fuse_disable_programming();
|
|
||||||
|
|
||||||
/* TODO: Overrides (iROM patches) and various reads happen here */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make all fuse registers visible */
|
|
||||||
void fuse_make_regs_visible(void) {
|
|
||||||
clkrst_enable_fuse_regs(true);
|
clkrst_enable_fuse_regs(true);
|
||||||
|
fuse_disable_private_key();
|
||||||
|
fuse_disable_programming();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable power to the fuse hardware array */
|
/* Disable access to the private key and set the TZ sticky bit. */
|
||||||
|
void fuse_disable_private_key(void) {
|
||||||
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
fuse->FUSE_PRIVATEKEYDISABLE = 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disables all fuse programming. */
|
||||||
|
void fuse_disable_programming(void) {
|
||||||
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
fuse->FUSE_DISABLEREGPROGRAM = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable power to the fuse hardware array. */
|
||||||
void fuse_enable_power(void) {
|
void fuse_enable_power(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||||
fuse->FUSE_PWR_GOOD_SW = 1;
|
pmc->fuse_control &= ~(0x200); /* Clear PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
|
||||||
udelay(1);
|
mdelay(1);
|
||||||
|
pmc->fuse_control |= 0x100; /* Set PMC_FUSE_CTRL_PS18_LATCH_SET. */
|
||||||
|
mdelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable power to the fuse hardware array */
|
/* Disable power to the fuse hardware array. */
|
||||||
void fuse_disable_power(void) {
|
void fuse_disable_power(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_pmc_t *pmc = pmc_get_regs();
|
||||||
fuse->FUSE_PWR_GOOD_SW = 0;
|
pmc->fuse_control &= ~(0x100); /* Clear PMC_FUSE_CTRL_PS18_LATCH_SET. */
|
||||||
udelay(1);
|
mdelay(1);
|
||||||
|
pmc->fuse_control |= 0x200; /* Set PMC_FUSE_CTRL_PS18_LATCH_CLEAR. */
|
||||||
|
mdelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for the fuse driver to go idle */
|
/* Wait for the fuse driver to go idle. */
|
||||||
void fuse_wait_idle(void) {
|
void fuse_wait_idle(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
uint32_t ctrl_val = 0;
|
uint32_t ctrl_val = 0;
|
||||||
|
|
||||||
/* Wait for STATE_IDLE */
|
/* Wait for STATE_IDLE */
|
||||||
while ((ctrl_val & (0xF0000)) != 0x40000)
|
while ((ctrl_val & (0xF0000)) != 0x40000)
|
||||||
{
|
ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
udelay(1);
|
|
||||||
ctrl_val = fuse->FUSE_CTRL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a fuse from the hardware array */
|
/* Read a fuse from the hardware array. */
|
||||||
uint32_t fuse_hw_read(uint32_t addr) {
|
uint32_t fuse_hw_read(uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
/* Program the target address */
|
/* Program the target address. */
|
||||||
fuse->FUSE_REG_ADDR = addr;
|
fuse->FUSE_FUSEADDR = addr;
|
||||||
|
|
||||||
/* Enable read operation in control register */
|
/* Enable read operation in control register. */
|
||||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x1; /* Set FUSE_READ command */
|
ctrl_val |= 0x1; /* Set READ command. */
|
||||||
fuse->FUSE_CTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
return fuse->FUSE_REG_READ;
|
return fuse->FUSE_FUSERDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write a fuse in the hardware array */
|
/* Write a fuse in the hardware array. */
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
/* Program the target address and value */
|
/* Program the target address and value. */
|
||||||
fuse->FUSE_REG_ADDR = addr;
|
fuse->FUSE_FUSEADDR = addr;
|
||||||
fuse->FUSE_REG_WRITE = value;
|
fuse->FUSE_FUSEWDATA = value;
|
||||||
|
|
||||||
/* Enable write operation in control register */
|
/* Enable write operation in control register. */
|
||||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x2; /* Set FUSE_WRITE command */
|
ctrl_val |= 0x2; /* Set WRITE command. */
|
||||||
fuse->FUSE_CTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sense the fuse hardware array into the shadow cache */
|
/* Sense the fuse hardware array into the shadow cache. */
|
||||||
void fuse_hw_sense(void) {
|
void fuse_hw_sense(void) {
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
|
|
||||||
/* Enable sense operation in control register */
|
/* Enable sense operation in control register */
|
||||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
uint32_t ctrl_val = fuse->FUSE_FUSECTRL;
|
||||||
ctrl_val &= ~0x3;
|
ctrl_val &= ~0x3;
|
||||||
ctrl_val |= 0x3; /* Set FUSE_SENSE command */
|
ctrl_val |= 0x3; /* Set SENSE_CTRL command */
|
||||||
fuse->FUSE_CTRL = ctrl_val;
|
fuse->FUSE_FUSECTRL = ctrl_val;
|
||||||
|
|
||||||
|
/* Wait for idle state. */
|
||||||
fuse_wait_idle();
|
fuse_wait_idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disables all fuse programming. */
|
/* Read the SKU info register from the shadow cache. */
|
||||||
void fuse_disable_programming(void) {
|
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
|
||||||
fuse->FUSE_DIS_PGM = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */
|
|
||||||
void fuse_secondary_private_key_disable(void) {
|
|
||||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
|
||||||
fuse->FUSE_PRIVATEKEYDISABLE = 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Read the SKU info register from the shadow cache */
|
|
||||||
uint32_t fuse_get_sku_info(void) {
|
uint32_t fuse_get_sku_info(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
return fuse_chip->FUSE_SKU_INFO;
|
return fuse_chip->FUSE_SKU_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the bootrom patch version from a register in the shadow cache */
|
/* Read the bootrom patch version from a register in the shadow cache. */
|
||||||
uint32_t fuse_get_bootrom_patch_version(void) {
|
uint32_t fuse_get_bootrom_patch_version(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
return fuse_chip->FUSE_SOC_SPEEDO_1;
|
return fuse_chip->FUSE_SOC_SPEEDO_1_CALIB;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a spare bit register from the shadow cache */
|
/* Read a spare bit register from the shadow cache */
|
||||||
uint32_t fuse_get_spare_bit(uint32_t idx) {
|
uint32_t fuse_get_spare_bit(uint32_t idx) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
if (idx < 32) {
|
||||||
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (idx >= 32) {
|
return fuse_chip->FUSE_SPARE_BIT[idx];
|
||||||
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fuse_chip->FUSE_SPARE_BIT[idx];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a reserved ODM register from the shadow cache */
|
/* Read a reserved ODM register from the shadow cache. */
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t idx) {
|
uint32_t fuse_get_reserved_odm(uint32_t idx) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
if (idx < 8) {
|
||||||
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
if (idx >= 8) {
|
return fuse_chip->FUSE_RESERVED_ODM[idx];
|
||||||
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fuse_chip->FUSE_RESERVED_ODM[idx];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Device ID using values in the shadow cache */
|
/* Get the DRAM ID using values in the shadow cache. */
|
||||||
|
uint32_t fuse_get_dram_id(void) {
|
||||||
|
return ((fuse_get_reserved_odm(4) >> 3) & 0x7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Derive the Device ID using values in the shadow cache. */
|
||||||
uint64_t fuse_get_device_id(void) {
|
uint64_t fuse_get_device_id(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
|
|
||||||
uint64_t device_id = 0;
|
uint64_t device_id = 0;
|
||||||
uint64_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
|
uint64_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint64_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
|
uint64_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint64_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
|
uint64_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code = fuse_chip->FUSE_LOT_CODE_0;
|
uint32_t lot_code = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
||||||
uint64_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
|
uint64_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
|
|
||||||
uint64_t derived_lot_code = 0;
|
uint64_t derived_lot_code = 0;
|
||||||
for (unsigned int i = 0; i < 5; i++) {
|
for (unsigned int i = 0; i < 5; i++) {
|
||||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||||
@@ -189,45 +196,41 @@ uint64_t fuse_get_device_id(void) {
|
|||||||
device_id |= wafer_id << 18;
|
device_id |= wafer_id << 18;
|
||||||
device_id |= derived_lot_code << 24;
|
device_id |= derived_lot_code << 24;
|
||||||
device_id |= fab_code << 50;
|
device_id |= fab_code << 50;
|
||||||
|
|
||||||
return device_id;
|
return device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the DRAM ID using values in the shadow cache */
|
/* Derive the Hardware Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_dram_id(void) {
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
return (fuse_chip->FUSE_RESERVED_ODM[4] >> 3) & 0x7;
|
uint32_t hardware_type = (((fuse_reserved_odm4 >> 7) & 2) | ((fuse_reserved_odm4 >> 2) & 1));
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive the Hardware Type using values in the shadow cache */
|
/* Firmware from versions 1.0.0 to 3.0.2. */
|
||||||
uint32_t fuse_get_hardware_type(void) {
|
if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
|
|
||||||
/* This function is very different between 4.x and < 4.x */
|
|
||||||
uint32_t hardware_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((fuse_chip->FUSE_RESERVED_ODM[4] >> 2) & 1);
|
|
||||||
|
|
||||||
/* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) {
|
|
||||||
static const uint32_t types[] = {0,1,4,3};
|
|
||||||
|
|
||||||
hardware_type |= (fuse_chip->FUSE_RESERVED_ODM[4] >> 14) & 0x3C;
|
|
||||||
hardware_type--;
|
|
||||||
return hardware_type > 3 ? 4 : types[hardware_type];
|
|
||||||
} else {*/
|
|
||||||
if (hardware_type >= 1) {
|
if (hardware_type >= 1) {
|
||||||
return hardware_type > 2 ? 3 : hardware_type - 1;
|
return (hardware_type > 2) ? 3 : hardware_type - 1;
|
||||||
} else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) {
|
} else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
// }
|
} else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) { /* Firmware versions from 4.0.0 to 6.2.0. */
|
||||||
|
static const uint32_t types[] = {0,1,4,3};
|
||||||
|
hardware_type |= ((fuse_reserved_odm4 >> 14) & 0x3C);
|
||||||
|
hardware_type--;
|
||||||
|
return (hardware_type > 3) ? 4 : types[hardware_type];
|
||||||
|
} else { /* Firmware versions from 7.0.0 onwards. */
|
||||||
|
/* Always return 0 in retail. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Retail Type using values in the shadow cache */
|
/* Derive the Retail Type using values in the shadow cache. */
|
||||||
uint32_t fuse_get_retail_type(void) {
|
uint32_t fuse_get_retail_type(void) {
|
||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
/* Retail Type = IS_RETAIL | UNIT_TYPE. */
|
||||||
|
uint32_t fuse_reserved_odm4 = fuse_get_reserved_odm(4);
|
||||||
/* Retail type = IS_RETAIL | UNIT_TYPE */
|
uint32_t retail_type = (((fuse_reserved_odm4 >> 7) & 4) | (fuse_reserved_odm4 & 3));
|
||||||
uint32_t retail_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 4) | (fuse_chip->FUSE_RESERVED_ODM[4] & 3);
|
|
||||||
if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */
|
if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */
|
||||||
return 1;
|
return 1;
|
||||||
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
|
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
|
||||||
@@ -241,17 +244,17 @@ void fuse_get_hardware_info(void *dst) {
|
|||||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||||
uint32_t hw_info[0x4];
|
uint32_t hw_info[0x4];
|
||||||
|
|
||||||
uint32_t unk_hw_fuse = fuse_chip->_0x120 & 0x3F;
|
uint32_t ops_reserved = fuse_chip->FUSE_OPT_OPS_RESERVED & 0x3F;
|
||||||
uint32_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
|
uint32_t y_coord = fuse_chip->FUSE_OPT_Y_COORDINATE & 0x1FF;
|
||||||
uint32_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
|
uint32_t x_coord = fuse_chip->FUSE_OPT_X_COORDINATE & 0x1FF;
|
||||||
uint32_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
|
uint32_t wafer_id = fuse_chip->FUSE_OPT_WAFER_ID & 0x3F;
|
||||||
uint32_t lot_code_0 = fuse_chip->FUSE_LOT_CODE_0;
|
uint32_t lot_code_0 = fuse_chip->FUSE_OPT_LOT_CODE_0;
|
||||||
uint32_t lot_code_1 = fuse_chip->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
|
uint32_t lot_code_1 = fuse_chip->FUSE_OPT_LOT_CODE_1 & 0x0FFFFFFF;
|
||||||
uint32_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
|
uint32_t fab_code = fuse_chip->FUSE_OPT_FAB_CODE & 0x3F;
|
||||||
uint32_t vendor_code = fuse_chip->FUSE_VENDOR_CODE & 0xF;
|
uint32_t vendor_code = fuse_chip->FUSE_OPT_VENDOR_CODE & 0xF;
|
||||||
|
|
||||||
/* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
|
/* Hardware Info = OPS_RESERVED || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
|
||||||
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse));
|
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (ops_reserved));
|
||||||
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
|
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
|
||||||
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
|
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
|
||||||
hw_info[3] = (uint32_t)(vendor_code);
|
hw_info[3] = (uint32_t)(vendor_code);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FUSEE_FUSE_H
|
#ifndef FUSEE_FUSE_H
|
||||||
#define FUSEE_FUSE_H
|
#define FUSEE_FUSE_H
|
||||||
|
|
||||||
@@ -23,154 +23,167 @@
|
|||||||
#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
|
#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t FUSE_CTRL;
|
uint32_t FUSE_FUSECTRL;
|
||||||
uint32_t FUSE_REG_ADDR;
|
uint32_t FUSE_FUSEADDR;
|
||||||
uint32_t FUSE_REG_READ;
|
uint32_t FUSE_FUSERDATA;
|
||||||
uint32_t FUSE_REG_WRITE;
|
uint32_t FUSE_FUSEWDATA;
|
||||||
uint32_t FUSE_TIME_RD1;
|
uint32_t FUSE_FUSETIME_RD1;
|
||||||
uint32_t FUSE_TIME_RD2;
|
uint32_t FUSE_FUSETIME_RD2;
|
||||||
uint32_t FUSE_TIME_PGM1;
|
uint32_t FUSE_FUSETIME_PGM1;
|
||||||
uint32_t FUSE_TIME_PGM2;
|
uint32_t FUSE_FUSETIME_PGM2;
|
||||||
uint32_t FUSE_PRIV2INTFC;
|
uint32_t FUSE_PRIV2INTFC_START;
|
||||||
uint32_t FUSE_FUSEBYPASS;
|
uint32_t FUSE_FUSEBYPASS;
|
||||||
uint32_t FUSE_PRIVATEKEYDISABLE;
|
uint32_t FUSE_PRIVATEKEYDISABLE;
|
||||||
uint32_t FUSE_DIS_PGM;
|
uint32_t FUSE_DISABLEREGPROGRAM;
|
||||||
uint32_t FUSE_WRITE_ACCESS;
|
uint32_t FUSE_WRITE_ACCESS_SW;
|
||||||
uint32_t FUSE_PWR_GOOD_SW;
|
uint32_t FUSE_PWR_GOOD_SW;
|
||||||
uint32_t _0x38[0x32];
|
uint32_t _0x38;
|
||||||
|
uint32_t FUSE_PRIV2RESHIFT;
|
||||||
|
uint32_t _0x40[0x3];
|
||||||
|
uint32_t FUSE_FUSETIME_RD3;
|
||||||
|
uint32_t _0x50[0xC];
|
||||||
|
uint32_t FUSE_PRIVATE_KEY0_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY1_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY2_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY3_NONZERO;
|
||||||
|
uint32_t FUSE_PRIVATE_KEY4_NONZERO;
|
||||||
|
uint32_t _0x90[0x1C];
|
||||||
} tegra_fuse_t;
|
} tegra_fuse_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t FUSE_PRODUCTION_MODE;
|
uint32_t FUSE_PRODUCTION_MODE;
|
||||||
uint32_t _0x4;
|
uint32_t FUSE_JTAG_SECUREID_VALID;
|
||||||
uint32_t _0x8;
|
uint32_t FUSE_ODM_LOCK;
|
||||||
uint32_t _0xC;
|
uint32_t FUSE_OPT_OPENGL_EN;
|
||||||
uint32_t FUSE_SKU_INFO;
|
uint32_t FUSE_SKU_INFO;
|
||||||
uint32_t FUSE_CPU_SPEEDO_0;
|
uint32_t FUSE_CPU_SPEEDO_0_CALIB;
|
||||||
uint32_t FUSE_CPU_IDDQ;
|
uint32_t FUSE_CPU_IDDQ_CALIB;
|
||||||
uint32_t _0x1C;
|
uint32_t FUSE_DAC_CRT_CALIB;
|
||||||
uint32_t _0x20;
|
uint32_t FUSE_DAC_HDTV_CALIB;
|
||||||
uint32_t _0x24;
|
uint32_t FUSE_DAC_SDTV_CALIB;
|
||||||
uint32_t FUSE_FT_REV;
|
uint32_t FUSE_OPT_FT_REV;
|
||||||
uint32_t FUSE_CPU_SPEEDO_1;
|
uint32_t FUSE_CPU_SPEEDO_1_CALIB;
|
||||||
uint32_t FUSE_CPU_SPEEDO_2;
|
uint32_t FUSE_CPU_SPEEDO_2_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_0;
|
uint32_t FUSE_SOC_SPEEDO_0_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_1;
|
uint32_t FUSE_SOC_SPEEDO_1_CALIB;
|
||||||
uint32_t FUSE_SOC_SPEEDO_2;
|
uint32_t FUSE_SOC_SPEEDO_2_CALIB;
|
||||||
uint32_t FUSE_SOC_IDDQ;
|
uint32_t FUSE_SOC_IDDQ_CALIB;
|
||||||
uint32_t _0x44;
|
uint32_t FUSE_RESERVED_PRODUCTION_WP;
|
||||||
uint32_t FUSE_FA;
|
uint32_t FUSE_FA;
|
||||||
uint32_t _0x4C;
|
uint32_t FUSE_RESERVED_PRODUCTION;
|
||||||
uint32_t _0x50;
|
uint32_t FUSE_HDMI_LANE0_CALIB;
|
||||||
uint32_t _0x54;
|
uint32_t FUSE_HDMI_LANE1_CALIB;
|
||||||
uint32_t _0x58;
|
uint32_t FUSE_HDMI_LANE2_CALIB;
|
||||||
uint32_t _0x5C;
|
uint32_t FUSE_HDMI_LANE3_CALIB;
|
||||||
uint32_t _0x60;
|
uint32_t FUSE_ENCRYPTION_RATE;
|
||||||
uint32_t FUSE_PUBLIC_KEY[0x8];
|
uint32_t FUSE_PUBLIC_KEY[0x8];
|
||||||
uint32_t FUSE_TSENSOR_1;
|
uint32_t FUSE_TSENSOR1_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_2;
|
uint32_t FUSE_TSENSOR2_CALIB;
|
||||||
uint32_t _0x8C;
|
uint32_t FUSE_VSENSOR_CALIB;
|
||||||
uint32_t FUSE_CP_REV;
|
uint32_t FUSE_OPT_CP_REV;
|
||||||
uint32_t _0x94;
|
uint32_t FUSE_OPT_PFG;
|
||||||
uint32_t FUSE_TSENSOR_0;
|
uint32_t FUSE_TSENSOR0_CALIB;
|
||||||
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG;
|
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE;
|
||||||
uint32_t FUSE_SECURITY_MODE;
|
uint32_t FUSE_SECURITY_MODE;
|
||||||
uint32_t FUSE_PRIVATE_KEY[0x4];
|
uint32_t FUSE_PRIVATE_KEY[0x5];
|
||||||
uint32_t FUSE_DEVICE_KEY;
|
uint32_t FUSE_ARM_JTAG_DIS;
|
||||||
uint32_t _0xB8;
|
uint32_t FUSE_BOOT_DEVICE_INFO;
|
||||||
uint32_t _0xBC;
|
|
||||||
uint32_t FUSE_RESERVED_SW;
|
uint32_t FUSE_RESERVED_SW;
|
||||||
uint32_t FUSE_VP8_ENABLE;
|
uint32_t FUSE_OPT_VP9_DISABLE;
|
||||||
uint32_t FUSE_RESERVED_ODM[0x8];
|
uint32_t FUSE_RESERVED_ODM[0x8];
|
||||||
uint32_t _0xE8;
|
uint32_t FUSE_OBS_DIS;
|
||||||
uint32_t _0xEC;
|
uint32_t FUSE_NOR_INFO;
|
||||||
uint32_t FUSE_SKU_USB_CALIB;
|
uint32_t FUSE_USB_CALIB;
|
||||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
||||||
uint32_t _0xF8;
|
uint32_t FUSE_KFUSE_PRIVKEY_CTRL;
|
||||||
uint32_t _0xFC;
|
uint32_t FUSE_PACKAGE_INFO;
|
||||||
uint32_t FUSE_VENDOR_CODE;
|
uint32_t FUSE_OPT_VENDOR_CODE;
|
||||||
uint32_t FUSE_FAB_CODE;
|
uint32_t FUSE_OPT_FAB_CODE;
|
||||||
uint32_t FUSE_LOT_CODE_0;
|
uint32_t FUSE_OPT_LOT_CODE_0;
|
||||||
uint32_t FUSE_LOT_CODE_1;
|
uint32_t FUSE_OPT_LOT_CODE_1;
|
||||||
uint32_t FUSE_WAFER_ID;
|
uint32_t FUSE_OPT_WAFER_ID;
|
||||||
uint32_t FUSE_X_COORDINATE;
|
uint32_t FUSE_OPT_X_COORDINATE;
|
||||||
uint32_t FUSE_Y_COORDINATE;
|
uint32_t FUSE_OPT_Y_COORDINATE;
|
||||||
uint32_t _0x11C;
|
uint32_t FUSE_OPT_SEC_DEBUG_EN;
|
||||||
uint32_t _0x120;
|
uint32_t FUSE_OPT_OPS_RESERVED;
|
||||||
uint32_t FUSE_SATA_CALIB;
|
uint32_t FUSE_SATA_CALIB;
|
||||||
uint32_t FUSE_GPU_IDDQ;
|
uint32_t FUSE_GPU_IDDQ_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_3;
|
uint32_t FUSE_TSENSOR3_CALIB;
|
||||||
uint32_t _0x130;
|
uint32_t FUSE_SKU_BOND_OUT_L;
|
||||||
uint32_t _0x134;
|
uint32_t FUSE_SKU_BOND_OUT_H;
|
||||||
uint32_t _0x138;
|
uint32_t FUSE_SKU_BOND_OUT_U;
|
||||||
uint32_t _0x13C;
|
uint32_t FUSE_SKU_BOND_OUT_V;
|
||||||
uint32_t _0x140;
|
uint32_t FUSE_SKU_BOND_OUT_W;
|
||||||
uint32_t _0x144;
|
uint32_t FUSE_OPT_SAMPLE_TYPE;
|
||||||
uint32_t FUSE_OPT_SUBREVISION;
|
uint32_t FUSE_OPT_SUBREVISION;
|
||||||
uint32_t _0x14C;
|
uint32_t FUSE_OPT_SW_RESERVED_0;
|
||||||
uint32_t _0x150;
|
uint32_t FUSE_OPT_SW_RESERVED_1;
|
||||||
uint32_t FUSE_TSENSOR_4;
|
uint32_t FUSE_TSENSOR4_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_5;
|
uint32_t FUSE_TSENSOR5_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_6;
|
uint32_t FUSE_TSENSOR6_CALIB;
|
||||||
uint32_t FUSE_TSENSOR_7;
|
uint32_t FUSE_TSENSOR7_CALIB;
|
||||||
uint32_t FUSE_OPT_PRIV_SEC_DIS;
|
uint32_t FUSE_OPT_PRIV_SEC_EN;
|
||||||
uint32_t FUSE_PKC_DISABLE;
|
uint32_t FUSE_PKC_DISABLE;
|
||||||
uint32_t _0x16C;
|
uint32_t _0x16C;
|
||||||
uint32_t _0x170;
|
uint32_t _0x170;
|
||||||
uint32_t _0x174;
|
uint32_t _0x174;
|
||||||
uint32_t _0x178;
|
uint32_t _0x178;
|
||||||
uint32_t _0x17C;
|
uint32_t FUSE_FUSE2TSEC_DEBUG_DISABLE;
|
||||||
uint32_t FUSE_TSENSOR_COMMON;
|
uint32_t FUSE_TSENSOR_COMMON;
|
||||||
uint32_t _0x184;
|
uint32_t FUSE_OPT_CP_BIN;
|
||||||
uint32_t _0x188;
|
uint32_t FUSE_OPT_GPU_DISABLE;
|
||||||
uint32_t _0x18C;
|
uint32_t FUSE_OPT_FT_BIN;
|
||||||
uint32_t _0x190;
|
uint32_t FUSE_OPT_DONE_MAP;
|
||||||
uint32_t _0x194;
|
uint32_t _0x194;
|
||||||
uint32_t _0x198;
|
uint32_t FUSE_APB2JTAG_DISABLE;
|
||||||
uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
|
uint32_t FUSE_ODM_INFO;
|
||||||
uint32_t _0x1A0;
|
uint32_t _0x1A0;
|
||||||
uint32_t _0x1A4;
|
uint32_t _0x1A4;
|
||||||
uint32_t _0x1A8;
|
uint32_t FUSE_ARM_CRYPT_DE_FEATURE;
|
||||||
uint32_t _0x1AC;
|
uint32_t _0x1AC;
|
||||||
uint32_t _0x1B0;
|
uint32_t _0x1B0;
|
||||||
uint32_t _0x1B4;
|
uint32_t _0x1B4;
|
||||||
uint32_t _0x1B8;
|
uint32_t _0x1B8;
|
||||||
uint32_t _0x1BC;
|
uint32_t _0x1BC;
|
||||||
uint32_t _0x1D0;
|
uint32_t FUSE_WOA_SKU_FLAG;
|
||||||
uint32_t FUSE_TSENSOR_8;
|
uint32_t FUSE_ECO_RESERVE_1;
|
||||||
|
uint32_t FUSE_GCPLEX_CONFIG_FUSE;
|
||||||
|
uint32_t FUSE_PRODUCTION_MONTH;
|
||||||
|
uint32_t FUSE_RAM_REPAIR_INDICATOR;
|
||||||
|
uint32_t FUSE_TSENSOR9_CALIB;
|
||||||
uint32_t _0x1D8;
|
uint32_t _0x1D8;
|
||||||
uint32_t _0x1DC;
|
uint32_t FUSE_VMIN_CALIBRATION;
|
||||||
uint32_t _0x1E0;
|
uint32_t FUSE_AGING_SENSOR_CALIBRATION;
|
||||||
uint32_t _0x1E4;
|
uint32_t FUSE_DEBUG_AUTHENTICATION;
|
||||||
uint32_t _0x1E8;
|
uint32_t FUSE_SECURE_PROVISION_INDEX;
|
||||||
uint32_t _0x1EC;
|
uint32_t FUSE_SECURE_PROVISION_INFO;
|
||||||
uint32_t _0x1F0;
|
uint32_t FUSE_OPT_GPU_DISABLE_CP1;
|
||||||
uint32_t _0x1F4;
|
uint32_t FUSE_SPARE_ENDIS;
|
||||||
uint32_t _0x1F8;
|
uint32_t FUSE_ECO_RESERVE_0;
|
||||||
uint32_t _0x1FC;
|
uint32_t _0x1FC;
|
||||||
uint32_t _0x200;
|
uint32_t _0x200;
|
||||||
uint32_t FUSE_RESERVED_CALIB;
|
uint32_t FUSE_RESERVED_CALIB0;
|
||||||
uint32_t _0x208;
|
uint32_t FUSE_RESERVED_CALIB1;
|
||||||
uint32_t _0x20C;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE;
|
||||||
uint32_t _0x210;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP1;
|
||||||
uint32_t _0x214;
|
uint32_t FUSE_OPT_CPU_DISABLE;
|
||||||
uint32_t _0x218;
|
uint32_t FUSE_OPT_CPU_DISABLE_CP1;
|
||||||
uint32_t FUSE_TSENSOR_9;
|
uint32_t FUSE_TSENSOR10_CALIB;
|
||||||
uint32_t _0x220;
|
uint32_t FUSE_TSENSOR10_CALIB_AUX;
|
||||||
uint32_t _0x224;
|
uint32_t FUSE_OPT_RAM_SVOP_DP;
|
||||||
uint32_t _0x228;
|
uint32_t FUSE_OPT_RAM_SVOP_PDP;
|
||||||
uint32_t _0x22C;
|
uint32_t FUSE_OPT_RAM_SVOP_REG;
|
||||||
uint32_t _0x230;
|
uint32_t FUSE_OPT_RAM_SVOP_SP;
|
||||||
uint32_t _0x234;
|
uint32_t FUSE_OPT_RAM_SVOP_SMPDP;
|
||||||
uint32_t _0x238;
|
uint32_t FUSE_OPT_GPU_TPC0_DISABLE_CP2;
|
||||||
uint32_t _0x23C;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE;
|
||||||
uint32_t _0x240;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP1;
|
||||||
uint32_t _0x244;
|
uint32_t FUSE_OPT_GPU_TPC1_DISABLE_CP2;
|
||||||
uint32_t _0x248;
|
uint32_t FUSE_OPT_CPU_DISABLE_CP2;
|
||||||
uint32_t _0x24C;
|
uint32_t FUSE_OPT_GPU_DISABLE_CP2;
|
||||||
uint32_t FUSE_USB_CALIB_EXT;
|
uint32_t FUSE_USB_CALIB_EXT;
|
||||||
uint32_t _0x254;
|
uint32_t FUSE_RESERVED_FIELD;
|
||||||
uint32_t _0x258;
|
uint32_t FUSE_OPT_ECC_EN;
|
||||||
uint32_t _0x25C;
|
uint32_t _0x25C;
|
||||||
uint32_t _0x260;
|
uint32_t _0x260;
|
||||||
uint32_t _0x264;
|
uint32_t _0x264;
|
||||||
@@ -179,35 +192,36 @@ typedef struct {
|
|||||||
uint32_t _0x270;
|
uint32_t _0x270;
|
||||||
uint32_t _0x274;
|
uint32_t _0x274;
|
||||||
uint32_t _0x278;
|
uint32_t _0x278;
|
||||||
uint32_t _0x27C;
|
uint32_t FUSE_SPARE_REALIGNMENT_REG;
|
||||||
uint32_t FUSE_SPARE_BIT[0x20];
|
uint32_t FUSE_SPARE_BIT[0x20];
|
||||||
} tegra_fuse_chip_t;
|
} tegra_fuse_chip_t;
|
||||||
|
|
||||||
static inline volatile tegra_fuse_t *fuse_get_regs(void) {
|
static inline volatile tegra_fuse_t *fuse_get_regs(void)
|
||||||
|
{
|
||||||
return (volatile tegra_fuse_t *)FUSE_BASE;
|
return (volatile tegra_fuse_t *)FUSE_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) {
|
static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void)
|
||||||
|
{
|
||||||
return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE;
|
return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuse_init(void);
|
void fuse_init(void);
|
||||||
|
|
||||||
uint32_t fuse_hw_read(uint32_t addr);
|
|
||||||
void fuse_hw_write(uint32_t value, uint32_t addr);
|
|
||||||
void fuse_hw_sense(void);
|
|
||||||
void fuse_disable_programming(void);
|
void fuse_disable_programming(void);
|
||||||
void fuse_secondary_private_key_disable(void);
|
void fuse_disable_private_key(void);
|
||||||
|
|
||||||
uint32_t fuse_get_sku_info(void);
|
uint32_t fuse_get_sku_info(void);
|
||||||
uint32_t fuse_get_spare_bit(uint32_t idx);
|
uint32_t fuse_get_spare_bit(uint32_t idx);
|
||||||
uint32_t fuse_get_reserved_odm(uint32_t idx);
|
uint32_t fuse_get_reserved_odm(uint32_t idx);
|
||||||
|
|
||||||
uint32_t fuse_get_bootrom_patch_version(void);
|
uint32_t fuse_get_bootrom_patch_version(void);
|
||||||
uint64_t fuse_get_device_id(void);
|
uint64_t fuse_get_device_id(void);
|
||||||
uint32_t fuse_get_dram_id(void);
|
uint32_t fuse_get_dram_id(void);
|
||||||
uint32_t fuse_get_hardware_type(void);
|
uint32_t fuse_get_hardware_type(uint32_t target_firmware);
|
||||||
uint32_t fuse_get_retail_type(void);
|
uint32_t fuse_get_retail_type(void);
|
||||||
void fuse_get_hardware_info(void *dst);
|
void fuse_get_hardware_info(void *dst);
|
||||||
|
|
||||||
|
uint32_t fuse_hw_read(uint32_t addr);
|
||||||
|
void fuse_hw_write(uint32_t value, uint32_t addr);
|
||||||
|
void fuse_hw_sense(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user