diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 000000000..50084ce85
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,56 @@
+---
+name: Bug Report
+about: Something doesn't work correctly in Atmosphère.
+#assignees:
+---
+
+## Bug Report
+
+[ If any section does not apply, replace its contents with "N/A". ]
+[ Lines between [ ] (square brackets) should be removed before posting. ]
+
+[ * ]
+[ Note: If the bug or crash you encountered is related to; ]
+[ - software used to make "backups", ]
+[ - software explicitly distributed for piracy, etc ]
+[ then contributors will not provide support for your issue and your issue will be closed. ]
+
+### What's the issue you encountered?
+
+[ Describe the issue in detail and what you were doing beforehand. ]
+[ Did you make any changes related to Atmosphère itself? ]
+[ If so, make sure to include details relating to what exactly you changed. ]
+
+### How can the issue be reproduced?
+
+[ * ]
+[ Include a detailed step by step process for recreating your issue. ]
+
+### Crash Report
+
+[ Crash reports can be found under ``/atmosphere/crash_reports``. ]
+[ If your issue caused Atmosphère to crash, include the crash report(s) by creating a [gist](https://gist.github.com/) and pasting the link here. ]
+[ If you don't include a crash report in instances of crash related issues, we will ask you one to provide one. ]
+
+### System Firmware Version
+
+X.X.X
+[ Replace X's with system firmware version at time of crash. ]
+[ You can find your firmware version in the Settings -> System, under "System Update". ]
+[ If it says "Update Pending", you can clear the pending update by rebooting to Maintenance Mode. ]
+
+### Environment?
+
+- What bootloader (fusèe, hekate, etc) was Atmosphère launched by:
+- Official release or unofficial build:
+ - [ Offical release version x.x.x (or) unofficial build ]
+ - [ If using an unofficial build, include details on where/how you acquired the build. ]
+ - [ Ex: Self-compilation ]
+ - [ Ex: Kosmos' distribution of Atmosphère ]
+- Do you have additional kips or sysmodules you're loading:
+- Homebrew software installed: [ * ]
+
+### Additional context?
+
+- Additional info about your environment:
+- [ Any other information relevant to your issue. ]
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 000000000..61a25494c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,48 @@
+---
+name: Feature Request
+about: Suggest a new feature for Atmosphère.
+#assignees:
+---
+
+## Feature Request
+
+[ If any section does not apply, replace its contents with "N/A". ]
+[ If you do not have the information needed for a section, replace its contents with "Unknown". ]
+[ Lines between [ ] (square brackets) are to be removed before posting. ]
+
+[ Please search for existing [feature requests](https://github.com/Atmosphere-NX/Atmosphere/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22features%2Ffeature-request%22) before you make your own request. ]
+[ Duplicate requests will be marked as such and you will be referred to the original request. ]
+
+### What feature are you suggesting?
+#### Overview:
+- [ Include the basic, high-level concepts for this feature here. ]
+
+#### Smaller Details:
+- [ These may include specific methods of implementation etc. ]
+
+#### Nature of Request:
+[ Remove all that do not apply to your request. ]
+- Addition
+ - [ Ex: Addition of certain original features or features from other community projects. ]
+ - [ If you are suggesting porting features or including features from other projects, include what license they are distributed under and what, if any libraries those project use. ]
+- Change
+- Removal
+ - [Ex: Removal of certain features or implementation due to a specific issue/bug or because of low quality code, etc.]
+
+### What component do you feel this would best fit within?
+- [Fusée](https://github.com/Atmosphere-NX/Atmosphere#components)
+ - Atmosphère's custom bootloader.
+- [Exosphère](https://github.com/Atmosphere-NX/Atmosphere#components)
+ - Fully-featured custom secure monitor.
+- [Stratosphère](https://github.com/Atmosphere-NX/Atmosphere#components)
+ - Custom system modules.
+- [**Thermosphère**](https://github.com/Atmosphere-NX/Atmosphere#components)
+ - Atmosphère's emuNAND implementation.
+- [**Troposphère**](https://github.com/Atmosphere-NX/Atmosphere#components)
+ - Application-level patches to the Horizon OS.
+
+[ Note: **Bolded components are not implemented** or are still at the prototyping phase. ]
+
+### Why would this feature be useful?
+[ If this is a feature for an end-user, how does it benefit the end-user? ]
+[ If this feature is for developers, what does it add to Atmosphère that did not already exist? ]
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
new file mode 100644
index 000000000..21e69bd4e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,7 @@
+---
+name: Question
+about: Please ask questions in the ReSwitched discord, instead of making issues.
+---
+We would like to use GitHub to keep track of problems/feature requests.
+If you have a question, please join the ReSwitched discord for help.
+- Discord link: https://discordapp.com/invite/DThbZ7z
diff --git a/.gitignore b/.gitignore
index e3c4e615c..20467a117 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,7 +41,9 @@
*.nso
*.nro
*.nacp
+*.npdm
*.pfs0
+*.nsp
*.kip
# Debug files
@@ -59,10 +61,27 @@ Module.symvers
Mkfile.old
dkms.conf
+# Distribution files
+*.tgz
+*.zip
+
+# IDA binaries
+*.id0
+*.id1
+*.id2
+*.idb
+*.nam
+*.til
+
+# KEYS file for sept-secondary.
+*.pyc
+sept/sept-secondary/KEYS.py
+
.**/
# NOTE: make sure to make exceptions to this pattern when needed!
*.bin
+*.enc
**/out
**/build
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 000000000..771f79185
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "common/include/boost"]
+ path = common/include/boost
+ url = https://github.com/Atmosphere-NX/ext-boost.git
+[submodule "stratosphere/libstratosphere"]
+ path = stratosphere/libstratosphere
+ url = https://github.com/Atmosphere-NX/libstratosphere.git
diff --git a/Makefile b/Makefile
index 014cb646c..97c78053d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,81 @@
-TOPTARGETS := all clean
+TOPTARGETS := all clean dist
+AMSBRANCH := $(shell git symbolic-ref --short HEAD)
+AMSHASH := $(shell git rev-parse --short HEAD)
+AMSREV := $(AMSBRANCH)-$(AMSHASH)
-all: fusee
-fusee:
+ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
+ AMSREV := $(AMSREV)-dirty
+endif
+
+COMPONENTS := fusee stratosphere exosphere thermosphere troposphere
+
+all: $(COMPONENTS)
+
+thermosphere:
+ $(MAKE) -C thermosphere all
+
+exosphere: thermosphere
+ $(MAKE) -C exosphere all
+
+stratosphere: exosphere
+ $(MAKE) -C stratosphere all
+
+troposphere: stratosphere
+ $(MAKE) -C troposphere all
+
+sept: exosphere
+ $(MAKE) -C sept all
+
+fusee: exosphere stratosphere sept
$(MAKE) -C $@ all
clean:
$(MAKE) -C fusee clean
+ rm -rf out
-.PHONY: $(TOPTARGETS) fusee
+dist: all
+ $(eval MAJORVER = $(shell grep '\ATMOSPHERE_RELEASE_VERSION_MAJOR\b' common/include/atmosphere/version.h \
+ | tr -s [:blank:] \
+ | cut -d' ' -f3))
+ $(eval MINORVER = $(shell grep '\ATMOSPHERE_RELEASE_VERSION_MINOR\b' common/include/atmosphere/version.h \
+ | tr -s [:blank:] \
+ | cut -d' ' -f3))
+ $(eval MICROVER = $(shell grep '\ATMOSPHERE_RELEASE_VERSION_MICRO\b' common/include/atmosphere/version.h \
+ | tr -s [:blank:] \
+ | cut -d' ' -f3))
+ $(eval AMSVER = $(MAJORVER).$(MINORVER).$(MICROVER)-$(AMSREV))
+ rm -rf atmosphere-$(AMSVER)
+ rm -rf out
+ mkdir atmosphere-$(AMSVER)
+ mkdir atmosphere-$(AMSVER)/atmosphere
+ mkdir atmosphere-$(AMSVER)/sept
+ mkdir atmosphere-$(AMSVER)/switch
+ mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036
+ mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034
+ mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032
+ cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
+ mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/010000000000000D
+ cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
+ cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/sept/payload.bin
+ cp sept/sept-primary/sept-primary.bin atmosphere-$(AMSVER)/sept/sept-primary.bin
+ cp sept/sept-secondary/sept-secondary.bin atmosphere-$(AMSVER)/sept/sept-secondary.bin
+ cp sept/sept-secondary/sept-secondary.enc atmosphere-$(AMSVER)/sept/sept-secondary.enc
+ cp common/defaults/BCT.ini atmosphere-$(AMSVER)/atmosphere/BCT.ini
+ cp common/defaults/loader.ini atmosphere-$(AMSVER)/atmosphere/loader.ini
+ cp common/defaults/system_settings.ini atmosphere-$(AMSVER)/atmosphere/system_settings.ini
+ cp -r common/defaults/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches
+ cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036/exefs.nsp
+ cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034/exefs.nsp
+ cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/exefs.nsp
+ cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro
+ mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/flags
+ touch atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/flags/boot2.flag
+ cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/atmosphere/titles/010000000000000D/exefs.nsp
+ cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
+ rm -r atmosphere-$(AMSVER)
+ mkdir out
+ mv atmosphere-$(AMSVER).zip out/atmosphere-$(AMSVER).zip
+ cp fusee/fusee-primary/fusee-primary.bin out/fusee-primary.bin
+
+
+.PHONY: $(TOPTARGETS) $(COMPONENTS)
diff --git a/README.md b/README.md
index 73fe01895..0e55cc854 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,7 @@
=====

+[](https://discordapp.com/invite/ZdqEhed)
Atmosphère is a work-in-progress customized firmware for the Nintendo Switch.
@@ -12,6 +13,7 @@ Components
Atmosphère consists of multiple components, each of which replaces/modifies a different component of the system:
* Fusée: First-stage Loader, responsible for loading and validating stage 2 (custom TrustZone) plus package2 (Kernel/FIRM sysmodules), and patching them as needed. This replaces all functionality normally in Package1loader/NX Bootloader.
+ * Sept: Payload used to enable support for runtime key derivation on 7.0.0.
* Exosphère: Customized TrustZone, to run a customized Secure Monitor
* Thermosphère: EL2 EmuNAND support, i.e. backing up and using virtualized/redirected NAND images
* Stratosphère: Custom Sysmodule(s), both Rosalina style to extend the kernel/provide new features, and of the loader reimplementation style to hook important system actions
@@ -20,15 +22,17 @@ Atmosphère consists of multiple components, each of which replaces/modifies a d
Credits
=====
-Atmosphère is currently being developed and maintained by __SciresM__, __TuxSH__ and __hexkyz__.
+Atmosphère is currently being developed and maintained by __SciresM__, __TuxSH__, __hexkyz__, and __fincs__.
In no particular order, we credit the following for their invaluable contributions:
* __switchbrew__ for the [libnx](https://github.com/switchbrew/libnx) project and the extensive [documentation, research and tool development](http://switchbrew.org) pertaining to the Nintendo Switch.
* __devkitPro__ for the [devkitA64](https://devkitpro.org/) toolchain and libnx support.
-* __ReSwitched Team__ for additional [documentation, research and tool development](https://reswitched.tech/) pertaining to the Nintendo Switch.
+* __ReSwitched Team__ for additional [documentation, research and tool development](https://reswitched.team/) pertaining to the Nintendo Switch.
* __ChaN__ for the [FatFs](http://elm-chan.org/fsw/ff/00index_e.html) module.
+* __Marcus Geelnard__ for the [bcl-1.2.0](https://sourceforge.net/projects/bcl/files/bcl/bcl-1.2.0) library.
+* __naehrwert__ and __st4rk__ for the original [hekate](https://github.com/nwert/hekate) project and its hwinit code base.
+* __CTCaer__ for the continued [hekate](https://github.com/CTCaer/hekate) project's fork and the [minerva_tc](https://github.com/CTCaer/minerva_tc) project.
* __Riley__ for suggesting "Atmosphere" as a Horizon OS reimplementation+customization project name.
-* __naehrwert__ for the [hekate](https://github.com/nwert/hekate) project and its hwinit code base.
* __hedgeberg__ for research and hardware testing.
* __lioncash__ for code cleanup and general improvements.
* __jaames__ for designing and providing Atmosphère's graphical resources.
diff --git a/common/defaults/BCT.ini b/common/defaults/BCT.ini
new file mode 100644
index 000000000..b74c19725
--- /dev/null
+++ b/common/defaults/BCT.ini
@@ -0,0 +1,14 @@
+BCT0
+[stage1]
+stage2_path = atmosphere/fusee-secondary.bin
+stage2_addr = 0xF0000000
+stage2_entrypoint = 0xF0000000
+
+[exosphere]
+; Note: Disabling debugmode will cause parts of ams.tma to not work, in the future.
+debugmode = 1
+debugmode_user = 0
+
+[stratosphere]
+; To force-enable nogc, add nogc = 1
+; To force-disable nogc, add nogc = 0
diff --git a/common/defaults/kip_patches/default_nogc/02D5ABAAFD20C8B0633AA0DBAEE0377EF526CE6AD2AC6F2CAD7180CE69E74311.ips b/common/defaults/kip_patches/default_nogc/02D5ABAAFD20C8B0633AA0DBAEE0377EF526CE6AD2AC6F2CAD7180CE69E74311.ips
new file mode 100644
index 000000000..62f99241b
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/02D5ABAAFD20C8B0633AA0DBAEE0377EF526CE6AD2AC6F2CAD7180CE69E74311.ips differ
diff --git a/common/defaults/kip_patches/default_nogc/06E90719595A010C6246FF70946F10FB367A00BBD8B7D8D1F25CCE0B458D7E89.ips b/common/defaults/kip_patches/default_nogc/06E90719595A010C6246FF70946F10FB367A00BBD8B7D8D1F25CCE0B458D7E89.ips
new file mode 100644
index 000000000..7f1adb6e1
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/06E90719595A010C6246FF70946F10FB367A00BBD8B7D8D1F25CCE0B458D7E89.ips differ
diff --git a/common/defaults/kip_patches/default_nogc/10B2D81605488599DF2242CB6BAC2DF1E2BCAB3BC19DC5CD63DB6FAEC0947097.ips b/common/defaults/kip_patches/default_nogc/10B2D81605488599DF2242CB6BAC2DF1E2BCAB3BC19DC5CD63DB6FAEC0947097.ips
new file mode 100644
index 000000000..d8f050ed0
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/10B2D81605488599DF2242CB6BAC2DF1E2BCAB3BC19DC5CD63DB6FAEC0947097.ips differ
diff --git a/common/defaults/kip_patches/default_nogc/2ADBE97E9B5F41779EC95FFE2699C93305D6A69D465CF597D67465CD69BACCE8.ips b/common/defaults/kip_patches/default_nogc/2ADBE97E9B5F41779EC95FFE2699C93305D6A69D465CF597D67465CD69BACCE8.ips
new file mode 100644
index 000000000..0b7bc228e
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/2ADBE97E9B5F41779EC95FFE2699C93305D6A69D465CF597D67465CD69BACCE8.ips differ
diff --git a/common/defaults/kip_patches/default_nogc/2CCE659CEC536A8E4D91F3BE4B74BED302613F1E442581FD863708E39112DB50.ips b/common/defaults/kip_patches/default_nogc/2CCE659CEC536A8E4D91F3BE4B74BED302613F1E442581FD863708E39112DB50.ips
new file mode 100644
index 000000000..3ee63f4f3
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/2CCE659CEC536A8E4D91F3BE4B74BED302613F1E442581FD863708E39112DB50.ips differ
diff --git a/common/defaults/kip_patches/default_nogc/330553F6B5FB55C4C2D7B736240276B3EAD664DA79826FA936F99803B6C28F3B.ips b/common/defaults/kip_patches/default_nogc/330553F6B5FB55C4C2D7B736240276B3EAD664DA79826FA936F99803B6C28F3B.ips
new file mode 100644
index 000000000..26f1345d9
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/330553F6B5FB55C4C2D7B736240276B3EAD664DA79826FA936F99803B6C28F3B.ips differ
diff --git a/common/defaults/kip_patches/default_nogc/3A574D436186191D1788EB2C0F076B11737132EBB1484CF906B6A8EB3B1BF459.ips b/common/defaults/kip_patches/default_nogc/3A574D436186191D1788EB2C0F076B11737132EBB1484CF906B6A8EB3B1BF459.ips
new file mode 100644
index 000000000..da978a82a
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/3A574D436186191D1788EB2C0F076B11737132EBB1484CF906B6A8EB3B1BF459.ips differ
diff --git a/common/defaults/kip_patches/default_nogc/549B0F8D6F72C4E9F3FD1F19EACE4A5A1DA2D5C393F74224F8BC09DE4AAA4217.ips b/common/defaults/kip_patches/default_nogc/549B0F8D6F72C4E9F3FD1F19EACE4A5A1DA2D5C393F74224F8BC09DE4AAA4217.ips
new file mode 100644
index 000000000..7f1adb6e1
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/549B0F8D6F72C4E9F3FD1F19EACE4A5A1DA2D5C393F74224F8BC09DE4AAA4217.ips differ
diff --git a/common/defaults/kip_patches/default_nogc/76F87402C9387C0F0A2FAB1B45CEBB93E3E9695C7CFD390F00509B1204101C24.ips b/common/defaults/kip_patches/default_nogc/76F87402C9387C0F0A2FAB1B45CEBB93E3E9695C7CFD390F00509B1204101C24.ips
new file mode 100644
index 000000000..d8f050ed0
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/76F87402C9387C0F0A2FAB1B45CEBB93E3E9695C7CFD390F00509B1204101C24.ips differ
diff --git a/common/defaults/kip_patches/default_nogc/8096AF7C6A35AA8271F3916995413B0B64CE03BD9BBFEB26F2B3E01C5427C69E.ips b/common/defaults/kip_patches/default_nogc/8096AF7C6A35AA8271F3916995413B0B64CE03BD9BBFEB26F2B3E01C5427C69E.ips
new file mode 100644
index 000000000..62f99241b
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/8096AF7C6A35AA8271F3916995413B0B64CE03BD9BBFEB26F2B3E01C5427C69E.ips differ
diff --git a/common/defaults/kip_patches/default_nogc/A6F27AD9AC7C73AD419B63B23E785A0CD7AA9DC1A63C57D10049423DE7B77E2C.ips b/common/defaults/kip_patches/default_nogc/A6F27AD9AC7C73AD419B63B23E785A0CD7AA9DC1A63C57D10049423DE7B77E2C.ips
new file mode 100644
index 000000000..dd546f608
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/A6F27AD9AC7C73AD419B63B23E785A0CD7AA9DC1A63C57D10049423DE7B77E2C.ips differ
diff --git a/common/defaults/kip_patches/default_nogc/CE3ECBA2F2F062F575F8F360842B32B432340DD2C7590CDEFC03E51B844AE805.ips b/common/defaults/kip_patches/default_nogc/CE3ECBA2F2F062F575F8F360842B32B432340DD2C7590CDEFC03E51B844AE805.ips
new file mode 100644
index 000000000..dd546f608
Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/CE3ECBA2F2F062F575F8F360842B32B432340DD2C7590CDEFC03E51B844AE805.ips differ
diff --git a/common/defaults/loader.ini b/common/defaults/loader.ini
new file mode 100644
index 000000000..d488f21b4
--- /dev/null
+++ b/common/defaults/loader.ini
@@ -0,0 +1,8 @@
+[hbl_config]
+title_id=010000000000100D
+path=atmosphere/hbl.nsp
+override_key=!R
+
+[default_config]
+override_key=!L
+cheat_enable_key=!L
\ No newline at end of file
diff --git a/common/defaults/system_settings.ini b/common/defaults/system_settings.ini
new file mode 100644
index 000000000..2d4d14d1f
--- /dev/null
+++ b/common/defaults/system_settings.ini
@@ -0,0 +1,11 @@
+; Disable uploading error reports to Nintendo
+[eupld]
+upload_enabled = u8!0x0
+; Enable USB 3.0 superspeed for homebrew
+[usb]
+usb30_force_enabled = u8!0x0
+; Atmosphere custom settings
+[atmosphere]
+; Make the power menu's "reboot" button reboot to payload.
+; Set to "normal" for normal reboot, "rcm" for rcm reboot.
+power_menu_reboot_function = str!payload
\ No newline at end of file
diff --git a/common/include/atmosphere.h b/common/include/atmosphere.h
new file mode 100644
index 000000000..09f2faccf
--- /dev/null
+++ b/common/include/atmosphere.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef ATMOSPHERE_H
+#define ATMOSPHERE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "atmosphere/version.h"
+#include "atmosphere/target_fw.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/common/include/atmosphere/target_fw.h b/common/include/atmosphere/target_fw.h
new file mode 100644
index 000000000..8cbdb6112
--- /dev/null
+++ b/common/include/atmosphere/target_fw.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef ATMOSPHERE_TARGET_FIRMWARE_H
+#define ATMOSPHERE_TARGET_FIRMWARE_H
+
+#define ATMOSPHERE_TARGET_FIRMWARE_100 1
+#define ATMOSPHERE_TARGET_FIRMWARE_200 2
+#define ATMOSPHERE_TARGET_FIRMWARE_300 3
+#define ATMOSPHERE_TARGET_FIRMWARE_400 4
+#define ATMOSPHERE_TARGET_FIRMWARE_500 5
+#define ATMOSPHERE_TARGET_FIRMWARE_600 6
+#define ATMOSPHERE_TARGET_FIRMWARE_620 7
+#define ATMOSPHERE_TARGET_FIRMWARE_700 8
+
+#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_700
+
+#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE_100
+#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_700
+
+/* TODO: What should this be, for release? */
+#define ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG ATMOSPHERE_TARGET_FIRMWARE_CURRENT
+
+#endif
\ No newline at end of file
diff --git a/common/include/atmosphere/version.h b/common/include/atmosphere/version.h
new file mode 100644
index 000000000..24c6f40dd
--- /dev/null
+++ b/common/include/atmosphere/version.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef ATMOSPHERE_VERSION_H
+#define ATMOSPHERE_VERSION_H
+
+#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
+#define ATMOSPHERE_RELEASE_VERSION_MINOR 8
+#define ATMOSPHERE_RELEASE_VERSION_MICRO 4
+
+#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 7
+#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
+#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 1
+
+#endif
\ No newline at end of file
diff --git a/common/include/boost b/common/include/boost
new file mode 160000
index 000000000..fc6429e46
--- /dev/null
+++ b/common/include/boost
@@ -0,0 +1 @@
+Subproject commit fc6429e46398e16178b828a3a20e1bee9c56443d
diff --git a/docs/building.md b/docs/building.md
new file mode 100644
index 000000000..47d230b8a
--- /dev/null
+++ b/docs/building.md
@@ -0,0 +1,6 @@
+# Building Atmosphère
+The process for building Atmosphère is similar to building Fusée Gelée payloads and other Switch apps.
+
+In order to build Atmosphère you must have devkitARM and devkitA64 installed on your computer. You can find instructions on how to install and setup devkitARM and devkitA64 on various OSes [here](https://devkitpro.org/wiki/Getting_Started).
+
+Once you have finished installing devkitARM and devkitA64, simply clone the Atmosphère repo, change to it and run `make`.
diff --git a/docs/changelog.md b/docs/changelog.md
new file mode 100644
index 000000000..82466cd77
--- /dev/null
+++ b/docs/changelog.md
@@ -0,0 +1,205 @@
+# Changelog
+## 0.8.4
++ Support for 7.0.0/7.0.1 was added.
+ + This is facilitated through a new payload, `sept`, which can be signed, encrypted, and then loaded by Nintendo's TSEC firmware.
+ + `sept` will derive the keys needed to boot new firmware, and then load `sept/payload.bin` off the SD card and jump to it.
++ Recognition of applications for override/mitm has been improved.
+ + Nintendo's official Title ID range (`0x0100000000000000`-`0x01FFFFFFFFFFFFFF`) is now enforced.
++ A deadlock condition was fixed involving libstratosphere mitm sysmodules.
++ Kernel patches for JIT support were added (Thanks, @m4xw!).
+ + These loosen restrictions on caller process in svcControlCodeMemory.
++ `set.mitm` and `fs.mitm` were merged into a single `ams_mitm` sysmodule.
+ + This saves a process ID, allowing users to run one additional process up to the 0x40 process limit.
++ A `bpc.mitm` component was added, performing custom behavior on shutdown/reboot requests from `am` or applications.
+ + Performing a reboot from the reboot menu now reboots to atmosphere. This can be configured via `system_settings.ini`.
+ + Performing a shutdown from the reboot menu now works properly with AutoRCM, and does a real shutdown.
++ General system stability improvements to enhance the user's experience.
+## 0.8.3
++ A custom warmboot firmware was implemented, which does not perform anti-downgrade fuse checks.
+ + This fixes sleep mode when using a downgraded NAND.
+ + This also removes Atmosphère's final dependency on Nintendo's encrypted PK11 binary; all components are now re-implemented.
++ The ExternalContentSource API was changed to not clear on failure.
++ Content override now supports an "app" setting, that causes all applications to be overridden with HBL instead of a specific title.
+ + Note: because override keys are system-wide, using this setting will prevent using mods in games (as every game will be HBL).
++ A bug was fixed causing incorrect fatal-error output when svcBreak was called on 5.0.0+.
++ An extension was added to set.mitm to support customization of system settings.
+ + These are controlled by `atmosphere/system_settings.ini`, see [here](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/modules/set_mitm.md) for documentation.
++ An extension was added to sm, adding a new `sm:dmnt` service.
+ + This can be used by a debug monitor in order to debug the registration state of various other services.
++ A bug was fixed in the MitM API that could sometimes cause a system hang during boot.
++ A change was made to the MitM API: in cases where sm would have returned 0xE15 when installing a mitm service, it now defers the result (following GetService semantics).
++ Support for booting into maintenance mode by holding +/- was added to PM.
++ An extension was added to exosphere, adding a custom SMC that allows for DMA to IRAM.
++ In addition, smcGetConfig was extended to reboot to a payload in IRAM at 0x40010000 when ConfigItem 65001 is set to 2.
+ + Fatal will now use this to reboot to sdmc:/atmosphere/reboot_payload.bin if present, when a vol button is pressed.
+ + An example homebrew ("reboot_to_payload") was also written and is now included with Atmosphère.
++ General system stability improvements to enhance the user's experience.
+## 0.8.2
++ A number of bugs were fixed causing users to sometimes see `Key Derivation Failed!`.
+ + KFUSE clock enable timings have been adjusted to allow time to stabilize before TSEC is granted access.
+ + A race condition was fixed that could cause wrong key data to be used on 6.2.0
+ + The TSEC firmware is now retried on failure, fixing a failure affecting ~1/50 boots on 6.2.0.
++ A bug was fixed causing some modules to not work on firmware 1.0.0.
++ A bug was fixed causing sleep mode to not work with debugmode enabled.
+ + As a result, debugmode is now enabled in the default BCT.ini.
++ General system stability improvements to enhance the user's experience.
+## 0.8.1
++ A bug was fixed causing users to see `Failed to enable SMMU!` if fusee had previously rebooted.
+ + This message will still occur sporadically if fusee is not launched from coldboot, but it can never happen twice in a row.
++ A race condition was fixed in Atmosphere `bis_protect` functionality that could cause NS to be able to overwrite BCT public keys.
+ + This sometimes broke AutoRCM protection, the current fix has been tested on hardware and verified to work.
++ Support was added for enabling `debugmode` based on the `exosphere` section of `BCT.ini`:
+ + Setting `debugmode = 1` will cause exosphere to tell the kernel that debugmode is active.
+ + Setting `debugmode_user = 1` will cause exosphere to tell userland that debugmode is active.
+ + These are completely independent of one another, allowing fine control of system behavior.
++ Support was added for `nogc` functionality; thanks to @rajkosto for the patches.
+ + By default, `nogc` patches will automatically apply if the user is booting into 4.0.0+ with fuses from <= 3.0.2.
+ + Users can override this functionality via the `nogc` entry in the `stratosphere` section of `BCT.ini`:
+ + Setting `nogc = 1` will force enable `nogc` patches.
+ + Setting `nogc = 0` will force disable `nogc` patches.
+ + If patches are enabled but not found for the booting system, a fatal error will be thrown.
+ + This should prevent running FS without `nogc` patches after updating to an unsupported system version.
++ An extension was added to `exosphere` allowing userland applications to cause the system to reboot into RCM:
+ + This is done by calling smcSetConfig(id=65001, value=); user homebrew can use splSetConfig for this.
++ On fatal error, the user can now choose to perform a standard reboot via the power button, or a reboot into RCM via either volume button.
++ A custom message was added to `fatal` for when an Atmosphère API version mismatch is detected (2495-1623).
++ General system stability improvements to enhance the user's experience.
+## 0.8.0
++ A custom `fatal` system module was added.
+ + This re-implements and extends Nintendo's fatal module, with the following features:
+ + Atmosphère's `fatal` does not create error reports.
+ + Atmosphère's `fatal` draws a custom error screen, showing registers and a backtrace.
+ + Atmosphère's `fatal` attempts to gather debugging info for all crashes, and not just ones that include info.
+ + Atmosphère's `fatal` will attempt saving reports to the SD, if a crash report was not generated by `creport`.
++ Title flag handling was changed to prevent folder clutter.
+ + Instead of living in `atmosphere/titles//%s.flag`, flags are now located in `atmosphere/titles//flags/%s.flag`
+ + The old format will continue to be supported for some time, but is deprecated.
+ + Flags can now be applied to HBL by placing them at `atmosphere/flags/hbl_%s.flag`.
++ Changes were made to the mitm API, greatly improving caller semantics.
+ + `sm` now informs mitm services of a new session's process id, enabling custom handling based on title id/process id.
++ smhax is no longer enabled, because it is no longer needed and breaks significant functionality.
+ + Users with updated HBL/homebrew should see no observable differences due to this change.
++ Functionality was added implementing basic protections for NAND from userland homebrew:
+ + BOOT0 now has write protection for the BCT public key and keyblob regions.
+ + The `ns` sysmodule is no longer allowed to write the BCT public keys; all other processes can.
+ + This should prevent system updates from removing AutoRCM.
+ + No processes should be allowed to write to the keyblob region.
+ + By default, BIS partitions other than BOOT0 are now read-only, and CAL0 is neither readable nor writable.
+ + Adding a `bis_write` flag for a title will allow it to write to BIS.
+ + Adding a `cal_read` flag for a title will allow it to read CAL0.
+ + An automatic backup is now made of CAL0 on boot.
+ + `fs.mitm` maintains a file handle to this backup, so userland software cannot read it.
+ + To facilitate this, `fs.mitm` now mitms all sessions for non-system modules; content overriding has been made separate from service interception.
+ + Please note: these protections are basic, and sufficiently malicious homebrew ++can defeat them++.
+ + Please be careful to only run homebrew software from sources that you trust.
++ A bug involving HDCP titles crashing on newer firmwares was fixed.
++ Support was added for system version 6.2.0; our thanks to @motezazer for his invaluable help.
+ + By default, new keys will automatically be derived without user input.
+ + Support is also present for loading new keys from `atmosphere/prod.keys` or `atmosphere/dev.keys`
++ General system stability improvements to enhance the user's experience.
+## 0.7.5
++ DRAM training was added to fusee-secondary, courtesy @hexkyz.
+ + This greatly improves the speed of memory accesses during boot, resulting in a boot time that is ~200-400% faster.
++ creport has had its code region detection improved.
+ + Instead of only checking one of the crashing thread's PC/LR for code region presence, creport now checks both + every address in the stacktrace. This is also now done for every thread.
+ + This matches the improvement Nintendo added to official creport in 6.1.0.
+ + The code region detection heuristic was further improved by checking whether an address points to .rodata or .rwdata, instead of just .text.
+ + This means that a crash appears in a loaded NRO (or otherwise discontiguous) code region, creport will be able to detect all active code regions, and not just that one.
+## 0.7.4
++ [libstratosphere](https://github.com/Atmosphere-NX/libstratosphere) has been completely refactored/rewritten, and split into its own, separate submodule.
+ + While this is mostly "under the hood" for end-users, the refactor is faster (improving both boot-time and runtime performance), more accurate (many of the internal IPC structures are now bug-for-bug compatible with Nintendo's implementations), and significantly more stable (it fixes a large number of bugs present in the old library).
+ + The refactored API is significantly cleaner and easier to write system module code for, which should improve/speed up development of stratosphere.
+ + Developers looking to write their own custom system modules for the Switch can now easily include libstratosphere as a submodule in their projects.
++ Loader was extended to add a new generic way to redirect content (ExternalContentSources), courtesy @misson20000:
+ + A new command was added to ldr:shel, taking in a tid to redirect and returning a session handle.
+ + When the requested TID is loading, Loader will query the handle as though it were an IFileSystem.
+ + This allows clients to generically define their own filesystems, and override content with them in loader.
++ fs.mitm has gotten several optimizations that should improve its performance and stability:
+ + RomFS redirection now only occurs when there is content to redirect, even if the title is being mitm'd elsewhere.
+ + A cache is now maintained of the active data storage, if any, for all opened title IDs. This means if two processes both try to open the same archive, fs.mitm won't duplicate any of its work.
+ + RomFS metadata is now cached to the SD card on build instead of being persisted in memory -- this greatly reduces memory footprint and allows fs.mitm to redirect more titles simultaneously than before.
++ A number of bugs were fixed, including:
+ + A resource leak was fixed in process creation. This fixes crashes that occur when a large number (>32) games have been launched since the last reboot.
+ + fs.mitm no longer errors when receiving a zero-sized buffer. This fixes crashes in some games, including The Messenger.
+ + Multi-threaded server semantics should no longer cause deadlocks in certain circumstances. This fixes crashes in some games, including NES Classics.
+ + PM now only gives full FS permissions to the active KIPs. This fixes a potential crash where new processes might be unable to be registered with FS.
++ The `make dist` target now includes the branch in the generated zip name.
++ General system stability improvements to enhance the user's experience.
+## 0.7.3
++ Loader and fs.mitm now try to reload loader.ini before reading it. This allows for changing the override button combination/HBL title id at runtime.
++ Added a MitM between set:sys and qlaunch, used to override the system version string displayed in system settings.
+ + The displayed system version will now display ` (AMS ..)`.
++ General system stability improvements to enhance the user's experience.
+## 0.7.2
++ Fixed a bug in fs.mitm's LayeredFS read implementation that caused some games to crash when trying to read files.
++ Fixed a bug affecting 1.0.0 that caused games to crash with fatal error 2001-0106 on boot.
++ Improved filenames output by the make dist target.
++ General system stability improvements to enhance the user's experience.
+
+## 0.7.1
++ Fixed a bug preventing consoles on 4.0.0-4.1.0 from going to sleep and waking back up.
++ Fixed a bug preventing consoles on < 4.0.0 from booting without specific KIPs on the SD card.
++ An API was added to Atmosphère's Service Manager for deferring acquisition of all handles for specific services until after early initialization is completed.
++ General system stability improvements to enhance the user's experience.
+
+## 0.7.0
++ First official release of Atmosphère.
++ Supports the following featureset:
+ + Fusée, a custom bootloader.
+ + Supports loading/customizing of arbitrary KIPs from the SD card.
+ + Supports loading a custom kernel from the SD card ("/atmosphere/kernel.bin").
+ + Supports compile-time defined kernel patches on a per-firmware basis.
+ + All patches at paths like /atmosphere/kip_patches//.ips will be applied to the relevant KIPs, allowing for easy distribution of patches supporting multiple versions.
+ + Both the IPS and IPS32 formats are supported.
+ + All patches at paths like /atmosphere/kernel_patches//.ips will be applied to the kernel, allowing for easy distribution of patches supporting multiple versions.
+ + Both the IPS and IPS32 formats are supported.
+ + Configurable by editing BCT.ini on the SD card.
+ + Atmosphère should also be launchable by the alternative hekate bootloader, for those who prefer it.
+ + Exosphère, a fully-featured custom secure monitor.
+ + Exosphere is a re-implementation of Nintendo's TrustZone firmware, fully replicating all of its features.
+ + In addition, it has been extended to provide information on current Atmosphere API version, for homebrew wishing to make use of it.
+ + Stratosphère, a set of custom system modules. This includes:
+ + A loader system module.
+ + Reimplementation of Nintendo's loader, fully replicating all original functionality.
+ + Configurable by editing /atmosphere/loader.ini
+ + First class support for the Homebrew Loader.
+ + An exefs NSP (default "/atmosphere/hbl.nsp") will be used in place of the victim title's exefs.
+ + By default, HBL will replace the album applet, but any application should also be supported.
+ + Extended to support arbitrary redirection of executable content to the SD card.
+ + Files will be preferentially loaded from /atmosphere/titles//exefs/, if present.
+ + Files present in the original exefs a user wants to mark as not present may be "stubbed" by creating a .stub file on the SD.
+ + If present, a PFS0 at /atmosphere/titles//exefs.nsp will fully replace the original exefs.
+ + Redirection is optionally toggleable by holding down certain buttons (by default, holding R disables redirection).
+ + Full support for patching NSO content is implemented.
+ + All patches at paths like /atmosphere/exefs_patches//.ips will be applied, allowing for easy distribution of patches supporting multiple firmware versions and/or titles.
+ + Both the IPS and IPS32 formats are supported.
+ + Extended to support launching content from loose executable files on the SD card, without requiring any official installation.
+ + This is done by specifying FsStorageId_None on launch.
+ + A service manager system module.
+ + Reimplementation of Nintendo's service manager, fully replicating all original functionality.
+ + Compile-time support for reintroduction of "smhax", allowing clients to optionally skip service access verification by skipping initialization.
+ + Extended to allow homebrew to acquire more handles to privileged services than Nintendo natively allows.
+ + Extended to add a new API for installing Man-In-The-Middle listeners for arbitrary services.
+ + API can additionally be used to safely detect whether a service has been registered in a non-blocking way with no side-effects.
+ + Full API documentation to come.
+ + A process manager system module.
+ + Reimplementation of Nintendo's process manager, fully replicating all original functionality.
+ + Extended to allow homebrew to acquire handles to arbitrary processes, and thus read/modify system memory without blocking execution.
+ + Extended to allow homebrew to retrieve information about system resource limits.
+ + Extended by embedding a full, extended implementation of Nintendo's boot2 system module.
+ + Title launch order has been optimized in order to grant access to the SD card faster.
+ + The error-collection system module is intentionally not launched, preventing many system telemetry error reports from being generated at all.
+ + Users may place their own custom sysmodules on the SD card and flag them for automatic boot2 launch by creating a /atmosphere/titles//boot2.flag file on their SD card.
+ + A custom fs.mitm system module.
+ + Uses Atmosphère's MitM API in order to provide an easy means for users to modify game content.
+ + Intercepts all FS commands sent by games, with special handling for commands used to mount RomFS/DLC content to enable easy creation and distribution of game/DLC mods.
+ + fs.mitm will parse the base RomFS image for a game, a RomFS image located at /atmosphere/titles//romfs.bin, and all loose files in /atmosphere/titles//romfs/, and merge them together into a single RomFS image.
+ + When merging, loose files are preferred to content in the SD card romfs.bin image, and files from the SD card image are preferred to those in the base image.
+ + Can additionally be used to intercept commands sent by arbitrary system titles (excepting those launched before SD card is active), by creating a /atmosphere/titles//fsmitm.flag file on the SD card.
+ + Can be forcibly disabled for any title, by creating a /atmosphere/titles//fsmitm_disable.flag file on the SD card.
+ + Redirection is optionally toggleable by holding down certain buttons (by default, holding R disables redirection).
+ + A custom crash report system module.
+ + Serves as a drop-in replacement for Nintendo's own creport system module.
+ + Generates detailed, human-readable reports on system crashes, saving to /atmosphere/crash_reports/_.log.
+ + Because reports are not sent to the erpt sysmodule, this disables all crash report related telemetry.
+ + General system stability improvements to enhance the user's experience.
diff --git a/docs/components/exosphere.md b/docs/components/exosphere.md
new file mode 100644
index 000000000..b8a1103c8
--- /dev/null
+++ b/docs/components/exosphere.md
@@ -0,0 +1,10 @@
+# Exosphère
+Exosphère is a reimplementation of Arm's TrustZone (TZ), also known as Secure Monitor (Secure_Monitor.bin). It has the highest privilege mode available on the Switch’s processor, and has access to everything on the console.
+
+Exosphère will potentially play a big role in Jamais Vu and Déja Vu, which are upcoming software exploits for the Switch, allowing one to launch Atmosphère on a Fusée-Gélee patched (ipatched) Switch console, and will also enable one to launch into CFW directly from the Switch itself without the use of any sort of external device, such as a computer or RCM jig, provided they are on a low enough system firmware.
+
+## TrustZone/Secure Monitor
+TrustZone is responsible for all the cryptographic operations on the Switch. The idea behind the way it operates is that all the keys stay in the TrustZone, and userspace only gets "handles" to them. This would make sure that keydata never leaks and is kept secure. It also has a few more responsibilities, such as power management, providing a source of random numbers, and providing access to various pieces of information that are stored in the fuses.
+
+## Extensions
+Exosphère currently only contains one extension, an SMC allowing homebrew to find which version of Atmosphère is currently running, in order to find out what extensions are allowed to be used.
diff --git a/docs/components/fusee/BCT.md b/docs/components/fusee/BCT.md
new file mode 100644
index 000000000..35c9f8246
--- /dev/null
+++ b/docs/components/fusee/BCT.md
@@ -0,0 +1,26 @@
+# BCT.ini
+BCT.ini is the configuration file used by fusée-primary and fusée-secondary. It is read by fusee-primary.bin to setup and boot fusee-secondary.bin and is also read by fusee-secondary.bin to configure Exosphère or to specify the environment it should boot.
+
+## Configuration
+This file is located at the root of your SD.
+```
+BCT0
+[stage1]
+stage2_path = fusee-secondary.bin
+stage2_addr = 0xF0000000
+stage2_entrypoint = 0xF0000000
+```
+Add the following lines and replace the `X` according to the following list if you have trouble booting past the firmware version detection.
+`target_firmware` is the OFW major version.
+```
+[exosphere]
+target_firmware = X
+```
+```
+1.0.0 = 1
+2.X.X = 2
+3.X.X = 3
+4.X.X = 4
+5.X.X = 5
+6.0.0 = 6
+```
diff --git a/docs/components/fusee/fusee.md b/docs/components/fusee/fusee.md
new file mode 100644
index 000000000..64c9575bd
--- /dev/null
+++ b/docs/components/fusee/fusee.md
@@ -0,0 +1,20 @@
+# Fusée
+Fusée (not to be confused with Fusée Gelée) is a custom bootloader needed to start Atmosphère and replaces Nintendo's Package1loader/bootloader. It currently utilizes the [Tegra X1 RCM Vulnerability](https://nvidia.custhelp.com/app/answers/detail/a_id/4660/~/security-notice%3A-nvidia-tegra-rcm-vulnerability) in order to function.
+
+Fusée is split into two separate parts: fusée-primary and fusée-secondary. This is due to the RCM Vulnerability only allowing payloads of a limited filesize to be sent to the device.
+
+As of June 2018, there are new Switch systems being sold that prevent Fusée (or any payload that requires the Fusée Gelée exploit) from working due to having an ipatched bootrom. All ipatched systems share the HAC-S-JXE-C3 product code. While Fusée cannot work on these ipatched units, they still come on firmware 4.1.0, which is vulnerable to the upcoming Déja Vu software exploit. Note that if you update past 4.1.0 on one of these ipatched units, your odds of being able to install Atmosphère or run any homebrew become practically non-existent.
+
+Additionally, a hardware revision of the Switch known as “Mariko” is believed to be in development. No such units have been seen in stores yet, but it is expected Nintendo will roll them out silently. The Mariko units will most likely patch the bootrom vulnerability Fusée Gelée, which is currently used to access CFW, and will likely have their own proprietary bootloader.
+
+## Fusée-Primary
+Fusée-primary is the payload file (fusee-primary.bin) sent to the Switch from an external device. Once sent, fusée-primary makes initial preparations before loading fusée-secondary from the Switch’s SD Card.
+
+Fusée-primary can be configured via the [BCT.ini](../fusee/BCT.md) file located on the Switch’s SD card.
+
+## Fusée-Secondary
+Fusée-secondary is a payload file that stays on the root of the Switch’s SD Card (fusee-secondary.bin). It is automatically launched once fusée-primary has finished, and is responsible for preparing the Switch’s hardware for future running environments, such as the homebrew menu. Fusée-secondary is also responsible for validating and launching Exosphère.
+
+Fusée-secondary contains various [.kip modules](/docs/main.md#modules). These modules modify existing features in the OS, and can also add new ones.
+
+Fusée is also capable of chainloading other payloads such as Linux.
diff --git a/docs/components/fusee/sept.md b/docs/components/fusee/sept.md
new file mode 100644
index 000000000..6d15be23e
--- /dev/null
+++ b/docs/components/fusee/sept.md
@@ -0,0 +1,15 @@
+# sept
+Sept is a payload that facilitates booting Atmosphère when targeting firmware version 7.0.0+.
+
+It consists of a primary and a secondary payload.
+
+## Sept-Primary
+Sept-primary is essentially a stand-in for Nintendo's package1ldr, on 7.0.0+. To use it, the caller (normally Fusée-secondary) loads the sept-primary binary to `0x4003F000`,
+loads the 7.0.0+ TSEC firmware to `0x40010F00`, and loads a signed, encrypted payload to `0x40016FE0`.
+
+This signed, encrypted payload is normally Sept-secondary.
+
+## Sept-Secondary
+Sept-secondary is a payload that performs 7.0.0+ key derivation, and then chainloads to `sept/payload.bin`.
+
+It is normally stored encrypted/signed; if one wishes to build sept-secondary instead of using release builds, one must bring his/her own keys.
diff --git a/docs/components/stratosphere.md b/docs/components/stratosphere.md
new file mode 100644
index 000000000..58813ab77
--- /dev/null
+++ b/docs/components/stratosphere.md
@@ -0,0 +1,10 @@
+# Stratosphère
+Stratosphère allows customization of the Horizon OS and Switch kernel. It includes custom sysmodules that extend the kernel and provide new features. It also includes a reimplementation of the loader sysmodules to hook important system actions.
+
+The sysmodules that Stratosphère includes are:
++ [boot](../modules/boot.md): This module boots the system and initalizes hardware.
++ [creport](../modules/creport.md): Reimplementation of Nintendo’s crash report system. Dumps all error logs to the SD card instead of saving them to the NAND and sending them to Nintendo.
++ [fs_mitm](../modules/fs_mitm.md): This module can log, deny, delay, replace, and redirect any request made to the File System.
++ [loader](../modules/loader.md): Enables modifying the code of binaries that are not stored inside the kernel.
++ [pm](../modules/pm.md): Reimplementation of Nintendo’s Process Manager.
++ [sm](../modules/sm.md): Reimplementation of Nintendo’s Service Manager.
diff --git a/docs/components/thermosphere.md b/docs/components/thermosphere.md
new file mode 100644
index 000000000..c29483598
--- /dev/null
+++ b/docs/components/thermosphere.md
@@ -0,0 +1,6 @@
+# Thermosphère
+Thermosphère is a hypervisor based implementation of emuNAND. An emuNAND is a copy of the firmware on the Switch’s internal memory (sysNAND), and is typically installed on an external SD Card.
+
+An emuNAND operates completely independently of the sysNAND. This allows one to make or test various modifications and homebrew safely without needing to restore their NAND backup afterwards by testing things on the emuNAND, and switching back to the sysNAND when finished. In the case of past Nintendo systems such as the 3DS, an emuNAND could also be used to update your system to the latest firmware while keeping your sysNAND on a lower version, however this may be more difficult to do on the Switch due to Nintendo using efuse technology for major system updates.
+
+Thermosphère is currently planned to be included in the 1.0 release of Atmosphère.
diff --git a/docs/components/troposphere.md b/docs/components/troposphere.md
new file mode 100644
index 000000000..2664843d8
--- /dev/null
+++ b/docs/components/troposphere.md
@@ -0,0 +1,2 @@
+# Troposphère
+Troposphère contains various application-level modifications to the OS, such as launching homebrew directly from the homemenu or executing cheat/gameshark codes, similar to Luma3DS. Troposphère is not yet implemented in Atmosphère.
diff --git a/docs/flags.md b/docs/flags.md
new file mode 100644
index 000000000..5ee403b28
--- /dev/null
+++ b/docs/flags.md
@@ -0,0 +1,12 @@
+# Flags
+Atmosphère supports customizing CFW behavior based on the presence of `flags` on the SD card.
+
+The following flags are supported on a per-title basis, by placing `.flag` inside `/atmosphere/titles//flags/`:
++ `boot2`, which indicates to PM that the title should be launched during the `boot2` process.
++ `fsmitm`, which indicates that `fs.mitm` should override contents for the title even if it otherwise wouldn't.
++ `fsmitm_disable`, which indicates that `fs.mitm` should not override contents for the title, even it it otherwise would.
++ `bis_write`, which indicates that `fs.mitm` should allow the title to write to BIS partitions.
++ `cal_read`, which indicates that `fs.mitm` should allow the title to read the CAL0/PRODINFO partition.
+
+The following global flags are supported, by placing `.flag` inside `/atmosphere/flags/`:
++ `hbl_bis_write` and `hbl_cal_read` enable the BIS write and CAL0 read functionality for HBL, without needing to specify its title id.
\ No newline at end of file
diff --git a/docs/main.md b/docs/main.md
new file mode 100644
index 000000000..02f3efc39
--- /dev/null
+++ b/docs/main.md
@@ -0,0 +1,29 @@
+# Atmosphère
+Atmosphère is a work-in-progress customized firmware for the Nintendo Switch. Atmosphère consists of several different components, each in charge of performing different system functions of the Nintendo Switch.
+
+The components of Atmosphère are:
++ [Fusée](../docs/components/fusee/fusee.md), a custom bootloader.
++ [Exosphère](../docs/components/exosphere.md), a fully-featured custom secure monitor.
++ [Stratosphère](../docs/components/stratosphere.md), a set of custom system modules.
++ [Thermosphère](../docs/components/thermosphere.md), a hypervisor-based emuNAND implementation. This component has not been implemented yet.
++ [Troposphère](../docs/components/troposphere.md), Application-level patches to the Horizon OS. This component has also not been implemented yet.
+
+### Modules
+The Stratosphère component of Atmosphère contains various modules. These have a `.kip` extension. They provide custom features, extend existing features, or replace Nintendo sysmodules.
+
+Stratosphère's modules include:
++ [boot](../docs/modules/boot.md)
++ [creport](../docs/modules/creport.md)
++ [fs_mitm](../docs/modules/fs_mitm.md)
++ [loader](../docs/modules/loader.md)
++ [pm](../docs/modules/pm.md)
++ [sm](../docs/modules/sm.md)
+
+### Building Atmosphère
+A guide to building Atmosphère can be found [here](../docs/building.md).
+
+### Upcoming Features
+A list of planned features for Atmosphère can be found [here](../docs/roadmap.md).
+
+### Release History
+A changelog of previous versions of Atmosphère can be found [here](../docs/changelog.md).
diff --git a/docs/modules/boot.md b/docs/modules/boot.md
new file mode 100644
index 000000000..53013b32c
--- /dev/null
+++ b/docs/modules/boot.md
@@ -0,0 +1,2 @@
+# boot
+The boot module is responsible for booting the system and initalizing hardware. A second boot module known as boot2 is integrated with the [pm (process manager)](../modules/pm.md) sysmodule in Atmosphère, and launches other processes.
diff --git a/docs/modules/creport.md b/docs/modules/creport.md
new file mode 100644
index 000000000..a6a996f43
--- /dev/null
+++ b/docs/modules/creport.md
@@ -0,0 +1,2 @@
+# creport
+creport is a reimplementation of Nintendo's crash reporter. Atmosphère's creport catches all error logs that would have been saved to the NAND and instead saves them to the SD card for debugging purposes. This is helpful because the errors no longer go to Nintendo and developers of homebrew can still see the errors to help with the debugging process. creport catches system errors, game crashes, and homebrew crashes.
diff --git a/docs/modules/fs_mitm.md b/docs/modules/fs_mitm.md
new file mode 100644
index 000000000..345c42275
--- /dev/null
+++ b/docs/modules/fs_mitm.md
@@ -0,0 +1,2 @@
+# fs_mitm
+fs_mitm is a sysmodule that enables intercepting file system operations. This module can log, deny, delay, replace, or redirect any request made to the filesystem. It enables LayeredFS to function, which allows for game mods.
diff --git a/docs/modules/loader.md b/docs/modules/loader.md
new file mode 100644
index 000000000..666ad86b5
--- /dev/null
+++ b/docs/modules/loader.md
@@ -0,0 +1,101 @@
+# loader
+
+loader is a reimplementation of the loader sysmodule. This module is responsible for creating processes from executable NSO images and registering their access control with the kernel, sm, and fs.
+
+## Atmosphère Extensions
+
+Atmosphère extends this module to allow executables to be replaced or patched by files stored on the SD card. Note that a few services are required for SD card access and therefore cannot be replaced or patched in this manner. This includes psc, bus, and pcv.
+
+### Exefs Replacement
+
+TODO: details on buttons affecting this.
+
+When a process is created, loader will search for several NSO filenames in the title's exefs directory.
+These filenames are, in this order:
+
+ - rtld
+ - main
+ - subsdk0
+ - subsdk1
+ - ...
+ - subsdk9
+ - sdk
+
+Each NSO that is found will be loaded into the process contiguously. The process's entrypoint is at the first NSO to be loaded, usually `rtld` or `main`.
+
+Additionally, when a process is loaded, loader will search for a `main.npdm` file in the exefs directory specifying the title's permissions.
+
+Atmosphère extends this functionality by also searching for these files on the SD card. When searching for a file, loader will first check if it exists on the SD card. If it does, that file will be used instead. Otherwise, it will use the copy located in the exefs, if that is present. The following directory will be searched.
+
+```
+sdmc:/atmosphere/titles//exefs/
+```
+
+This allows the replacement of applets, sysmodules, or even games with homebrew versions.
+
+In order to prevent an NSO from being loaded even if it exists in the exefs, loader will also check if a stub file exists. If such a file exists, the NSO will not be loaded. The files should be named like `rtld.stub`, `main.stub`, etc. and may be empty.
+
+### NSO Patching
+
+TODO: details on buttons affecting this.
+
+When an NSO is loaded, the stratosphere implementatin of loader will search for IPS patch files on the SD card in the following locations.
+```
+sdmc:/atmosphere/exefs_patches//.ips
+```
+This organization allows patchsets affecting multiple NSOs to be distributed as a single directory. Patches will be searched for in each patchset directory. The name of each patch file should match the hexadecimal build ID of the NSO to affect, except that trailing zero bytes may be left off. Because the NSO build ID is unique for every NSO, this means patches will only apply to the files they are meant to apply to.
+
+Patch files are accepted in either IPS format or IPS32 format.
+
+Because NSO files are compressed, patch files are not made between the original version of a compressed NSO and the modified version of such an NSO. Instead, they are made between the uncompressed version of an NSO and the modified (and still uncompressed) version of that NSO. This also means that a patch file cannot be manually applied to the compressed version of an NSO; it must be applied to the uncompressed version. The Stratosphere implementation of loader will correctly apply these patches while loading the process regardless of whether the NSO it finds is compressed or not.
+
+When authoring patches, [hactool](https://github.com/SciresM/hactool) can be used to find an NSO's build ID and to uncompress NSOs. Recent versions of the [ReSwitched IDA loaders](https://github.com/reswitched/loaders) can be used to load uncompressed NSOs into IDA in such a way that you can [apply patches to the input file](https://www.hex-rays.com/products/ida/support/idadoc/1618.shtml). From there, any IPS tool can be used to create the patch between the original NSO and the patched NSO. Note that if the NSO you are patching is larger than 16 MiB, you will have to use a tool that supports IPS32.
+
+### HBL Support
+
+Atmosphère can use the loader module in order to turn any game on your Switch's home menu into a launchpoint for the Homebrew Menu, rather than launching it through the album applet. This allows one to launch the Homebrew Menu with access to the ~3.2GB of RAM that the Switch reserves for games and applications, as opposed to the 442MB of RAM we are limited to when launching the Homebrew Menu from the album. This also means that it is no longer necessary to install homebrew as `.nsp` files on your Switch so long as you are using this method, as the only reason to do so is to allow the homebrew to access all of the Switch's available memory.
+
+In order to setup this method you will need the latest release of [hbmenu](https://github.com/switchbrew/nx-hbmenu/releases), and the latest release of [hbloader](https://github.com/switchbrew/nx-hbloader/releases). Place `hbmenu.nro` on the root of your Switch's SD Card, and place `hbl.nsp` in the atmosphere folder. From there, simply configure `loader.ini` in the atmosphere folder by replacing the Title ID in the ini (title_id in the [hbl_config] section) (it is the Title ID for the album by default) with the Title ID of whatever game you wish to use to launch the Homebrew Menu. A list of Title IDs for Switch Games can be found [here](https://switchbrew.org/wiki/Title_list/Games). Afterwards you may reinsert your SD Card into your Switch and boot into Atmosphère as you normally would. You should now be able to boot into the Homebrew Menu by launching your designated game of choice.
+
+### Button Overrides
+
+By default `loader.ini` is configured to launch the Homebrew Menu when launching the game normally, and launching the game when selecting the game while holding down R. If you wish to change this, you can modify the override_key section of `loader.ini`. Placing an exclamation point in front of whatever button you wish to use will make it so that you will only launch the actual game while holding down that button, otherwise you will go into the Homebrew Menu. Removing the exclamation point will reverse this, meaning that you will boot into the Homebrew Menu only while holding down the assigned button when launching the game.
+
+For example, `override_key=!R` will run the game only while holding down R when launching it, otherwise it will boot into the Homebrew Menu. `override_key=R` will only boot into the Homebrew Menu while holding down R when launching the game, otherwise it will launch the game as normal.
+
+### SM MITM Integration
+
+When the Stratosphere implementation of loader creates a new process, it notifies [sm](sm.md) through the `AtmosphereAssociatePidTidForMitm` command to notify any MITM services of new processes' identities.
+
+### IPC: AtmosphereSetExternalContentSource and AtmosphereClearExternalContentSource
+
+Two additional commands are added to the [`ldr:shel`](https://reswitched.github.io/SwIPC/ifaces.html#nn::ro::detail::ILdrShellInterface) interface, called `AtmosphereSetExternalContentSource` and `AtmosphereClearExternalContentSource`.
+Their command IDs are `65000` and `65001` on all system firmware versions.
+
+`AtmosphereSetExternalContentSource` takes a `u64 tid` and returns a server-side session handle.
+The client is expected to implement the `IFileSystem` interface on the returned handle. The next
+time the title specified by the given title ID is launched, its ExeFS contents will be loaded from
+the custom `IFileSystem` instead of from SD card or original ExeFS. NSOs loaded from external
+content source may still be subject to exefs IPS patches. After the title is launched successfuly,
+the `IFileSystem` is closed and the external content source override is removed. If
+`AtmosphereSetExternalContentSource` is called on a title that already has an external content
+source set for it, the existing one will be removed and replaced with the new one. It is illegal to
+call `AtmosphereSetExternalContentSource` while the title is being launched.
+
+If title launching fails, the external content source remains registered. The
+`AtmosphereClearExternalContentSource` command can be used to clear an external content source if
+title launch fails.
+
+The `IFileSystem` only needs to implement `OpenFile` and `GetFileTimeStampRaw`. The paths received
+by the `IFileSystem`'s `OpenFile` command begin with slashes, as in `/main`, `/rtld`, and `/main.npdm`.
+A result code of 0x202 should be returned if the file does not exist. `GetFileTimeStampRaw` can just
+be a stub. The `IFile`s returned from `OpenFile` only need to implement `Read` and `GetSize`.
+
+The SwIPC definitions for the extension commands follow.
+```
+interface nn::ldr::detail::IShellInterface is ldr:shel {
+ ...
+ [65000] AtmosphereSetExternalContentSource(u64 tid) -> handle ifilesystem_handle;
+ [65001] AtmosphereClearExternalContentSource(u64 tid);
+}
+```
diff --git a/docs/modules/pm.md b/docs/modules/pm.md
new file mode 100644
index 000000000..288fdf355
--- /dev/null
+++ b/docs/modules/pm.md
@@ -0,0 +1,23 @@
+# pm
+
+pm is a reimplementation of Nintendo's process manager. This module is responsible for tracking running processes on the system, and managing resource limits. pm is also required to create and manage processes for homebrew applications.
+
+## Atmosphère Extensions
+
+There are a few ways in which the Stratosphere implementation of pm differs intentionally from the stock pm.
+
+### IPC: AtmosphereGetProcessHandle
+
+The Stratosphere implementation of pm adds an additional command to the [`pm:dmnt`](https://reswitched.github.io/SwIPC/ifaces.html#nn::pm::detail::IDebugMonitorInterface) interface, called `AtmosphereGetProcessHandle`. Its command ID is `65000` on all system firmware versions. It takes a `u64 process_id` and returns a process handle for the specified process, if that process is known. Notable exceptions include KIPs, which are not known to pm. If the specified process cannot be found, error code 0x20F is returned.
+
+The SwIPC definition for this command follows.
+```
+interface nn::pm::detail::IDebugMonitorInterface is pm:dmnt {
+ ...
+ [65000] AtmosphereGetProcessInfo(u64 pid) -> handle process_handle, u64 title_id, u64 storage_id;
+}
+```
+
+### Extra System Memory for Sysmodules
+
+The Stratosphere implementation of pm shrinks the APPLET memory pool by 24 MiB by default, giving this memory to the SYSTEM pool. This allows custom sysmodules to use more memory without hitting the SYSTEM memory limit.
diff --git a/docs/modules/set_mitm.md b/docs/modules/set_mitm.md
new file mode 100644
index 000000000..586f1e840
--- /dev/null
+++ b/docs/modules/set_mitm.md
@@ -0,0 +1,54 @@
+# set_mitm
+set_mitm is a sysmodule that enables intercepting requests to the system settings service.
+
+## Atmosphère Extensions
+
+set_mitm intercepts the `GetFirmwareVersion` command, if the requester is `qlaunch` or `maintenance`.\
+It modifies the `display_version` field of the returned system version, causing the version to display\
+in settings as `#.#.# (AMS #.#.#)`. This allows users to easily verify what version of Atmosphère they are running.
+
+set_mitm also intercepts the `GetSettingsItemValueSize` and `GetSettingsItemValue` commands for all requesters.\
+It does so in order to enable user configuration of system settings, which are parsed from `atmosphere/system_settings.ini` on boot.\
+The format for settings is described below.
+
+### Atmosphère Settings Format
+
+Settings are parsed from the `atmosphere/system_settings.ini` file during the boot process. This file is a normal ini file,\
+with some specific interpretations.
+
+The standard representation of a system setting's identifier takes the form `name!key`. This is represented within\
+`system_settings.ini` as a section `name`, with an entry `key`. For example:
+
+```
+[name]
+key = ...
+```
+
+System settings can have variable types (strings, integral values, byte arrays, etc). To accommodate this, `system_settings.ini`\
+must store values as a `type_identifier!value_store` pair. A number of different types are supported, with identifiers detailed below.\
+Please note that a malformed value string will cause a fatal error to occur on boot. A full example of a custom setting is given below\
+(setting `eupld!upload_enabled = 0`), for posterity:
+
+```
+[eupld]
+upload_enabled = u8!0x0
+```
+
+### Supported Types
+
+* Strings
+ * Type identifiers: `str`, `string`
+ * The value string is used directly as the setting, with null terminator appended.
+* Integral types
+ * Type identifiers: `u8`, `u16`, `u32`, `u64`
+ * The value string is parsed via a call to `strtoul(value, NULL, 0)`.
+ * Setting bitwidth is determined by the identifier (8 for 1 byte, 16 for 2 bytes, and so on).
+* Raw bytes
+ * Type identifiers: `hex`, `bytes`
+ * The value string is parsed as a hexadecimal string.
+ * The value string must be of even length, or a fatal error will be thrown on parse.
+
+### Atmosphère Custom Settings
+
+At present, Atmosphère implements no custom settings. However, this is subject to change in the future, and any\
+custom settings will be documented here as they are added.
diff --git a/docs/modules/sm.md b/docs/modules/sm.md
new file mode 100644
index 000000000..79d5e800f
--- /dev/null
+++ b/docs/modules/sm.md
@@ -0,0 +1,125 @@
+# sm
+
+sm is a reimplementation of Nintendo's service manager. It allows Atmosphère to add or remove process handle limits, add new services, or intercept service calls. This allows high-level intercepting of Horizon OS functionality.
+
+## Atmosphère Extensions
+
+There are a few ways in which the Stratosphere implementation of sm differs intentionally from the stock sm.
+
+### IPC: MITM Commands
+
+The Stratosphere implementation of sm adds a few additional commands to the [`sm:`](https://reswitched.github.io/SwIPC/ifaces.html#nn::sm::detail::IUserInterface) port session.
+
+Their SwIPC definitions follow.
+```
+interface nn::sm::detail::IUserInterface is sm: {
+ ...
+ [65000] AtmosphereInstallMitm(ServiceName service) -> handle service, handle query;
+ [65001] AtmosphereUninstallMitm(ServiceName service);
+ [65002] AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid);
+}
+```
+
+Additionally, an interface `sm:dmnt` has been created to allow a debug monitor to query sm's state.
+
+Its SwIPC definition follows.
+```
+interface nn::sm::detail::IDebugMonitorInterface is sm:dmnt {
+ [65000] AtmosphereGetServiceRecord(ServiceName name) -> SmServiceRecord;
+ [65001] AtmosphereListServiceRecords(u64 offset) -> buffer, u64 count;
+ [65002] AtmosphereGetServiceRecordSize() -> u64 record_size;
+}
+```
+
+
+#### AtmosphereInstallMitm
+
+This command alters the registration for the named service, in order to allow services to intercept communication between client processes and their intended services. It is used by [fs_mitm](fs_mitm.md).
+
+It takes the name of the service to install an MITM for, and returns two handles. The first is a port handle, similar to those returned from the [RegisterService](https://reswitched.github.io/SwIPC/ifaces.html#nn::sm::detail::IUserInterface(2)) command. The second is the server side of a session, called the query session. This session will used by sm to determine whether or not a new session should be intercepted, and to inform the MITM service of the identity of new processes.
+
+The query session is expected to implement the following interface.
+```
+interface MitmQueryService {
+ [65000] ShouldMitm(u64 pid) -> u64 should_mitm;
+ [65001] AssociatePidTid(u64 pid, u64 tid);
+}
+```
+
+The `ShouldMitm` command is invoked whenever a process attempts to make a new connection to the MITM'd service. It should return `0` if the process's connection should not be intercepted. Any other value will cause the process's connection to be intercepted. If the command returns an error code, the process's connection will not be intercepted.
+
+The `AssociatePidTid` command is invoked on all MITM query sessions whenever a new process is created, in order to inform those services of the identity of a newly created process before it attempts to connect to any services.
+
+If the process that installed the MITM attempts to connect to the service, it will always connect to the original service.
+
+This command requires that the session be initialized, returning error code 0x415 if it is not.\
+If the given service name is invalid, error code 0xC15 is returned.\
+If the user does not have service registration permission for the named service, error code 0x1015 is returned.\
+If the service already has an MITM installed, error code 0x815 is returned.\
+If the service has not yet been registered, the request will be deferred until the service is registered in the same manner as IUserInterface::GetService.
+
+#### AtmosphereUninstallMitm
+
+Removes any installed MITM for the named service.
+
+This command requires that the session be initialized, returning error code 0x415 if it is not.
+
+#### AtmosphereAssociatePidTidForMitm
+
+This command is used internally by the Stratosphere implementation of the [loader](loader.md) sysmodule, when a new process is created. It will call the `AssociatePidTid` command on every registered MITM query session.
+
+If the given process ID refers to a kernel internal process, error code 0x1015 is returned. This command requires that the session be initialized, returning error code 0x415 if it is not.
+
+#### AtmosphereGetServiceRecordSize
+
+Retrieves `sizeof(SmServiceRecord)` for a service. The current format of `SmServiceRecord` structure follows.
+
+```
+struct SmServiceRecord {
+ uint64_t service_name;
+ uint64_t owner_pid;
+ uint64_t max_sessions;
+ uint64_t mitm_pid;
+ uint64_t mitm_waiting_ack_pid;
+ bool is_light;
+ bool mitm_waiting_ack;
+};
+```
+
+#### AtmosphereGetServiceRecord
+
+Retrieves a service registration record for a service.
+
+#### AtmosphereListServiceRecords
+
+Provides a list of service registrations records.
+
+The command will return an array of `SmServiceRecord`s, skipping `offset` records. The number of records returned is indicated by `count`.
+If `count` is less than the size of the buffer divided by `sizeof(SmServiceRecord)` (the buffer was not completely filled), the end of the service registration list has been reached. Otherwise, client code
+should increment `offset` by `count` and call again. Client code should retrieve a record size using `AtmosphereGetServiceRecordSize`, and either make sure that the size of a record matches what it expects,
+or should make sure to use the correct size as the stride while iterating over the array of returned records. Example pseudocode is shown below.
+
+```
+offset = 0;
+record_size = AtmosphereGetServiceRecordSize();
+do {
+ SmServiceRecord records[16];
+ count = AtmosphereListServiceRecords(offset, buffer(records));
+ for (i = 0; i < count; i++) {
+ SmServiceRecord record = {0};
+ memcpy(&record, &records[i], min(record_size, sizeof(SmServiceRecord));
+ /* process record */
+ offset++;
+ }
+} while(count == sizeof(records) / record_size);
+```
+
+### Minimum Session Limit
+
+When a service is registered, the sysmodule registering it must specify a limit on the number of sessions that are allowed to be active for that service at a time. This is used to ensure that services like `fs-pr`, `fs-ldr`, and `ldr:pm` can only be connected to once, adding an additional layer of safety over the regular service verification to ensure that those services are only connected to by the highly priveleged process they are intended to be used by.
+
+By default, the Stratosphere implementation of PM will raise any session limits to at least 8, meaning that for services like `fs-pr` and those mentioned above, up to 8 processes will be able to connect to those sessions, leaving 7 sessions for homebrew to use.
+
+### Weak Service Verification
+
+In system firmware versions before 3.0.1, if a process did not call the [Initialize](https://reswitched.github.io/SwIPC/ifaces.html#nn::sm::detail::IUserInterface(0)) command on its `sm:` session, normally used to inform sm of the process's identity, sm would assume that the process was a kernel internal process and skip any service registration or access checks. The Stratosphere implementation of sm reimplements this vulnerability, allowing homebrew processes to skip service registration and access checks.
diff --git a/docs/roadmap.md b/docs/roadmap.md
new file mode 100644
index 000000000..03367dff9
--- /dev/null
+++ b/docs/roadmap.md
@@ -0,0 +1,16 @@
+# Planned Features
+The following features are planned to be added in future versions of Atmosphère:
++ Thermosphère, a hypervisor-based emunand implementation.
++ A feature-rich debugging toolset (a component of Stratosphère).
+ + A custom debug monitor system module, providing an API for debugging Switch's processes. This may not be a reimplementation of Nintendo's own debug monitor.
+ + This should include a gdbstub implementation, possibly borrowing from Luma3DS's.
+ + This API should be additionally usable for RAM Editing/"Cheat Engine" purposes.
+ + A custom shell system module, providing an means for users to perform various RPC (with support for common/interesting functionality) on their Switch remotely. This may not be a reimplementation of Nintendo's own shell.
+ + This should support client connections over both Wi-Fi and USB.
+ + A custom logging system module, providing a means for other Atmosphère components (and possibly Nintendo's own system modules) to log debug output.
+ + This should support logging to the SD card, over Wi-Fi, and over USB.
++ An application-level plugin system.
+ + This will, ideally, work somewhat like NTR-CFW's plugin system on the 3DS, allowing users to run their own code in a game's process in their own thread.
++ An AR Code/Gameshark analog implementation, allowing for easy sharing/development of cheat codes to run on device.
++ Further extensions to existing Atmosphère components.
++ General system stability improvements to enhance the user's experience.
diff --git a/exosphere/Makefile b/exosphere/Makefile
index 079ae7bd4..4603f7e4a 100644
--- a/exosphere/Makefile
+++ b/exosphere/Makefile
@@ -9,6 +9,13 @@ endif
TOPDIR ?= $(CURDIR)
include $(DEVKITPRO)/devkitA64/base_rules
+AMSBRANCH := $(shell git symbolic-ref --short HEAD)
+AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
+
+ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
+ AMSREV := $(AMSREV)-dirty
+endif
+
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
@@ -20,30 +27,32 @@ TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := src src/dbg
DATA := data
-INCLUDES := include
+INCLUDES := include ../common/include
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
-ARCH := -march=armv8-a -mtune=cortex-a57
-DEFINES := -D__CCPLEX__
+ARCH := -march=armv8-a -mtune=cortex-a57 -mgeneral-regs-only #<- important
+DEFINES := -D__CCPLEX__ -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
CFLAGS := \
-g \
-O2 \
-ffunction-sections \
-fdata-sections \
-fomit-frame-pointer \
+ -fno-asynchronous-unwind-tables \
+ -fno-unwind-tables \
-std=gnu11 \
-Werror \
-Wall \
$(ARCH) $(DEFINES)
-CFLAGS += $(INCLUDE)
+CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH)
-LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
+LDFLAGS = -specs=$(TOPDIR)/linker.specs -nostartfiles -nostdlib -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS :=
@@ -66,14 +75,16 @@ export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
- $(TOPDIR)/bpmpfw
+ $(TOPDIR)/lp0fw \
+ $(TOPDIR)/sc7fw \
+ $(TOPDIR)/rebootstub
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
-BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) bpmpfw.bin
+BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) sc7fw.bin lp0fw.bin rebootstub.bin
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
@@ -100,22 +111,30 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
-.PHONY: $(BUILD) build_bpmpfw clean all
+.PHONY: $(BUILD) build_sc7fw build_lp0fw build_rebootstub clean all
#---------------------------------------------------------------------------------
all: $(BUILD)
-check_bpmpfw:
- @$(MAKE) -C bpmpfw all
+check_sc7fw:
+ @$(MAKE) -C sc7fw all
-$(BUILD): check_bpmpfw
+check_lp0fw:
+ @$(MAKE) -C lp0fw all
+
+check_rebootstub:
+ @$(MAKE) -C rebootstub all
+
+$(BUILD): check_sc7fw check_lp0fw check_rebootstub
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
- @$(MAKE) -C $(TOPDIR)/bpmpfw clean
+ @$(MAKE) -C $(TOPDIR)/sc7fw clean
+ @$(MAKE) -C $(TOPDIR)/lp0fw clean
+ @$(MAKE) -C $(TOPDIR)/rebootstub clean
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
diff --git a/exosphere/bpmpfw/src/lp0.h b/exosphere/bpmpfw/src/lp0.h
deleted file mode 100644
index 81049933b..000000000
--- a/exosphere/bpmpfw/src/lp0.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef EXOSPHERE_BPMPFW_LP0_H
-#define EXOSPHERE_BPMPFW_LP0_H
-
-#include "utils.h"
-
-void lp0_entry_main(void);
-
-void reboot(void);
-
-#endif
diff --git a/exosphere/bpmpfw/src/start.s b/exosphere/bpmpfw/src/start.s
deleted file mode 100644
index c6a0ac794..000000000
--- a/exosphere/bpmpfw/src/start.s
+++ /dev/null
@@ -1,24 +0,0 @@
-.section .text.start
-.align 4
-.global _start
-_start:
- b crt0
-.global _reboot
- b reboot
-
-.global crt0
-.type crt0, %function
-crt0:
- @ setup to call lp0_entry_main
- msr cpsr_cxsf, #0xD3
- ldr sp, =__stack_top__
- ldr lr, =reboot
- b lp0_entry_main
-
-
-.global spinlock_wait
-.type spinlock_wait, %function
-spinlock_wait:
- subs r0, r0, #1
- bgt spinlock_wait
- bx lr
diff --git a/exosphere/bpmpfw/src/timer.h b/exosphere/bpmpfw/src/timer.h
deleted file mode 100644
index c2906a3fe..000000000
--- a/exosphere/bpmpfw/src/timer.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef EXOSPHERE_BPMPFW_TIMER_H
-#define EXOSPHERE_BPMPFW_TIMER_H
-
-#include "utils.h"
-
-#define TIMERUS_CNTR_1US_0 MAKE_REG32(0x60005010)
-
-static inline void timer_wait(uint32_t microseconds) {
- uint32_t old_time = TIMERUS_CNTR_1US_0;
- while (TIMERUS_CNTR_1US_0 - old_time <= microseconds) {
- /* Spin-lock. */
- }
-}
-
-void spinlock_wait(uint32_t count);
-
-#endif
diff --git a/exosphere/bpmpfw/src/utils.h b/exosphere/bpmpfw/src/utils.h
deleted file mode 100644
index d3eff9b4c..000000000
--- a/exosphere/bpmpfw/src/utils.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef EXOSPHERE_BPMPFW_UTILS_H
-#define EXOSPHERE_BPMPFW_UTILS_H
-
-#include
-#include
-#include
-
-#define BIT(n) (1u << (n))
-#define BITL(n) (1ull << (n))
-#define MASK(n) (BIT(n) - 1)
-#define MASKL(n) (BITL(n) - 1)
-#define MASK2(a,b) (MASK(a) & ~MASK(b))
-#define MASK2L(a,b) (MASKL(a) & ~MASKL(b))
-
-#define MAKE_REG32(a) (*(volatile uint32_t *)(a))
-
-#define ALIGN(m) __attribute__((aligned(m)))
-#define PACKED __attribute__((packed))
-
-#define ALINLINE __attribute__((always_inline))
-
-#endif
diff --git a/exosphere/linker.specs b/exosphere/linker.specs
index 300990418..fb0cb34bc 100644
--- a/exosphere/linker.specs
+++ b/exosphere/linker.specs
@@ -2,6 +2,3 @@
*link:
%(old_link) -T %:getenv(TOPDIR /linker.ld) --nmagic --gc-sections
-
-*startfile:
-crti%O%s crtbegin%O%s
diff --git a/exosphere/lp0fw/Makefile b/exosphere/lp0fw/Makefile
new file mode 100644
index 000000000..e8afccfd1
--- /dev/null
+++ b/exosphere/lp0fw/Makefile
@@ -0,0 +1,154 @@
+#---------------------------------------------------------------------------------
+.SUFFIXES:
+#---------------------------------------------------------------------------------
+
+ifeq ($(strip $(DEVKITARM)),)
+$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM")
+endif
+
+TOPDIR ?= $(CURDIR)
+include $(DEVKITARM)/base_rules
+
+#---------------------------------------------------------------------------------
+# TARGET is the name of the output
+# BUILD is the directory where object files & intermediate files will be placed
+# SOURCES is a list of directories containing source code
+# DATA is a list of directories containing data files
+# INCLUDES is a list of directories containing header files
+#---------------------------------------------------------------------------------
+TARGET := $(notdir $(CURDIR))
+BUILD := build
+SOURCES := src
+DATA := data
+INCLUDES := include ../../common/include
+
+#---------------------------------------------------------------------------------
+# options for code generation
+#---------------------------------------------------------------------------------
+ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
+
+CFLAGS := \
+ -g \
+ -O2 \
+ -ffunction-sections \
+ -fdata-sections \
+ -fomit-frame-pointer \
+ -fno-inline \
+ -std=gnu11 \
+ -Werror \
+ -Wall \
+ $(ARCH) $(DEFINES)
+
+CFLAGS += $(INCLUDE) -D__BPMP__
+
+CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
+
+ASFLAGS := -g $(ARCH)
+LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
+
+LIBS :=
+
+#---------------------------------------------------------------------------------
+# list of directories containing libraries, this must be the top level containing
+# include and lib
+#---------------------------------------------------------------------------------
+LIBDIRS :=
+
+
+#---------------------------------------------------------------------------------
+# no real need to edit anything past this point unless you need to add additional
+# rules for different file extensions
+#---------------------------------------------------------------------------------
+ifneq ($(BUILD),$(notdir $(CURDIR)))
+#---------------------------------------------------------------------------------
+
+export OUTPUT := $(CURDIR)/$(TARGET)
+export TOPDIR := $(CURDIR)
+
+export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
+ $(foreach dir,$(DATA),$(CURDIR)/$(dir))
+
+export DEPSDIR := $(CURDIR)/$(BUILD)
+
+CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
+CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
+SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
+BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
+
+#---------------------------------------------------------------------------------
+# use CXX for linking C++ projects, CC for standard C
+#---------------------------------------------------------------------------------
+ifeq ($(strip $(CPPFILES)),)
+#---------------------------------------------------------------------------------
+ export LD := $(CC)
+#---------------------------------------------------------------------------------
+else
+#---------------------------------------------------------------------------------
+ export LD := $(CXX)
+#---------------------------------------------------------------------------------
+endif
+#---------------------------------------------------------------------------------
+
+export OFILES_BIN := $(addsuffix .o,$(BINFILES))
+export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
+export OFILES := $(OFILES_BIN) $(OFILES_SRC)
+export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
+
+export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
+ $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
+ -I$(CURDIR)/$(BUILD)
+
+export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
+
+.PHONY: $(BUILD) clean all
+
+#---------------------------------------------------------------------------------
+all: $(BUILD)
+
+$(BUILD):
+ @[ -d $@ ] || mkdir -p $@
+ @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
+
+#---------------------------------------------------------------------------------
+clean:
+ @echo clean ...
+ @rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
+
+
+#---------------------------------------------------------------------------------
+else
+.PHONY: all
+
+DEPENDS := $(OFILES:.o=.d)
+
+#---------------------------------------------------------------------------------
+# main targets
+#---------------------------------------------------------------------------------
+all : $(OUTPUT).bin
+
+$(OUTPUT).bin : $(OUTPUT).elf
+ $(OBJCOPY) -S -O binary $< $@
+ @echo built ... $(notdir $@)
+
+$(OUTPUT).elf : $(OFILES)
+
+%.elf: $(OFILES)
+ @echo linking $(notdir $@)
+ @$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
+ @$(NM) -CSn $@ > $(notdir $*.lst)
+
+$(OFILES_SRC) : $(HFILES_BIN)
+
+#---------------------------------------------------------------------------------
+# you need a rule like this for each extension you use as binary data
+#---------------------------------------------------------------------------------
+%.bin.o : %.bin
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+-include $(DEPENDS)
+
+#---------------------------------------------------------------------------------------
+endif
+#---------------------------------------------------------------------------------------
diff --git a/exosphere/lp0fw/linker.ld b/exosphere/lp0fw/linker.ld
new file mode 100644
index 000000000..165608360
--- /dev/null
+++ b/exosphere/lp0fw/linker.ld
@@ -0,0 +1,24 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x40010000;
+
+ __start__ = ABSOLUTE(.);
+
+ .text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
+ .rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
+ .bss : ALIGN(8) { __bss_start__ = .; *(.bss* COMMON); . = ALIGN(8); __bss_end__ = .; }
+
+ . = ALIGN(4);
+
+ __end__ = ABSOLUTE(.);
+
+ __total_size__ = (__end__ - __start__);
+ __executable_size__ = (__end__ - _start);
+
+ __stack_top__ = 0x40013000;
+ __stack_bottom__ = 0x40012000;
+}
\ No newline at end of file
diff --git a/exosphere/bpmpfw/linker.specs b/exosphere/lp0fw/linker.specs
similarity index 100%
rename from exosphere/bpmpfw/linker.specs
rename to exosphere/lp0fw/linker.specs
diff --git a/exosphere/lp0fw/src/car.c b/exosphere/lp0fw/src/car.c
new file mode 100644
index 000000000..12f3b7c3c
--- /dev/null
+++ b/exosphere/lp0fw/src/car.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "utils.h"
+#include "car.h"
+#include "timer.h"
+#include "pmc.h"
+#include "emc.h"
+#include "lp0.h"
+
+static inline uint32_t get_special_clk_reg(CarDevice dev) {
+ switch (dev) {
+ case CARDEVICE_UARTA: return 0x178;
+ case CARDEVICE_UARTB: return 0x17C;
+ case CARDEVICE_I2C1: return 0x124;
+ case CARDEVICE_I2C5: return 0x128;
+ case CARDEVICE_ACTMON: return 0x3E8;
+ case CARDEVICE_BPMP: return 0;
+ default: reboot();
+ }
+}
+
+static inline uint32_t get_special_clk_val(CarDevice dev) {
+ switch (dev) {
+ case CARDEVICE_UARTA: return 0;
+ case CARDEVICE_UARTB: return 0;
+ case CARDEVICE_I2C1: return (6 << 29);
+ case CARDEVICE_I2C5: return (6 << 29);
+ case CARDEVICE_ACTMON: return (6 << 29);
+ case CARDEVICE_BPMP: return 0;
+ default: reboot();
+ }
+}
+
+static uint32_t g_clk_reg_offsets[NUM_CAR_BANKS] = {0x010, 0x014, 0x018, 0x360, 0x364, 0x280, 0x298};
+static uint32_t g_rst_reg_offsets[NUM_CAR_BANKS] = {0x004, 0x008, 0x00C, 0x358, 0x35C, 0x28C, 0x2A4};
+
+static uint32_t g_clk_clr_reg_offsets[NUM_CAR_BANKS] = {0x324, 0x32C, 0x334, 0x444, 0x44C, 0x228, 0x2A0};
+
+void car_configure_oscillators(void) {
+ /* Enable the crystal oscillator, setting drive strength to the saved value in PMC. */
+ CLK_RST_CONTROLLER_OSC_CTRL_0 = (CLK_RST_CONTROLLER_OSC_CTRL_0 & 0xFFFFFC0E) | 1 | (((APBDEV_PMC_OSC_EDPD_OVER_0 >> 1) & 0x3F) << 4);
+
+ /* Set CLK_M_DIVISOR to 1 (causes actual division by 2.) */
+ CLK_RST_CONTROLLER_SPARE_REG0_0 = (1 << 2);
+ /* Reading the register after writing it is required to ensure value takes. */
+ (void)(CLK_RST_CONTROLLER_SPARE_REG0_0);
+
+ /* Set TIMERUS_USEC_CFG to cycle at 0x60 / 0x5 = 19.2 MHz. */
+ /* Value is (dividend << 8) | (divisor). */
+ TIMERUS_USEC_CFG_0 = 0x45F;
+}
+
+void car_mbist_workaround(void) {
+ /* This code works around MBIST bug. */
+
+ /* Clear LVL2_CLK_GATE_OVR* registers. */
+ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA_0 = 0;
+ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_0 = 0;
+ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC_0 = 0;
+ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 = 0;
+ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE_0 = 0;
+
+ /* Clear bit patterns in CAR. */
+ /* L: Reset all but RTC, TMR, GPIO, BPMP Cache (CACHE2). */
+ MAKE_CAR_REG(g_clk_clr_reg_offsets[0]) = MAKE_CAR_REG(g_clk_reg_offsets[0]) & 0x7FFFFECF;
+ /* H: Reset all but MC, PMC, FUSE, EMC. */
+ MAKE_CAR_REG(g_clk_clr_reg_offsets[1]) = MAKE_CAR_REG(g_clk_reg_offsets[1]) & 0xFDFFFF3E;
+ /* U: Reset all but CSITE, IRAM[A-D], BPMP Cache RAM (CRAM2). */
+ MAKE_CAR_REG(g_clk_clr_reg_offsets[2]) = MAKE_CAR_REG(g_clk_reg_offsets[2]) & 0xFE0FFDFF;
+ /* V: Reset all but MSELECT, S/PDIF audio doubler, TZRAM, SE. */
+ MAKE_CAR_REG(g_clk_clr_reg_offsets[3]) = MAKE_CAR_REG(g_clk_reg_offsets[3]) & 0x3FBFFFF7;
+ /* W: Reset all but PCIERX[0-5], ENTROPY. */
+ MAKE_CAR_REG(g_clk_clr_reg_offsets[4]) = MAKE_CAR_REG(g_clk_reg_offsets[4]) & 0xFFDFFF03;
+ /* X: Reset all but ETC, MCLK, MCLK2, I2C6, EMC_DLL, GPU, DBGAPB, PLLG_REF, . */
+ MAKE_CAR_REG(g_clk_clr_reg_offsets[5]) = MAKE_CAR_REG(g_clk_reg_offsets[5]) & 0xDCFFB87F;
+ /* Y: Reset all but MC_CDPA, MC_CCPA. */
+ MAKE_CAR_REG(g_clk_clr_reg_offsets[6]) = MAKE_CAR_REG(g_clk_reg_offsets[6]) & 0xFFFFFCFF;
+
+ /* Enable clock to MC1, if CH1 is enabled in EMC. */
+ if (EMC_FBIO_CFG7_0 & 4) { /* CH1_ENABLE */
+ CLK_RST_CONTROLLER_CLK_ENB_W_SET_0 |= 0x40000000; /* SET_CLK_ENB_MC1 */
+ }
+}
+
+void clk_enable(CarDevice dev) {
+ uint32_t special_reg;
+ if ((special_reg = get_special_clk_reg(dev))) {
+ MAKE_CAR_REG(special_reg) = get_special_clk_val(dev);
+ }
+ MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
+}
+
+void clk_disable(CarDevice dev) {
+ MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
+}
+
+void rst_enable(CarDevice dev) {
+ MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
+}
+
+void rst_disable(CarDevice dev) {
+ MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
+}
+
+void clkrst_enable(CarDevice dev) {
+ clk_enable(dev);
+ rst_disable(dev);
+}
+
+void clkrst_disable(CarDevice dev) {
+ rst_enable(dev);
+ clk_disable(dev);
+}
+
+void clkrst_reboot(CarDevice dev) {
+ clkrst_disable(dev);
+ clkrst_enable(dev);
+}
diff --git a/exosphere/lp0fw/src/car.h b/exosphere/lp0fw/src/car.h
new file mode 100644
index 000000000..c762f434f
--- /dev/null
+++ b/exosphere/lp0fw/src/car.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_CLOCK_AND_RESET_H
+#define EXOSPHERE_WARMBOOT_BIN_CLOCK_AND_RESET_H
+
+#include
+
+#define CAR_BASE 0x60006000
+
+#define MAKE_CAR_REG(n) MAKE_REG32(CAR_BASE + n)
+
+#define CLK_RST_CONTROLLER_MISC_CLK_ENB_0 MAKE_CAR_REG(0x048)
+#define CLK_RST_CONTROLLER_OSC_CTRL_0 MAKE_CAR_REG(0x050)
+#define CLK_RST_CONTROLLER_PLLX_BASE_0 MAKE_CAR_REG(0x0E0)
+#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 MAKE_CAR_REG(0x3A4)
+#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET_0 MAKE_CAR_REG(0x450)
+#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR_0 MAKE_CAR_REG(0x454)
+
+#define CLK_RST_CONTROLLER_SUPER_CCLKG_DIVIDER_0 MAKE_CAR_REG(0x36C)
+#define CLK_RST_CONTROLLER_SUPER_CCLKP_DIVIDER_0 MAKE_CAR_REG(0x374)
+
+#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C5_0 MAKE_CAR_REG(0x128)
+
+#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_REF_0 MAKE_CAR_REG(0x62C)
+#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_SOC_0 MAKE_CAR_REG(0x630)
+
+#define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2_0 MAKE_CAR_REG(0x388)
+#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT_0 MAKE_CAR_REG(0x3B4)
+
+#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA_0 MAKE_CAR_REG(0x0F8)
+#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_0 MAKE_CAR_REG(0x0FC)
+#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC_0 MAKE_CAR_REG(0x3A0)
+#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 MAKE_CAR_REG(0x3A4)
+#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE_0 MAKE_CAR_REG(0x554)
+
+#define CLK_RST_CONTROLLER_CCLKG_BURST_POLICY_0 MAKE_CAR_REG(0x368)
+#define CLK_RST_CONTROLLER_CCLKP_BURST_POLICY_0 MAKE_CAR_REG(0x370)
+
+#define CLK_RST_CONTROLLER_RST_DEVICES_H_0 MAKE_CAR_REG(0x008)
+
+#define CLK_RST_CONTROLLER_SPARE_REG0_0 MAKE_CAR_REG(0x55C)
+
+#define CLK_RST_CONTROLLER_RST_DEV_H_SET_0 MAKE_CAR_REG(0x308)
+#define CLK_RST_CONTROLLER_RST_DEV_U_SET_0 MAKE_CAR_REG(0x310)
+
+#define CLK_RST_CONTROLLER_RST_DEV_H_CLR_0 MAKE_CAR_REG(0x30C)
+#define CLK_RST_CONTROLLER_RST_DEV_U_CLR_0 MAKE_CAR_REG(0x314)
+#define CLK_RST_CONTROLLER_RST_DEV_V_CLR_0 MAKE_CAR_REG(0x434)
+
+#define CLK_RST_CONTROLLER_CLK_ENB_L_SET_0 MAKE_CAR_REG(0x320)
+#define CLK_RST_CONTROLLER_CLK_ENB_H_SET_0 MAKE_CAR_REG(0x328)
+#define CLK_RST_CONTROLLER_CLK_ENB_U_SET_0 MAKE_CAR_REG(0x330)
+#define CLK_RST_CONTROLLER_CLK_ENB_V_SET_0 MAKE_CAR_REG(0x440)
+#define CLK_RST_CONTROLLER_CLK_ENB_W_SET_0 MAKE_CAR_REG(0x448)
+#define CLK_RST_CONTROLLER_CLK_ENB_Y_SET_0 MAKE_CAR_REG(0x29C)
+
+#define CLK_RST_CONTROLLER_CLK_ENB_H_CLR_0 MAKE_CAR_REG(0x32C)
+#define CLK_RST_CONTROLLER_CLK_ENB_W_CLR_0 MAKE_CAR_REG(0x44C)
+
+#define NUM_CAR_BANKS 7
+
+typedef enum {
+ CARDEVICE_UARTA = ((0 << 5) | 0x6),
+ CARDEVICE_UARTB = ((0 << 5) | 0x7),
+ CARDEVICE_UARTC = ((1 << 5) | 0x17),
+ CARDEVICE_I2C1 = ((0 << 5) | 0xC),
+ CARDEVICE_I2C5 = ((1 << 5) | 0xF),
+ CARDEVICE_UNK = ((3 << 5) | 0x1E),
+ CARDEVICE_SE = ((3 << 5) | 0x1F),
+ CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
+ CARDEVICE_TSEC = ((2 << 5) | 0x13),
+ CARDEVICE_SOR_SAFE = ((6 << 5) | 0x1E),
+ CARDEVICE_SOR0 = ((5 << 5) | 0x16),
+ CARDEVICE_SOR1 = ((5 << 5) | 0x17),
+ CARDEVICE_KFUSE = ((1 << 5) | 0x8),
+ CARDEVICE_CL_DVFS = ((4 << 5) | 0x1B),
+ CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
+ CARDEVICE_ACTMON = ((3 << 5) | 0x17),
+ CARDEVICE_BPMP = ((0 << 5) | 0x1)
+} CarDevice;
+
+void car_configure_oscillators(void);
+void car_mbist_workaround(void);
+
+void clk_enable(CarDevice dev);
+void clk_disable(CarDevice dev);
+void rst_enable(CarDevice dev);
+void rst_disable(CarDevice dev);
+
+void clkrst_enable(CarDevice dev);
+void clkrst_disable(CarDevice dev);
+
+void clkrst_reboot(CarDevice dev);
+
+#endif
diff --git a/exosphere/lp0fw/src/cluster.c b/exosphere/lp0fw/src/cluster.c
new file mode 100644
index 000000000..bbbc4fd2f
--- /dev/null
+++ b/exosphere/lp0fw/src/cluster.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "utils.h"
+#include "cluster.h"
+#include "car.h"
+#include "timer.h"
+#include "pmc.h"
+#include "misc.h"
+#include "i2c.h"
+#include "flow.h"
+#include "sysreg.h"
+
+static void cluster_pmc_enable_partition(uint32_t mask, uint32_t toggle) {
+ /* Set toggle if unset. */
+ if (!(APBDEV_PMC_PWRGATE_STATUS_0 & mask)) {
+ APBDEV_PMC_PWRGATE_TOGGLE_0 = toggle;
+ }
+
+ /* Wait until toggle set. */
+ while (!(APBDEV_PMC_PWRGATE_STATUS_0 & mask)) { }
+
+ /* Remove clamping. */
+ APBDEV_PMC_REMOVE_CLAMPING_CMD_0 = mask;
+ while (APBDEV_PMC_CLAMP_STATUS_0 & mask) { }
+}
+
+void cluster_initialize_cpu(void) {
+ /* Hold CoreSight in reset. */
+ CLK_RST_CONTROLLER_RST_DEV_U_SET_0 = 0x200;
+
+ /* CAR2PMC_CPU_ACK_WIDTH should be set to 0. */
+ CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2_0 &= 0xFFFFF000;
+
+ /* Restore SB_AA64_RESET values from PMC scratch. */
+ SB_AA64_RESET_LOW_0 = APBDEV_PMC_SECURE_SCRATCH34_0 | 1;
+ SB_AA64_RESET_HIGH_0 = APBDEV_PMC_SECURE_SCRATCH35_0;
+
+ /* Set CDIV_ENB for CCLKG/CCLKP. */
+ CLK_RST_CONTROLLER_SUPER_CCLKG_DIVIDER_0 = 0x80000000;
+ CLK_RST_CONTROLLER_SUPER_CCLKP_DIVIDER_0 = 0x80000000;
+
+ /* Enable CoreSight clock, take CoreSight out of reset. */
+ CLK_RST_CONTROLLER_CLK_ENB_U_SET_0 = 0x200;
+ CLK_RST_CONTROLLER_RST_DEV_U_CLR_0 = 0x200;
+
+ /* Configure MSELECT to divide by 4, enable MSELECT clock. */
+ CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT_0 = 6; /* (6/2) + 1 = 4. */
+ CLK_RST_CONTROLLER_CLK_ENB_V_SET_0 = 0x8;
+
+ /* Wait 2 us, then take MSELECT out of reset. */
+ timer_wait(2);
+ CLK_RST_CONTROLLER_RST_DEV_V_CLR_0 = 0x8;
+
+ /* Set MSELECT WRAP_TO_SLAVE_INCR[0-2], clear ERR_RESP_EN_SLAVE[1-2]. */
+ MSELECT_CONFIG_0 = (MSELECT_CONFIG_0 & 0xFCFFFFFF) | 0x38000000;
+
+ /* Clear PLLX_ENABLE. */
+ CLK_RST_CONTROLLER_PLLX_BASE_0 &= 0xBFFFFFFF;
+
+ /* Clear PMC scratch 190, disable PMC DPD then wait 10 us. */
+ APBDEV_PMC_SCRATCH190_0 &= 0xFFFFFFFE;
+ APBDEV_PMC_DPD_SAMPLE_0 = 0;
+ timer_wait(10);
+
+ /* Configure UART2 via GPIO controller 2 G. */
+ MAKE_REG32(0x6000D108) |= 4; /* GPIO_CNF */
+ MAKE_REG32(0x6000D118) |= 4; /* GPIO_OE */
+ MAKE_REG32(0x6000D128) &= ~4; /* GPIO_OUT */
+
+ /* Set CL_DVFS RSVD0 + TRISTATE, read register to make it stick. */
+ PINMUX_AUX_DVFS_PWM_0 = 0x11;
+ (void)PINMUX_AUX_DVFS_PWM_0;
+
+ /* Configure I2C. */
+ PINMUX_AUX_PWR_I2C_SCL_0 = 0x40;
+ PINMUX_AUX_PWR_I2C_SDA_0 = 0x40;
+
+ /* Enable clock to CL_DVFS, and set its source/divider. */
+ CLK_RST_CONTROLLER_CLK_ENB_W_SET_0 = 0x08000000;
+ CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_REF_0 = 0xE;
+ CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_SOC_0 = 0xE;
+
+ /* Power on I2C5, wait 5 us, set source + take out of reset. */
+ CLK_RST_CONTROLLER_CLK_ENB_H_SET_0 = 0x8000;
+ CLK_RST_CONTROLLER_RST_DEV_H_SET_0 = 0x8000;
+ timer_wait(5);
+ CLK_RST_CONTROLLER_CLK_SOURCE_I2C5_0 = 0x4;
+ CLK_RST_CONTROLLER_RST_DEV_H_CLR_0 = 0x8000;
+
+ /* Enable the PMIC, wait 2ms. */
+ i2c_enable_pmic();
+ timer_wait(2000);
+
+ /* Enable power to the CRAIL partition. */
+ cluster_pmc_enable_partition(1, 0x100);
+
+ /* Remove SW clamp to CRAIL. */
+ APBDEV_PMC_SET_SW_CLAMP_0 = 0;
+ APBDEV_PMC_REMOVE_CLAMPING_CMD_0 = 1;
+ while (APBDEV_PMC_CLAMP_STATUS_0 & 1) { }
+
+ /* Nintendo manually counts down from 8. I am not sure why this happens. */
+ {
+ volatile int32_t counter = 8;
+ while (counter >= 0) {
+ counter--;
+ }
+ }
+
+ /* Power off I2C5. */
+ CLK_RST_CONTROLLER_RST_DEV_H_SET_0 = 0x8000;
+ CLK_RST_CONTROLLER_CLK_ENB_H_CLR_0 = 0x8000;
+
+ /* Disable clock to CL_DVFS */
+ CLK_RST_CONTROLLER_CLK_ENB_W_CLR_0 = 0x08000000;
+
+ /* Perform RAM repair if necessary. */
+ flow_perform_ram_repair();
+
+ /* Enable power to the non-CPU partition. */
+ cluster_pmc_enable_partition(0x8000, 0x10F);
+
+ /* Enable clock to PLLP_OUT_CPU, wait 2 us. */
+ CLK_RST_CONTROLLER_CLK_ENB_Y_SET_0 = 0x80000000;
+ timer_wait(2);
+
+ /* Enable clock to CPU, CPUG, wait 10 us. */
+ CLK_RST_CONTROLLER_CLK_ENB_L_SET_0 = 1;
+ CLK_RST_CONTROLLER_CLK_ENB_V_SET_0 = 1;
+ timer_wait(10);
+
+ /* Set CPU clock sources to PLLP_OUT_0 + state to RUN, wait 10 us. */
+ CLK_RST_CONTROLLER_CCLKG_BURST_POLICY_0 = 0x20004444;
+ CLK_RST_CONTROLLER_CCLKP_BURST_POLICY_0 = 0x20004444;
+ timer_wait(10);
+
+ /* Take non-CPU out of reset (write CLR_NONCPURESET). */
+ CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR_0 = 0x20000000;
+}
+
+void cluster_power_on_cpu(void) {
+ /* Enable power to CE0 partition. */
+ cluster_pmc_enable_partition(0x4000, 0x10E);
+
+ /* Clear CPU reset. */
+ CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR_0 = 0x10001;
+}
\ No newline at end of file
diff --git a/exosphere/lp0fw/src/cluster.h b/exosphere/lp0fw/src/cluster.h
new file mode 100644
index 000000000..5daf26f09
--- /dev/null
+++ b/exosphere/lp0fw/src/cluster.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_CLUSTER_H
+#define EXOSPHERE_WARMBOOT_BIN_CLUSTER_H
+
+#include
+
+#include "utils.h"
+
+#define MSELECT_CONFIG_0 MAKE_REG32(0x50060000)
+
+void cluster_initialize_cpu(void);
+void cluster_power_on_cpu(void);
+
+#endif
diff --git a/exosphere/lp0fw/src/emc.c b/exosphere/lp0fw/src/emc.c
new file mode 100644
index 000000000..a2ffc57c9
--- /dev/null
+++ b/exosphere/lp0fw/src/emc.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "utils.h"
+#include "lp0.h"
+#include "emc.h"
+#include "pmc.h"
+#include "timer.h"
+
+void emc_configure_pmacro_training(void) {
+ /* Set DISABLE_CFG_BYTEN for all N. */
+ EMC_PMACRO_CFG_PM_GLOBAL_0_0 = 0xFF0000;
+
+ /* Set CHN_TRAINING_E_WRPTR for channel 0 + channel 1. */
+ EMC_PMACRO_TRAINING_CTRL_0_0 = 8;
+ EMC_PMACRO_TRAINING_CTRL_1_0 = 8;
+
+ /* Clear DISABLE_CFG_BYTEN for all N. */
+ EMC_PMACRO_CFG_PM_GLOBAL_0_0 = 0x0;
+}
\ No newline at end of file
diff --git a/exosphere/lp0fw/src/emc.h b/exosphere/lp0fw/src/emc.h
new file mode 100644
index 000000000..d9c54d041
--- /dev/null
+++ b/exosphere/lp0fw/src/emc.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_EMC_H
+#define EXOSPHERE_WARMBOOT_BIN_EMC_H
+
+#include "utils.h"
+
+#define EMC_BASE (0x7001B000)
+
+#define EMC0_BASE (0x7001E000)
+#define EMC1_BASE (0x7001F000)
+
+
+#define MAKE_EMC_REG(ofs) (MAKE_REG32(EMC_BASE + ofs))
+
+#define MAKE_EMC0_REG(ofs) (MAKE_REG32(EMC0_BASE + ofs))
+#define MAKE_EMC1_REG(ofs) (MAKE_REG32(EMC1_BASE + ofs))
+
+#define EMC_CFG_0 MAKE_EMC_REG(0x00C)
+
+#define EMC_ADR_CFG_0 MAKE_EMC_REG(0x10)
+
+#define EMC_TIMING_CONTROL_0 MAKE_EMC_REG(0x028)
+
+#define EMC_SELF_REF_0 MAKE_EMC_REG(0x0E0)
+
+#define EMC_MRW_0 MAKE_EMC_REG(0x0E8)
+
+#define EMC_FBIO_CFG5_0 MAKE_EMC_REG(0x104)
+
+#define EMC_MRW3_0 MAKE_EMC_REG(0x138)
+
+#define EMC_AUTO_CAL_CONFIG_0 MAKE_EMC_REG(0x2A4)
+
+#define EMC_REQ_CTRL_0 MAKE_EMC_REG(0x2B0)
+
+#define EMC_EMC_STATUS_0 MAKE_EMC_REG(0x2B4)
+#define EMC0_EMC_STATUS_0 MAKE_EMC0_REG(0x2B4)
+#define EMC1_EMC_STATUS_0 MAKE_EMC1_REG(0x2B4)
+
+#define EMC_CFG_DIG_DLL_0 MAKE_EMC_REG(0x2BC)
+#define EMC0_CFG_DIG_DLL_0 MAKE_EMC0_REG(0x2BC)
+#define EMC1_CFG_DIG_DLL_0 MAKE_EMC1_REG(0x2BC)
+
+#define EMC_ZCAL_INTERVAL_0 MAKE_EMC_REG(0x2E0)
+
+#define EMC_PMC_SCRATCH3_0 MAKE_EMC_REG(0x448)
+
+#define EMC_FBIO_CFG7_0 MAKE_EMC_REG(0x584)
+
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_0 MAKE_EMC_REG(0xC30)
+#define EMC_PMACRO_TRAINING_CTRL_0_0 MAKE_EMC_REG(0xCF8)
+#define EMC_PMACRO_TRAINING_CTRL_1_0 MAKE_EMC_REG(0xCFC)
+
+void emc_configure_pmacro_training(void);
+
+#endif
diff --git a/exosphere/lp0fw/src/flow.c b/exosphere/lp0fw/src/flow.c
new file mode 100644
index 000000000..9fa847936
--- /dev/null
+++ b/exosphere/lp0fw/src/flow.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "utils.h"
+#include "flow.h"
+
+void flow_perform_ram_repair(void) {
+ /* Perform repair only if not active cluster. */
+ if (!(FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 & 1)) {
+ /* Set REQ, to begin RAM repair. */
+ FLOW_CTLR_RAM_REPAIR_0 = 1;
+
+ /* Wait for STS to say RAM repair has completed. */
+ while (!(FLOW_CTLR_RAM_REPAIR_0 & 2)) { }
+ }
+}
\ No newline at end of file
diff --git a/exosphere/lp0fw/src/flow.h b/exosphere/lp0fw/src/flow.h
new file mode 100644
index 000000000..e0bd86ccd
--- /dev/null
+++ b/exosphere/lp0fw/src/flow.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_FLOW_CTLR_H
+#define EXOSPHERE_WARMBOOT_BIN_FLOW_CTLR_H
+
+#include
+#include
+
+#include "utils.h"
+
+#define FLOW_BASE (0x60007000)
+
+#define MAKE_FLOW_REG(ofs) MAKE_REG32(FLOW_BASE + ofs)
+
+#define FLOW_CTLR_HALT_COP_EVENTS_0 MAKE_FLOW_REG(0x004)
+#define FLOW_CTLR_RAM_REPAIR_0 MAKE_FLOW_REG(0x040)
+#define FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 MAKE_FLOW_REG(0x098)
+
+void flow_perform_ram_repair(void);
+
+#endif
diff --git a/exosphere/lp0fw/src/fuse.c b/exosphere/lp0fw/src/fuse.c
new file mode 100644
index 000000000..cad33c8f3
--- /dev/null
+++ b/exosphere/lp0fw/src/fuse.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "utils.h"
+#include "fuse.h"
+#include "car.h"
+#include "pmc.h"
+
+#define NUM_FUSE_BYPASS_ENTRIES 0
+
+bool fuse_check_downgrade_status(void) {
+ /* We aren't going to implement anti-downgrade. */
+ return false;
+}
+
+void fuse_disable_programming(void) {
+ FUSE_REGS->FUSE_DIS_PGM = 1;
+}
+
+static fuse_bypass_data_t g_fuse_bypass_entries[NUM_FUSE_BYPASS_ENTRIES] = {
+ /* No entries here. */
+};
+
+void fuse_configure_fuse_bypass(void) {
+ /* Enable fuses in CAR? This seems to affect fuse data visibility. */
+ CLK_RST_CONTROLLER_MISC_CLK_ENB_0 |= 0x10000000;
+
+ /* Configure bypass/override, only if programming is allowed. */
+ if (!(FUSE_REGS->FUSE_DIS_PGM & 1)) {
+ /* Enable write access. */
+ FUSE_REGS->FUSE_WRITE_ACCESS = (FUSE_REGS->FUSE_WRITE_ACCESS & ~0x1) | 0x10000;
+ /* Enable fuse bypass config. */
+ FUSE_REGS->FUSE_FUSEBYPASS = 1;
+
+ /* Override fuses. */
+ for (size_t i = 0; i < NUM_FUSE_BYPASS_ENTRIES; i++) {
+ MAKE_FUSE_REG(g_fuse_bypass_entries[i].offset) = g_fuse_bypass_entries[i].value;
+ }
+
+ /* Disable fuse write access. */
+ FUSE_REGS->FUSE_WRITE_ACCESS |= 1;
+
+ /* Enable fuse bypass config. */
+ /* I think this is a bug, and Nintendo meant to write 0 here? */
+ FUSE_REGS->FUSE_FUSEBYPASS = 1;
+
+ /* This...clears the disable programming bit(?). */
+ /* I have no idea why this happens. What? */
+ /* This is probably also either a bug or does nothing. */
+ /* Is this bit even clearable? */
+ FUSE_REGS->FUSE_DIS_PGM &= 0xFFFFFFFE;
+
+ /* Restore saved private key disable bit. */
+ FUSE_REGS->FUSE_PRIVATEKEYDISABLE |= (APBDEV_PMC_SECURE_SCRATCH21_0 & 0x10);
+
+ /* Lock private key disable secure scratch. */
+ APBDEV_PMC_SEC_DISABLE2_0 |= 0x4000000;
+ }
+
+}
diff --git a/exosphere/lp0fw/src/fuse.h b/exosphere/lp0fw/src/fuse.h
new file mode 100644
index 000000000..6c3059680
--- /dev/null
+++ b/exosphere/lp0fw/src/fuse.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_FUSE_H
+#define EXOSPHERE_WARMBOOT_BIN_FUSE_H
+
+#include
+#include
+
+#include "utils.h"
+
+typedef struct {
+ uint32_t FUSE_CTRL;
+ uint32_t FUSE_REG_ADDR;
+ uint32_t FUSE_REG_READ;
+ uint32_t FUSE_REG_WRITE;
+ uint32_t FUSE_TIME_RD1;
+ uint32_t FUSE_TIME_RD2;
+ uint32_t FUSE_TIME_PGM1;
+ uint32_t FUSE_TIME_PGM2;
+ uint32_t FUSE_PRIV2INTFC;
+ uint32_t FUSE_FUSEBYPASS;
+ uint32_t FUSE_PRIVATEKEYDISABLE;
+ uint32_t FUSE_DIS_PGM;
+ uint32_t FUSE_WRITE_ACCESS;
+ uint32_t FUSE_PWR_GOOD_SW;
+ uint32_t _0x38[0x32];
+} fuse_registers_t;
+
+typedef struct {
+ uint32_t FUSE_PRODUCTION_MODE;
+ uint32_t _0x4;
+ uint32_t _0x8;
+ uint32_t _0xC;
+ uint32_t FUSE_SKU_INFO;
+ uint32_t FUSE_CPU_SPEEDO_0;
+ uint32_t FUSE_CPU_IDDQ;
+ uint32_t _0x1C;
+ uint32_t _0x20;
+ uint32_t _0x24;
+ uint32_t FUSE_FT_REV;
+ uint32_t FUSE_CPU_SPEEDO_1;
+ uint32_t FUSE_CPU_SPEEDO_2;
+ uint32_t FUSE_SOC_SPEEDO_0;
+ uint32_t FUSE_SOC_SPEEDO_1;
+ uint32_t FUSE_SOC_SPEEDO_2;
+ uint32_t FUSE_SOC_IDDQ;
+ uint32_t _0x44;
+ uint32_t FUSE_FA;
+ uint32_t _0x4C;
+ uint32_t _0x50;
+ uint32_t _0x54;
+ uint32_t _0x58;
+ uint32_t _0x5C;
+ uint32_t _0x60;
+ uint32_t FUSE_PUBLIC_KEY[0x8];
+ uint32_t FUSE_TSENSOR_1;
+ uint32_t FUSE_TSENSOR_2;
+ uint32_t _0x8C;
+ uint32_t FUSE_CP_REV;
+ uint32_t _0x94;
+ uint32_t FUSE_TSENSOR_0;
+ uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG;
+ uint32_t FUSE_SECURITY_MODE;
+ uint32_t FUSE_PRIVATE_KEY[0x4];
+ uint32_t FUSE_DEVICE_KEY;
+ uint32_t _0xB8;
+ uint32_t _0xBC;
+ uint32_t FUSE_RESERVED_SW;
+ uint32_t FUSE_VP8_ENABLE;
+ uint32_t FUSE_RESERVED_ODM[0x8];
+ uint32_t _0xE8;
+ uint32_t _0xEC;
+ uint32_t FUSE_SKU_USB_CALIB;
+ uint32_t FUSE_SKU_DIRECT_CONFIG;
+ uint32_t _0xF8;
+ uint32_t _0xFC;
+ uint32_t FUSE_VENDOR_CODE;
+ uint32_t FUSE_FAB_CODE;
+ uint32_t FUSE_LOT_CODE_0;
+ uint32_t FUSE_LOT_CODE_1;
+ uint32_t FUSE_WAFER_ID;
+ uint32_t FUSE_X_COORDINATE;
+ uint32_t FUSE_Y_COORDINATE;
+ uint32_t _0x11C;
+ uint32_t _0x120;
+ uint32_t FUSE_SATA_CALIB;
+ uint32_t FUSE_GPU_IDDQ;
+ uint32_t FUSE_TSENSOR_3;
+ uint32_t _0x130;
+ uint32_t _0x134;
+ uint32_t _0x138;
+ uint32_t _0x13C;
+ uint32_t _0x140;
+ uint32_t _0x144;
+ uint32_t FUSE_OPT_SUBREVISION;
+ uint32_t _0x14C;
+ uint32_t _0x150;
+ uint32_t FUSE_TSENSOR_4;
+ uint32_t FUSE_TSENSOR_5;
+ uint32_t FUSE_TSENSOR_6;
+ uint32_t FUSE_TSENSOR_7;
+ uint32_t FUSE_OPT_PRIV_SEC_DIS;
+ uint32_t FUSE_PKC_DISABLE;
+ uint32_t _0x16C;
+ uint32_t _0x170;
+ uint32_t _0x174;
+ uint32_t _0x178;
+ uint32_t _0x17C;
+ uint32_t FUSE_TSENSOR_COMMON;
+ uint32_t _0x184;
+ uint32_t _0x188;
+ uint32_t _0x18C;
+ uint32_t _0x190;
+ uint32_t _0x194;
+ uint32_t _0x198;
+ uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
+ uint32_t _0x1A0;
+ uint32_t _0x1A4;
+ uint32_t _0x1A8;
+ uint32_t _0x1AC;
+ uint32_t _0x1B0;
+ uint32_t _0x1B4;
+ uint32_t _0x1B8;
+ uint32_t _0x1BC;
+ uint32_t _0x1D0;
+ uint32_t FUSE_TSENSOR_8;
+ uint32_t _0x1D8;
+ uint32_t _0x1DC;
+ uint32_t _0x1E0;
+ uint32_t _0x1E4;
+ uint32_t _0x1E8;
+ uint32_t _0x1EC;
+ uint32_t _0x1F0;
+ uint32_t _0x1F4;
+ uint32_t _0x1F8;
+ uint32_t _0x1FC;
+ uint32_t _0x200;
+ uint32_t FUSE_RESERVED_CALIB;
+ uint32_t _0x208;
+ uint32_t _0x20C;
+ uint32_t _0x210;
+ uint32_t _0x214;
+ uint32_t _0x218;
+ uint32_t FUSE_TSENSOR_9;
+ uint32_t _0x220;
+ uint32_t _0x224;
+ uint32_t _0x228;
+ uint32_t _0x22C;
+ uint32_t _0x230;
+ uint32_t _0x234;
+ uint32_t _0x238;
+ uint32_t _0x23C;
+ uint32_t _0x240;
+ uint32_t _0x244;
+ uint32_t _0x248;
+ uint32_t _0x24C;
+ uint32_t FUSE_USB_CALIB_EXT;
+ uint32_t _0x254;
+ uint32_t _0x258;
+ uint32_t _0x25C;
+ uint32_t _0x260;
+ uint32_t _0x264;
+ uint32_t _0x268;
+ uint32_t _0x26C;
+ uint32_t _0x270;
+ uint32_t _0x274;
+ uint32_t _0x278;
+ uint32_t _0x27C;
+ uint32_t FUSE_SPARE_BIT[0x20];
+} fuse_chip_registers_t;
+
+#define FUSE_REGS ((volatile fuse_registers_t *)(0x7000F800))
+#define FUSE_CHIP_REGS ((volatile fuse_chip_registers_t *)(0x7000F900))
+
+#define MAKE_FUSE_REG(n) MAKE_REG32(0x7000F800 + n)
+
+typedef struct {
+ uint32_t offset;
+ uint32_t value;
+} fuse_bypass_data_t;
+
+bool fuse_check_downgrade_status(void);
+
+void fuse_configure_fuse_bypass(void);
+
+void fuse_disable_programming(void);
+
+#endif
diff --git a/exosphere/lp0fw/src/i2c.c b/exosphere/lp0fw/src/i2c.c
new file mode 100644
index 000000000..b7fafd932
--- /dev/null
+++ b/exosphere/lp0fw/src/i2c.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "i2c.h"
+#include "timer.h"
+
+/* Prototypes for internal commands. */
+void i2c_set_test_master_config_load(void);
+void i2c_write(unsigned int device, uint32_t val, unsigned int num_bytes);
+void i2c_send_byte_command(unsigned int device, unsigned char reg, unsigned char b);
+
+/* Load hardware config for I2C5. */
+void i2c_set_test_master_config_load(void) {
+ /* Set MSTR_CONFIG_LOAD. */
+ I2C_I2C_CONFIG_LOAD_0 = 0x1;
+
+ while (I2C_I2C_CONFIG_LOAD_0 & 1) {
+ /* Wait forever until it's unset. */
+ }
+}
+
+/* Writes a value to an i2c device. */
+void i2c_write(unsigned int device, uint32_t val, unsigned int num_bytes) {
+ if (num_bytes > 4) {
+ return;
+ }
+
+ /* Set device for 7-bit mode. */
+ I2C_I2C_CMD_ADDR0_0 = device << 1;
+
+ /* Load in data to write. */
+ I2C_I2C_CMD_DATA1_0 = val;
+
+ /* Set config with LENGTH = num_bytes, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
+ I2C_I2C_CNFG_0 = ((num_bytes << 1) - 2) | 0x2800;
+
+ i2c_set_test_master_config_load();
+
+ /* Config |= SEND; */
+ I2C_I2C_CNFG_0 = ((num_bytes << 1) - 2) | 0x2800 | 0x200;
+
+
+ while (I2C_I2C_STATUS_0 & 0x100) {
+ /* Wait until not busy. */
+ }
+
+ while (I2C_I2C_STATUS_0 & 0xF) {
+ /* Wait until write successful. */
+ }
+}
+
+/* Writes a byte val to reg for given device. */
+void i2c_send_byte_command(unsigned int device, unsigned char reg, unsigned char b) {
+ uint32_t val = (reg) | (b << 8);
+ /* Write 1 byte (reg) + 1 byte (value) */
+ i2c_write(device, val, 2);
+}
+
+/* Enable the PMIC. */
+void i2c_enable_pmic(void) {
+ /* Write 00 to Device 27 Reg 00. */
+ i2c_send_byte_command(27, 0, 0x80);
+}
diff --git a/exosphere/lp0fw/src/i2c.h b/exosphere/lp0fw/src/i2c.h
new file mode 100644
index 000000000..90c05215b
--- /dev/null
+++ b/exosphere/lp0fw/src/i2c.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_I2C_H
+#define EXOSPHERE_WARMBOOT_BIN_I2C_H
+
+#include "utils.h"
+
+/* I2C_BASE = I2C5. */
+#define I2C_BASE (0x7000D000)
+
+#define MAKE_I2C_REG(ofs) (MAKE_REG32(I2C_BASE + ofs))
+
+#define I2C_I2C_CNFG_0 MAKE_I2C_REG(0x000)
+
+#define I2C_I2C_CMD_ADDR0_0 MAKE_I2C_REG(0x004)
+
+#define I2C_I2C_CMD_DATA1_0 MAKE_I2C_REG(0x00C)
+
+#define I2C_I2C_STATUS_0 MAKE_I2C_REG(0x01C)
+
+#define I2C_INTERRUPT_STATUS_REGISTER_0 MAKE_I2C_REG(0x068)
+
+#define I2C_I2C_CLK_DIVISOR_REGISTER_0 MAKE_I2C_REG(0x06C)
+
+#define I2C_I2C_BUS_CLEAR_CONFIG_0 MAKE_I2C_REG(0x084)
+
+#define I2C_I2C_BUS_CLEAR_STATUS_0 MAKE_I2C_REG(0x088)
+
+
+#define I2C_I2C_CONFIG_LOAD_0 MAKE_I2C_REG(0x08C)
+
+void i2c_enable_pmic(void);
+
+#endif
diff --git a/exosphere/lp0fw/src/lp0.c b/exosphere/lp0fw/src/lp0.c
new file mode 100644
index 000000000..5aaf46987
--- /dev/null
+++ b/exosphere/lp0fw/src/lp0.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "utils.h"
+#include "lp0.h"
+#include "mc.h"
+#include "pmc.h"
+#include "misc.h"
+#include "fuse.h"
+#include "car.h"
+#include "emc.h"
+#include "cluster.h"
+#include "flow.h"
+#include "timer.h"
+#include "secmon.h"
+
+void reboot(void) {
+ /* Write MAIN_RST */
+ APBDEV_PMC_CNTRL_0 = 0x10;
+ while (true) {
+ /* Wait for reboot. */
+ }
+}
+
+void lp0_entry_main(warmboot_metadata_t *meta) {
+ const uint32_t target_firmware = meta->target_firmware;
+ /* Before doing anything else, ensure some sanity. */
+ if (meta->magic != WARMBOOT_MAGIC || target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX) {
+ reboot();
+ }
+
+ /* [4.0.0+] First thing warmboot does is disable BPMP access to memory. */
+ if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_400) {
+ disable_bpmp_access_to_dram();
+ }
+
+ /* Configure debugging depending on FUSE_PRODUCTION_MODE */
+ misc_configure_device_dbg_settings();
+
+ /* Check for downgrade. */
+ /* NOTE: We implemented this as "return false" */
+ if (fuse_check_downgrade_status()) {
+ reboot();
+ }
+
+ if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_300) {
+ /* Nintendo's firmware checks APBDEV_PMC_SECURE_SCRATCH32_0 against a per-warmboot binary value here. */
+ /* We won't bother with that. */
+ if (false /* APBDEV_PMC_SECURE_SCRATCH32_0 == WARMBOOT_MAGIC_NUMBER */) {
+ reboot();
+ }
+ }
+
+ /* TODO: Check that we're running at the correct physical address. */
+
+ /* Setup fuses, disable bypass. */
+ fuse_configure_fuse_bypass();
+
+ /* Configure oscillators/timing in CAR. */
+ car_configure_oscillators();
+
+ /* Restore RAM configuration. */
+ misc_restore_ram_svop();
+ emc_configure_pmacro_training();
+
+ /* Setup clock output for all devices, working around mbist bug. */
+ car_mbist_workaround();
+
+ /* Initialize the CPU cluster. */
+ cluster_initialize_cpu();
+
+ secmon_restore_to_tzram(target_firmware);
+
+ /* Power on the CPU cluster. */
+ cluster_power_on_cpu();
+
+ /* Nintendo clears most of warmboot.bin out of IRAM here. We're not gonna bother. */
+ /* memset( ... ); */
+
+ const uint32_t halt_val = (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_400) ? 0x40000000 : 0x50000000;
+ while (true) {
+ /* Halt the BPMP. */
+ FLOW_CTLR_HALT_COP_EVENTS_0 = halt_val;
+ }
+}
diff --git a/exosphere/lp0fw/src/lp0.h b/exosphere/lp0fw/src/lp0.h
new file mode 100644
index 000000000..04787f0ed
--- /dev/null
+++ b/exosphere/lp0fw/src/lp0.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_LP0_H
+#define EXOSPHERE_WARMBOOT_BIN_LP0_H
+
+#include "utils.h"
+
+/* WBT0 */
+#define WARMBOOT_MAGIC 0x30544257
+
+typedef struct {
+ uint32_t magic;
+ uint32_t target_firmware;
+ uint32_t padding[2];
+} warmboot_metadata_t;
+
+void lp0_entry_main(warmboot_metadata_t *meta);
+
+void __attribute__((noreturn)) reboot(void);
+
+#endif
diff --git a/exosphere/lp0fw/src/mc.c b/exosphere/lp0fw/src/mc.c
new file mode 100644
index 000000000..a26ef285b
--- /dev/null
+++ b/exosphere/lp0fw/src/mc.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "mc.h"
+#include "utils.h"
+
+void disable_bpmp_access_to_dram(void) {
+ /* Modify carveout 4 to prevent BPMP access to dram (TZ will fix it). */
+ volatile security_carveout_t *carveout = (volatile security_carveout_t *)(MC_BASE + 0xC08 + 0x50 * (4 - CARVEOUT_ID_MIN));
+ carveout->paddr_low = 0;
+ carveout->paddr_high = 0;
+ carveout->size_big_pages = 1; /* 128 KiB */
+ carveout->client_access_0 = 0;
+ carveout->client_access_1 = 0;
+ carveout->client_access_2 = 0;
+ carveout->client_access_3 = 0;
+ carveout->client_access_4 = 0;
+ carveout->client_force_internal_access_0 = BIT(CSR_AVPCARM7R);
+ carveout->client_force_internal_access_1 = BIT(CSW_AVPCARM7W);
+ carveout->client_force_internal_access_2 = 0;
+ carveout->client_force_internal_access_3 = 0;
+ carveout->client_force_internal_access_4 = 0;
+ /* Set config to LOCKED, TZ-SECURE, untranslated addresses only. */
+ carveout->config = 0x8F;
+}
diff --git a/exosphere/lp0fw/src/mc.h b/exosphere/lp0fw/src/mc.h
new file mode 100644
index 000000000..647a826c4
--- /dev/null
+++ b/exosphere/lp0fw/src/mc.h
@@ -0,0 +1,614 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_MC_H
+#define EXOSPHERE_WARMBOOT_BIN_MC_H
+
+#include
+
+#define MC_BASE_PHYS 0x70019000
+
+#define MC_BASE (MC_BASE_PHYS)
+#define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n)
+
+#define MC_INTSTATUS 0x0
+#define MC_INTMASK 0x4
+#define MC_ERR_STATUS 0x8
+#define MC_ERR_ADR 0xc
+#define MC_SMMU_CONFIG 0x10
+#define MC_SMMU_TLB_CONFIG 0x14
+#define MC_SMMU_PTC_CONFIG 0x18
+#define MC_SMMU_PTB_ASID 0x1c
+#define MC_SMMU_PTB_DATA 0x20
+#define MC_SMMU_TLB_FLUSH 0x30
+#define MC_SMMU_PTC_FLUSH 0x34
+#define MC_SMMU_AFI_ASID 0x238
+#define MC_SMMU_AVPC_ASID 0x23c
+#define MC_SMMU_PPCS1_ASID 0x298
+#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
+#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
+#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
+#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
+#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
+#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0
+#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
+#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
+#define MC_PCFIFO_CLIENT_CONFIG3 0xddc
+#define MC_PCFIFO_CLIENT_CONFIG4 0xde0
+#define MC_EMEM_CFG 0x50
+#define MC_EMEM_ADR_CFG 0x54
+#define MC_EMEM_ADR_CFG_DEV0 0x58
+#define MC_EMEM_ADR_CFG_DEV1 0x5c
+#define MC_EMEM_ADR_CFG_CHANNEL_MASK 0x60
+#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64
+#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68
+#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c
+#define MC_SECURITY_CFG0 0x70
+#define MC_SECURITY_CFG1 0x74
+#define MC_SECURITY_CFG3 0x9bc
+#define MC_SECURITY_RSV 0x7c
+#define MC_EMEM_ARB_CFG 0x90
+#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
+#define MC_EMEM_ARB_TIMING_RCD 0x98
+#define MC_EMEM_ARB_TIMING_RP 0x9c
+#define MC_EMEM_ARB_TIMING_RC 0xa0
+#define MC_EMEM_ARB_TIMING_RAS 0xa4
+#define MC_EMEM_ARB_TIMING_FAW 0xa8
+#define MC_EMEM_ARB_TIMING_RRD 0xac
+#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
+#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
+#define MC_EMEM_ARB_TIMING_R2R 0xb8
+#define MC_EMEM_ARB_TIMING_W2W 0xbc
+#define MC_EMEM_ARB_TIMING_R2W 0xc0
+#define MC_EMEM_ARB_TIMING_W2R 0xc4
+#define MC_EMEM_ARB_TIMING_RFCPB 0x6c0
+#define MC_EMEM_ARB_TIMING_CCDMW 0x6c4
+#define MC_EMEM_ARB_REFPB_HP_CTRL 0x6f0
+#define MC_EMEM_ARB_REFPB_BANK_CTRL 0x6f4
+#define MC_EMEM_ARB_DA_TURNS 0xd0
+#define MC_EMEM_ARB_DA_COVERS 0xd4
+#define MC_EMEM_ARB_MISC0 0xd8
+#define MC_EMEM_ARB_MISC1 0xdc
+#define MC_EMEM_ARB_MISC2 0xc8
+#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
+#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
+#define MC_EMEM_ARB_NISO_THROTTLE 0x6b0
+#define MC_EMEM_ARB_OVERRIDE 0xe8
+#define MC_EMEM_ARB_RSV 0xec
+#define MC_CLKEN_OVERRIDE 0xf4
+#define MC_TIMING_CONTROL_DBG 0xf8
+#define MC_TIMING_CONTROL 0xfc
+#define MC_STAT_CONTROL 0x100
+#define MC_STAT_STATUS 0x104
+#define MC_STAT_EMC_CLOCK_LIMIT 0x108
+#define MC_STAT_EMC_CLOCK_LIMIT_MSBS 0x10c
+#define MC_STAT_EMC_CLOCKS 0x110
+#define MC_STAT_EMC_CLOCKS_MSBS 0x114
+#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 0x118
+#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 0x158
+#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 0x11c
+#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 0x15c
+#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER 0xa20
+#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER 0xa24
+#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 0x198
+#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 0x1a8
+#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 0x19c
+#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 0x1ac
+#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER 0xa28
+#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER 0xa2c
+#define MC_STAT_EMC_FILTER_SET0_ASID 0x1a0
+#define MC_STAT_EMC_FILTER_SET1_ASID 0x1b0
+#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 0x120
+#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 0x160
+#define MC_STAT_EMC_FILTER_SET0_CLIENT_0 0x128
+#define MC_STAT_EMC_FILTER_SET1_CLIENT_0 0x168
+#define MC_STAT_EMC_FILTER_SET0_CLIENT_1 0x12c
+#define MC_STAT_EMC_FILTER_SET1_CLIENT_1 0x16c
+#define MC_STAT_EMC_FILTER_SET0_CLIENT_2 0x130
+#define MC_STAT_EMC_FILTER_SET1_CLIENT_2 0x170
+#define MC_STAT_EMC_FILTER_SET0_CLIENT_3 0x134
+#define MC_STAT_EMC_FILTER_SET0_CLIENT_4 0xb88
+#define MC_STAT_EMC_FILTER_SET1_CLIENT_3 0x174
+#define MC_STAT_EMC_FILTER_SET1_CLIENT_4 0xb8c
+#define MC_STAT_EMC_SET0_COUNT 0x138
+#define MC_STAT_EMC_SET0_COUNT_MSBS 0x13c
+#define MC_STAT_EMC_SET1_COUNT 0x178
+#define MC_STAT_EMC_SET1_COUNT_MSBS 0x17c
+#define MC_STAT_EMC_SET0_SLACK_ACCUM 0x140
+#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 0x144
+#define MC_STAT_EMC_SET1_SLACK_ACCUM 0x180
+#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 0x184
+#define MC_STAT_EMC_SET0_HISTO_COUNT 0x148
+#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 0x14c
+#define MC_STAT_EMC_SET1_HISTO_COUNT 0x188
+#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 0x18c
+#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 0x150
+#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 0x190
+#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 0x1b8
+#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 0x1bc
+#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 0x1c8
+#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 0x1cc
+#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 0x1c0
+#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 0x1d0
+#define MC_CLIENT_HOTRESET_CTRL 0x200
+#define MC_CLIENT_HOTRESET_CTRL_1 0x970
+#define MC_CLIENT_HOTRESET_STATUS 0x204
+#define MC_CLIENT_HOTRESET_STATUS_1 0x974
+#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208
+#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c
+#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210
+#define MC_EMEM_ARB_ISOCHRONOUS_3 0x214
+#define MC_EMEM_ARB_ISOCHRONOUS_4 0xb94
+#define MC_EMEM_ARB_HYSTERESIS_0 0x218
+#define MC_EMEM_ARB_HYSTERESIS_1 0x21c
+#define MC_EMEM_ARB_HYSTERESIS_2 0x220
+#define MC_EMEM_ARB_HYSTERESIS_3 0x224
+#define MC_EMEM_ARB_HYSTERESIS_4 0xb84
+#define MC_EMEM_ARB_DHYSTERESIS_0 0xbb0
+#define MC_EMEM_ARB_DHYSTERESIS_1 0xbb4
+#define MC_EMEM_ARB_DHYSTERESIS_2 0xbb8
+#define MC_EMEM_ARB_DHYSTERESIS_3 0xbbc
+#define MC_EMEM_ARB_DHYSTERESIS_4 0xbc0
+#define MC_EMEM_ARB_DHYST_CTRL 0xbcc
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xbd0
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xbd4
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xbd8
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xbdc
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xbe0
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xbe4
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xbe8
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xbec
+#define MC_RESERVED_RSV 0x3fc
+#define MC_DISB_EXTRA_SNAP_LEVELS 0x408
+#define MC_APB_EXTRA_SNAP_LEVELS 0x2a4
+#define MC_AHB_EXTRA_SNAP_LEVELS 0x2a0
+#define MC_USBD_EXTRA_SNAP_LEVELS 0xa18
+#define MC_ISP_EXTRA_SNAP_LEVELS 0xa08
+#define MC_AUD_EXTRA_SNAP_LEVELS 0xa10
+#define MC_MSE_EXTRA_SNAP_LEVELS 0x40c
+#define MC_GK2_EXTRA_SNAP_LEVELS 0xa40
+#define MC_A9AVPPC_EXTRA_SNAP_LEVELS 0x414
+#define MC_FTOP_EXTRA_SNAP_LEVELS 0x2bc
+#define MC_JPG_EXTRA_SNAP_LEVELS 0xa3c
+#define MC_HOST_EXTRA_SNAP_LEVELS 0xa14
+#define MC_SAX_EXTRA_SNAP_LEVELS 0x2c0
+#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac
+#define MC_VICPC_EXTRA_SNAP_LEVELS 0xa1c
+#define MC_HDAPC_EXTRA_SNAP_LEVELS 0xa48
+#define MC_AVP_EXTRA_SNAP_LEVELS 0x2a8
+#define MC_USBX_EXTRA_SNAP_LEVELS 0x404
+#define MC_PCX_EXTRA_SNAP_LEVELS 0x2b8
+#define MC_SD_EXTRA_SNAP_LEVELS 0xa04
+#define MC_DFD_EXTRA_SNAP_LEVELS 0xa4c
+#define MC_VE_EXTRA_SNAP_LEVELS 0x2d8
+#define MC_GK_EXTRA_SNAP_LEVELS 0xa00
+#define MC_VE2_EXTRA_SNAP_LEVELS 0x410
+#define MC_SDM_EXTRA_SNAP_LEVELS 0xa44
+#define MC_VIDEO_PROTECT_BOM 0x648
+#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
+#define MC_VIDEO_PROTECT_BOM_ADR_HI 0x978
+#define MC_VIDEO_PROTECT_REG_CTRL 0x650
+#define MC_ERR_VPR_STATUS 0x654
+#define MC_ERR_VPR_ADR 0x658
+#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418
+#define MC_VIDEO_PROTECT_VPR_OVERRIDE1 0x590
+#define MC_IRAM_BOM 0x65c
+#define MC_IRAM_TOM 0x660
+#define MC_IRAM_ADR_HI 0x980
+#define MC_IRAM_REG_CTRL 0x964
+#define MC_EMEM_CFG_ACCESS_CTRL 0x664
+#define MC_TZ_SECURITY_CTRL 0x668
+#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c
+#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO 0x6b4
+#define MC_EMEM_ARB_RING0_THROTTLE_MASK 0x6bc
+#define MC_EMEM_ARB_NISO_THROTTLE_MASK 0x6b8
+#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1 0xb80
+#define MC_SEC_CARVEOUT_BOM 0x670
+#define MC_SEC_CARVEOUT_SIZE_MB 0x674
+#define MC_SEC_CARVEOUT_ADR_HI 0x9d4
+#define MC_SEC_CARVEOUT_REG_CTRL 0x678
+#define MC_ERR_SEC_STATUS 0x67c
+#define MC_ERR_SEC_ADR 0x680
+#define MC_PC_IDLE_CLOCK_GATE_CONFIG 0x684
+#define MC_STUTTER_CONTROL 0x688
+#define MC_RESERVED_RSV_1 0x958
+#define MC_DVFS_PIPE_SELECT 0x95c
+#define MC_AHB_PTSA_MIN 0x4e0
+#define MC_AUD_PTSA_MIN 0x54c
+#define MC_MLL_MPCORER_PTSA_RATE 0x44c
+#define MC_RING2_PTSA_RATE 0x440
+#define MC_USBD_PTSA_RATE 0x530
+#define MC_USBX_PTSA_MIN 0x528
+#define MC_USBD_PTSA_MIN 0x534
+#define MC_APB_PTSA_MAX 0x4f0
+#define MC_JPG_PTSA_RATE 0x584
+#define MC_DIS_PTSA_MIN 0x420
+#define MC_AVP_PTSA_MAX 0x4fc
+#define MC_AVP_PTSA_RATE 0x4f4
+#define MC_RING1_PTSA_MIN 0x480
+#define MC_DIS_PTSA_MAX 0x424
+#define MC_SD_PTSA_MAX 0x4d8
+#define MC_MSE_PTSA_RATE 0x4c4
+#define MC_VICPC_PTSA_MIN 0x558
+#define MC_PCX_PTSA_MAX 0x4b4
+#define MC_ISP_PTSA_RATE 0x4a0
+#define MC_A9AVPPC_PTSA_MIN 0x48c
+#define MC_RING2_PTSA_MAX 0x448
+#define MC_AUD_PTSA_RATE 0x548
+#define MC_HOST_PTSA_MIN 0x51c
+#define MC_MLL_MPCORER_PTSA_MAX 0x454
+#define MC_SD_PTSA_MIN 0x4d4
+#define MC_RING1_PTSA_RATE 0x47c
+#define MC_JPG_PTSA_MIN 0x588
+#define MC_HDAPC_PTSA_MIN 0x62c
+#define MC_AVP_PTSA_MIN 0x4f8
+#define MC_JPG_PTSA_MAX 0x58c
+#define MC_VE_PTSA_MAX 0x43c
+#define MC_DFD_PTSA_MAX 0x63c
+#define MC_VICPC_PTSA_RATE 0x554
+#define MC_GK_PTSA_MAX 0x544
+#define MC_VICPC_PTSA_MAX 0x55c
+#define MC_SDM_PTSA_MAX 0x624
+#define MC_SAX_PTSA_RATE 0x4b8
+#define MC_PCX_PTSA_MIN 0x4b0
+#define MC_APB_PTSA_MIN 0x4ec
+#define MC_GK2_PTSA_MIN 0x614
+#define MC_PCX_PTSA_RATE 0x4ac
+#define MC_RING1_PTSA_MAX 0x484
+#define MC_HDAPC_PTSA_RATE 0x628
+#define MC_MLL_MPCORER_PTSA_MIN 0x450
+#define MC_GK2_PTSA_MAX 0x618
+#define MC_AUD_PTSA_MAX 0x550
+#define MC_GK2_PTSA_RATE 0x610
+#define MC_ISP_PTSA_MAX 0x4a8
+#define MC_DISB_PTSA_RATE 0x428
+#define MC_VE2_PTSA_MAX 0x49c
+#define MC_DFD_PTSA_MIN 0x638
+#define MC_FTOP_PTSA_RATE 0x50c
+#define MC_A9AVPPC_PTSA_RATE 0x488
+#define MC_VE2_PTSA_MIN 0x498
+#define MC_USBX_PTSA_MAX 0x52c
+#define MC_DIS_PTSA_RATE 0x41c
+#define MC_USBD_PTSA_MAX 0x538
+#define MC_A9AVPPC_PTSA_MAX 0x490
+#define MC_USBX_PTSA_RATE 0x524
+#define MC_FTOP_PTSA_MAX 0x514
+#define MC_HDAPC_PTSA_MAX 0x630
+#define MC_SD_PTSA_RATE 0x4d0
+#define MC_DFD_PTSA_RATE 0x634
+#define MC_FTOP_PTSA_MIN 0x510
+#define MC_SDM_PTSA_RATE 0x61c
+#define MC_AHB_PTSA_RATE 0x4dc
+#define MC_SMMU_SMMU_PTSA_MAX 0x460
+#define MC_RING2_PTSA_MIN 0x444
+#define MC_SDM_PTSA_MIN 0x620
+#define MC_APB_PTSA_RATE 0x4e8
+#define MC_MSE_PTSA_MIN 0x4c8
+#define MC_HOST_PTSA_RATE 0x518
+#define MC_VE_PTSA_RATE 0x434
+#define MC_AHB_PTSA_MAX 0x4e4
+#define MC_SAX_PTSA_MIN 0x4bc
+#define MC_SMMU_SMMU_PTSA_MIN 0x45c
+#define MC_ISP_PTSA_MIN 0x4a4
+#define MC_HOST_PTSA_MAX 0x520
+#define MC_SAX_PTSA_MAX 0x4c0
+#define MC_VE_PTSA_MIN 0x438
+#define MC_GK_PTSA_MIN 0x540
+#define MC_MSE_PTSA_MAX 0x4cc
+#define MC_DISB_PTSA_MAX 0x430
+#define MC_DISB_PTSA_MIN 0x42c
+#define MC_SMMU_SMMU_PTSA_RATE 0x458
+#define MC_VE2_PTSA_RATE 0x494
+#define MC_GK_PTSA_RATE 0x53c
+#define MC_PTSA_GRANT_DECREMENT 0x960
+#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
+#define MC_LATENCY_ALLOWANCE_AXIAP_0 0x3a0
+#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
+#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384
+#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc
+#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8
+#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
+#define MC_LATENCY_ALLOWANCE_SE_0 0x3e0
+#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
+#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
+#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
+#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
+#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3d8
+#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
+#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
+#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 0x694
+#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
+#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
+#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
+#define MC_LATENCY_ALLOWANCE_TSECB_0 0x3f0
+#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 0x698
+#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
+#define MC_LATENCY_ALLOWANCE_APE_0 0x3dc
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 0x6a0
+#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4
+#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3e8
+#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
+#define MC_LATENCY_ALLOWANCE_HC_1 0x314
+#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0
+#define MC_LATENCY_ALLOWANCE_NVJPG_0 0x3e4
+#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
+#define MC_LATENCY_ALLOWANCE_ETR_0 0x3ec
+#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
+#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 0x69c
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 0x6a4
+#define MC_LATENCY_ALLOWANCE_SATA_0 0x350
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 0x690
+#define MC_LATENCY_ALLOWANCE_HC_0 0x310
+#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8
+#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac
+#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4
+#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388
+#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328
+#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
+#define MC_MIN_LENGTH_APE_0 0xb34
+#define MC_MIN_LENGTH_DCB_2 0x8a8
+#define MC_MIN_LENGTH_A9AVP_0 0x950
+#define MC_MIN_LENGTH_TSEC_0 0x93c
+#define MC_MIN_LENGTH_DC_1 0x898
+#define MC_MIN_LENGTH_AXIAP_0 0x94c
+#define MC_MIN_LENGTH_ISP2B_0 0x930
+#define MC_MIN_LENGTH_VI2_0 0x944
+#define MC_MIN_LENGTH_DCB_0 0x8a0
+#define MC_MIN_LENGTH_DCB_1 0x8a4
+#define MC_MIN_LENGTH_PPCS_1 0x8f4
+#define MC_MIN_LENGTH_NVJPG_0 0xb3c
+#define MC_MIN_LENGTH_HDA_0 0x8c4
+#define MC_MIN_LENGTH_NVENC_0 0x8d4
+#define MC_MIN_LENGTH_SDMMC_0 0xb18
+#define MC_MIN_LENGTH_ISP2B_1 0x934
+#define MC_MIN_LENGTH_HC_1 0x8c0
+#define MC_MIN_LENGTH_DC_3 0xb20
+#define MC_MIN_LENGTH_AVPC_0 0x890
+#define MC_MIN_LENGTH_VIC_0 0x940
+#define MC_MIN_LENGTH_ISP2_0 0x91c
+#define MC_MIN_LENGTH_HC_0 0x8bc
+#define MC_MIN_LENGTH_SE_0 0xb38
+#define MC_MIN_LENGTH_NVDEC_0 0xb30
+#define MC_MIN_LENGTH_SATA_0 0x8fc
+#define MC_MIN_LENGTH_DC_0 0x894
+#define MC_MIN_LENGTH_XUSB_1 0x92c
+#define MC_MIN_LENGTH_DC_2 0x89c
+#define MC_MIN_LENGTH_SDMMCAA_0 0xb14
+#define MC_MIN_LENGTH_GPU_0 0xb04
+#define MC_MIN_LENGTH_ETR_0 0xb44
+#define MC_MIN_LENGTH_AFI_0 0x88c
+#define MC_MIN_LENGTH_PPCS_0 0x8f0
+#define MC_MIN_LENGTH_ISP2_1 0x920
+#define MC_MIN_LENGTH_XUSB_0 0x928
+#define MC_MIN_LENGTH_MPCORE_0 0x8cc
+#define MC_MIN_LENGTH_TSECB_0 0xb48
+#define MC_MIN_LENGTH_SDMMCA_0 0xb10
+#define MC_MIN_LENGTH_GPU2_0 0xb40
+#define MC_MIN_LENGTH_SDMMCAB_0 0xb1c
+#define MC_MIN_LENGTH_PTC_0 0x8f8
+#define MC_EMEM_ARB_OVERRIDE_1 0x968
+#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0 0x984
+#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1 0x988
+#define MC_EMEM_ARB_STATS_0 0x990
+#define MC_EMEM_ARB_STATS_1 0x994
+#define MC_MTS_CARVEOUT_BOM 0x9a0
+#define MC_MTS_CARVEOUT_SIZE_MB 0x9a4
+#define MC_MTS_CARVEOUT_ADR_HI 0x9a8
+#define MC_MTS_CARVEOUT_REG_CTRL 0x9ac
+#define MC_ERR_MTS_STATUS 0x9b0
+#define MC_ERR_MTS_ADR 0x9b4
+#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
+#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
+#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 0xd74
+#define MC_SECURITY_CARVEOUT4_CFG0 0xcf8
+#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 0xd10
+#define MC_SECURITY_CARVEOUT4_SIZE_128KB 0xd04
+#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 0xc28
+#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 0xc30
+#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 0xc8c
+#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 0xd1c
+#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 0xd70
+#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 0xc2c
+#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 0xd7c
+#define MC_SECURITY_CARVEOUT3_SIZE_128KB 0xcb4
+#define MC_SECURITY_CARVEOUT2_CFG0 0xc58
+#define MC_SECURITY_CARVEOUT1_CFG0 0xc08
+#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 0xc84
+#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 0xc68
+#define MC_SECURITY_CARVEOUT3_BOM 0xcac
+#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 0xc70
+#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 0xd78
+#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 0xc7c
+#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 0xd18
+#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 0xcbc
+#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 0xc38
+#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 0xc34
+#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 0xcc0
+#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 0xd60
+#define MC_SECURITY_CARVEOUT3_CFG0 0xca8
+#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 0xcb8
+#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 0xc88
+#define MC_SECURITY_CARVEOUT2_SIZE_128KB 0xc64
+#define MC_SECURITY_CARVEOUT5_BOM_HI 0xd50
+#define MC_SECURITY_CARVEOUT1_SIZE_128KB 0xc14
+#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 0xd14
+#define MC_SECURITY_CARVEOUT1_BOM 0xc0c
+#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 0xd2c
+#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 0xd68
+#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 0xcc8
+#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 0xd58
+#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 0xd24
+#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 0xcc4
+#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 0xc78
+#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 0xc1c
+#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 0xc18
+#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 0xd28
+#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 0xd5c
+#define MC_SECURITY_CARVEOUT3_BOM_HI 0xcb0
+#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 0xcd8
+#define MC_SECURITY_CARVEOUT2_BOM_HI 0xc60
+#define MC_SECURITY_CARVEOUT4_BOM_HI 0xd00
+#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 0xd64
+#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 0xcdc
+#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 0xc80
+#define MC_SECURITY_CARVEOUT5_SIZE_128KB 0xd54
+#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 0xd20
+#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 0xcd4
+#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 0xd0c
+#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 0xc74
+#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 0xccc
+#define MC_SECURITY_CARVEOUT4_BOM 0xcfc
+#define MC_SECURITY_CARVEOUT5_CFG0 0xd48
+#define MC_SECURITY_CARVEOUT2_BOM 0xc5c
+#define MC_SECURITY_CARVEOUT5_BOM 0xd4c
+#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 0xc24
+#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 0xd6c
+#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 0xcd0
+#define MC_SECURITY_CARVEOUT1_BOM_HI 0xc10
+#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 0xc20
+#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 0xc3c
+#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c
+#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08
+#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
+#define MC_DA_CONFIG0 0x9dc
+
+/* Virtual aliases */
+#define VIRT_MC_SECURITY_CFG3 MAKE_MC_REG(MC_SECURITY_CFG3)
+
+/* Memory Controller clients */
+#define CLIENT_ACCESS_NUM_CLIENTS 32
+typedef enum {
+ /* _ACCESS0 */
+ CSR_PTCR = (0 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0A = (1 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0AB = (2 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0B = (3 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0BB = (4 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0C = (5 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0CB = (6 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_AFIR = (14 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_AVPCARM7R = (15 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAYHC = (16 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAYHCB = (17 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_HDAR = (21 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_HOST1XDMAR = (22 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_HOST1XR = (23 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_NVENCSRD = (28 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_PPCSAHBDMAR = (29 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_PPCSAHBSLVR = (30 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_SATAR = (31 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+
+ /* _ACCESS1 */
+ CSR_VDEBSEVR = (34 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_VDEMBER = (35 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_VDEMCER = (36 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_VDETPER = (37 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_MPCORELPR = (38 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_MPCORER = (39 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_NVENCSWR = (43 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_AFIW = (49 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_AVPCARM7W = (50 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_HDAW = (53 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_HOST1XW = (54 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_MPCORELPW = (56 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_MPCOREW = (57 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_PPCSAHBDMAW = (59 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_PPCSAHBSLVW = (60 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_SATAW = (61 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_VDEBSEVW = (62 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_VDEDBGW = (63 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+
+ /* _ACCESS2 */
+ CSW_VDEMBEW = (64 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_VDETPMW = (65 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_ISPRA = (68 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWA = (70 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWB = (71 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_XUSB_HOSTR = (74 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_XUSB_HOSTW = (75 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_XUSB_DEVR = (76 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_XUSB_DEVW = (77 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_ISPRAB = (78 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWAB = (80 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWBB = (81 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_TSECSRD = (84 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_TSECSWR = (85 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_A9AVPSCR = (86 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_A9AVPSCW = (87 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_GPUSRD = (88 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_GPUSWR = (89 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_DISPLAYT = (90 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+
+ /* _ACCESS3 */
+ CSR_SDMMCRA = (96 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_SDMMCRAA = (97 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_SDMMCR = (98 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_SDMMCRAB = (99 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCWA = (100 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCWAA = (101 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCW = (102 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCWAB = (103 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_VICSRD = (108 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_VICSWR = (109 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_VIW = (114 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_DISPLAYD = (115 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_NVDECSRD = (120 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_NVDECSWR = (121 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_APER = (122 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_APEW = (123 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_NVJPGSRD = (126 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_NVJPGSWR = (127 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+
+ /* _ACCESS4 */
+ CSR_SESRD = (128 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_SESWR = (129 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_AXIAPR = (130 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_AXIAPW = (131 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_ETRR = (132 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_ETRW = (133 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_TSECSRDB = (134 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_TSECSWRB = (135 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_GPUSRD2 = (136 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_GPUSWR2 = (137 - (CLIENT_ACCESS_NUM_CLIENTS * 4))
+} McClient;
+
+/* Memory Controller carveouts */
+#define CARVEOUT_ID_MIN 1
+#define CARVEOUT_ID_MAX 5
+typedef struct {
+ uint32_t config;
+ uint32_t paddr_low;
+ uint32_t paddr_high;
+ uint32_t size_big_pages;
+ uint32_t client_access_0;
+ uint32_t client_access_1;
+ uint32_t client_access_2;
+ uint32_t client_access_3;
+ uint32_t client_access_4;
+ uint32_t client_force_internal_access_0;
+ uint32_t client_force_internal_access_1;
+ uint32_t client_force_internal_access_2;
+ uint32_t client_force_internal_access_3;
+ uint32_t client_force_internal_access_4;
+ uint8_t padding[0x18];
+} security_carveout_t;
+
+void disable_bpmp_access_to_dram(void);
+
+#endif
\ No newline at end of file
diff --git a/exosphere/lp0fw/src/misc.c b/exosphere/lp0fw/src/misc.c
new file mode 100644
index 000000000..9a795d37c
--- /dev/null
+++ b/exosphere/lp0fw/src/misc.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "utils.h"
+#include "misc.h"
+#include "fuse.h"
+#include "sysreg.h"
+#include "pmc.h"
+
+void misc_configure_device_dbg_settings(void) {
+ /* Enable RTCK daisychaining by setting TBE bit. */
+ APB_MISC_PP_CONFIG_CTL_0 = 0x80;
+
+ /* Literally none of this is documented in the TRM, lol. */
+ if (FUSE_CHIP_REGS->FUSE_SECURITY_MODE == 1) {
+ uint32_t secure_boot_val = 0b0100; /* Sets NIDEN for aarch64. */
+ uint32_t misc_val = 0x40;
+ if (APBDEV_PMC_STICKY_BITS_0 & 0x40) {
+ misc_val = 0x0;
+ } else {
+ secure_boot_val = 0b1101; /* Sets SPNIDEN, NIDEN, DBGEN for aarch64. */
+ }
+ SB_PFCFG_0 = (SB_PFCFG_0 & ~0b1111) | secure_boot_val; /* Configures debug bits. */
+ APB_MISC_PP_CONFIG_CTL_0 |= misc_val; /* Undocumented, seems to control invasive debugging/JTAG. */
+ }
+
+ /* Set sticky bits based SECURITY_MODE. */
+ APBDEV_PMC_STICKY_BITS_0 |= FUSE_CHIP_REGS->FUSE_SECURITY_MODE;
+
+ /* Set E_INPUT in PINMUX_AUX_GPIO_PA6_0 */
+ PINMUX_AUX_GPIO_PA6_0 |= 0x40;
+}
+
+void misc_restore_ram_svop(void) {
+ /* This sets CFG2TMC_RAM_SVOP_PDP to 0x2. */
+ APB_MISC_GP_ASDBGREG_0 = (APB_MISC_GP_ASDBGREG_0 & 0xFCFFFFFF) | 0x02000000;
+}
\ No newline at end of file
diff --git a/exosphere/lp0fw/src/misc.h b/exosphere/lp0fw/src/misc.h
new file mode 100644
index 000000000..6fe93d520
--- /dev/null
+++ b/exosphere/lp0fw/src/misc.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_MISC_H
+#define EXOSPHERE_WARMBOOT_BIN_MISC_H
+
+#include
+
+#include "utils.h"
+
+#define MISC_BASE (0x70000000)
+
+#define MAKE_MISC_REG(n) MAKE_REG32(MISC_BASE + n)
+
+#define APB_MISC_PP_CONFIG_CTL_0 MAKE_MISC_REG(0x024)
+
+#define APB_MISC_GP_ASDBGREG_0 MAKE_MISC_REG(0x810)
+
+#define PINMUX_AUX_PWR_I2C_SCL_0 MAKE_MISC_REG(0x30DC)
+#define PINMUX_AUX_PWR_I2C_SDA_0 MAKE_MISC_REG(0x30E0)
+#define PINMUX_AUX_DVFS_PWM_0 MAKE_MISC_REG(0x3184)
+
+#define PINMUX_AUX_GPIO_PA6_0 MAKE_MISC_REG(0x3244)
+
+void misc_configure_device_dbg_settings(void);
+
+void misc_restore_ram_svop(void);
+
+#endif
diff --git a/exosphere/lp0fw/src/pmc.h b/exosphere/lp0fw/src/pmc.h
new file mode 100644
index 000000000..908a55e8f
--- /dev/null
+++ b/exosphere/lp0fw/src/pmc.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_PMC_H
+#define EXOSPHERE_WARMBOOT_BIN_PMC_H
+
+#include "utils.h"
+
+#define PMC_BASE (0x7000E400)
+
+#define MAKE_PMC_REG(ofs) (MAKE_REG32(PMC_BASE + ofs))
+
+#define APBDEV_PMC_CNTRL_0 MAKE_PMC_REG(0x000)
+
+#define APBDEV_PMC_DPD_SAMPLE_0 MAKE_PMC_REG(0x020)
+
+#define APBDEV_PMC_DPD_ENABLE_0 MAKE_PMC_REG(0x024)
+
+#define APBDEV_PMC_CLAMP_STATUS_0 MAKE_PMC_REG(0x02C)
+
+#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x030)
+#define APBDEV_PMC_REMOVE_CLAMPING_CMD_0 MAKE_PMC_REG(0x034)
+#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x038)
+
+#define APBDEV_PMC_SCRATCH12_0 MAKE_PMC_REG(0x080)
+#define APBDEV_PMC_SCRATCH13_0 MAKE_PMC_REG(0x084)
+#define APBDEV_PMC_SCRATCH18_0 MAKE_PMC_REG(0x098)
+#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818)
+
+#define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4)
+
+#define APBDEV_PMC_STICKY_BITS_0 MAKE_PMC_REG(0x2C0)
+#define APBDEV_PMC_SEC_DISABLE2_0 MAKE_PMC_REG(0x2C4)
+#define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8)
+
+#define APBDEV_PMC_SECURE_SCRATCH21_0 MAKE_PMC_REG(0x334)
+#define APBDEV_PMC_SECURE_SCRATCH32_0 MAKE_PMC_REG(0x360)
+#define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_PMC_REG(0x368)
+#define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_PMC_REG(0x36C)
+
+#define APBDEV_PMC_SECURE_SCRATCH112_0 MAKE_PMC_REG(0xB18)
+#define APBDEV_PMC_SECURE_SCRATCH113_0 MAKE_PMC_REG(0xB1C)
+#define APBDEV_PMC_SECURE_SCRATCH114_0 MAKE_PMC_REG(0xB20)
+#define APBDEV_PMC_SECURE_SCRATCH115_0 MAKE_PMC_REG(0xB24)
+
+#define APBDEV_PMC_IO_DPD3_REQ_0 MAKE_PMC_REG(0x45C)
+#define APBDEV_PMC_IO_DPD3_STATUS_0 MAKE_PMC_REG(0x460)
+
+#define APBDEV_PMC_IO_DPD4_REQ_0 MAKE_PMC_REG(0x464)
+#define APBDEV_PMC_IO_DPD4_STATUS_0 MAKE_PMC_REG(0x468)
+
+#define APBDEV_PMC_SET_SW_CLAMP_0 MAKE_PMC_REG(0x47C)
+
+#define APBDEV_PMC_DDR_CNTRL_0 MAKE_PMC_REG(0x4E4)
+
+#endif
diff --git a/exosphere/lp0fw/src/se.c b/exosphere/lp0fw/src/se.c
new file mode 100644
index 000000000..f6ae15816
--- /dev/null
+++ b/exosphere/lp0fw/src/se.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "utils.h"
+#include "lp0.h"
+#include "se.h"
+
+static void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size);
+
+/* Initialize a SE linked list. */
+static void __attribute__((__noinline__)) ll_init(volatile se_ll_t *ll, void *buffer, size_t size) {
+ ll->num_entries = 0; /* 1 Entry. */
+
+ if (buffer != NULL) {
+ ll->addr_info.address = (uint32_t) buffer;
+ ll->addr_info.size = (uint32_t) size;
+ } else {
+ ll->addr_info.address = 0;
+ ll->addr_info.size = 0;
+ }
+}
+
+void se_check_error_status_reg(void) {
+ if (se_get_regs()->ERR_STATUS_REG) {
+ reboot();
+ }
+}
+
+void se_check_for_error(void) {
+ volatile tegra_se_t *se = se_get_regs();
+ if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) {
+ reboot();
+ }
+}
+
+void se_verify_flags_cleared(void) {
+ if (se_get_regs()->FLAGS_REG & 3) {
+ reboot();
+ }
+}
+
+void clear_aes_keyslot(unsigned int keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
+ if (keyslot >= KEYSLOT_AES_MAX) {
+ reboot();
+ }
+
+ /* Zero out the whole keyslot and IV. */
+ for (unsigned int i = 0; i < 0x10; i++) {
+ se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
+ se->AES_KEYTABLE_DATA = 0;
+ }
+}
+
+void clear_rsa_keyslot(unsigned int keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
+ if (keyslot >= KEYSLOT_RSA_MAX) {
+ reboot();
+ }
+
+ /* Zero out the whole keyslot. */
+ for (unsigned int i = 0; i < 0x40; i++) {
+ /* Select Keyslot Modulus[i] */
+ se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
+ se->RSA_KEYTABLE_DATA = 0;
+ }
+ for (unsigned int i = 0; i < 0x40; i++) {
+ /* Select Keyslot Expontent[i] */
+ se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
+ se->RSA_KEYTABLE_DATA = 0;
+ }
+}
+
+void clear_aes_keyslot_iv(unsigned int keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
+ if (keyslot >= KEYSLOT_AES_MAX) {
+ reboot();
+ }
+
+ for (size_t i = 0; i < (0x10 >> 2); i++) {
+ se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
+ se->AES_KEYTABLE_DATA = 0;
+ }
+}
+
+
+void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size) {
+ volatile tegra_se_t *se = se_get_regs();
+ se_ll_t in_ll;
+ se_ll_t out_ll;
+
+ ll_init(&in_ll, (void *)src, src_size);
+ ll_init(&out_ll, dst, dst_size);
+
+ /* Set the LLs. */
+ se->IN_LL_ADDR_REG = (uint32_t)(&in_ll);
+ se->OUT_LL_ADDR_REG = (uint32_t) (&out_ll);
+
+ /* Set registers for operation. */
+ se->ERR_STATUS_REG = se->ERR_STATUS_REG;
+ se->INT_STATUS_REG = se->INT_STATUS_REG;
+ se->OPERATION_REG = op;
+
+ while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
+ se_check_for_error();
+}
+
+/* Secure AES Functionality. */
+void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, size_t src_size) {
+ uint8_t block[0x10] = {0};
+
+ if (src_size > sizeof(block) || dst_size > sizeof(block)) {
+ reboot();
+ }
+
+ /* Load src data into block. */
+ if (src_size != 0) {
+ memcpy(block, src, src_size);
+ }
+
+ /* Trigger AES operation. */
+ se_get_regs()->BLOCK_COUNT_REG = 0;
+ trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
+
+ /* Copy output data into dst. */
+ if (dst_size != 0) {
+ memcpy(dst, block, dst_size);
+ }
+}
+
+void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) {
+ volatile tegra_se_t *se = se_get_regs();
+
+ if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
+ reboot();
+ }
+
+ /* Set configuration high (256-bit vs 128-bit) based on parameter. */
+ se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
+ se->CRYPTO_REG = keyslot << 24 | 0x100;
+ se_perform_aes_block_operation(dst, 0x10, src, 0x10);
+}
+
+void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
+ if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
+ reboot();
+ }
+
+ se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
+ se->CRYPTO_REG = keyslot << 24;
+ se_perform_aes_block_operation(dst, 0x10, src, 0x10);
+}
+
+void shift_left_xor_rb(uint8_t *key) {
+ uint8_t prev_high_bit = 0;
+ for (unsigned int i = 0; i < 0x10; i++) {
+ uint8_t cur_byte = key[0xF - i];
+ key[0xF - i] = (cur_byte << 1) | (prev_high_bit);
+ prev_high_bit = cur_byte >> 7;
+ }
+ if (prev_high_bit) {
+ key[0xF] ^= 0x87;
+ }
+}
+
+void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) {
+ volatile tegra_se_t *se = se_get_regs();
+
+ if (keyslot >= KEYSLOT_AES_MAX) {
+ reboot();
+ }
+
+ /* Generate the derived key, to be XOR'd with final output block. */
+ uint8_t ALIGN(16) derived_key[0x10] = {0};
+ se_aes_ecb_encrypt_block(keyslot, derived_key, sizeof(derived_key), derived_key, sizeof(derived_key), config_high);
+ shift_left_xor_rb(derived_key);
+ if (data_size & 0xF) {
+ shift_left_xor_rb(derived_key);
+ }
+
+ se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
+ se->CRYPTO_REG = (keyslot << 24) | (0x145);
+ clear_aes_keyslot_iv(keyslot);
+
+ unsigned int num_blocks = (data_size + 0xF) >> 4;
+ /* Handle aligned blocks. */
+ if (num_blocks > 1) {
+ se->BLOCK_COUNT_REG = num_blocks - 2;
+ trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
+ se->CRYPTO_REG |= 0x80;
+ }
+
+ /* Create final block. */
+ uint8_t ALIGN(16) last_block[0x10] = {0};
+ if (data_size & 0xF) {
+ memcpy(last_block, data + (data_size & ~0xF), data_size & 0xF);
+ last_block[data_size & 0xF] = 0x80; /* Last block = data || 100...0 */
+ } else if (data_size >= 0x10) {
+ memcpy(last_block, data + data_size - 0x10, 0x10);
+ }
+
+ for (unsigned int i = 0; i < 0x10; i++) {
+ last_block[i] ^= derived_key[i];
+ }
+
+ /* Perform last operation. */
+ se->BLOCK_COUNT_REG = 0;
+ trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
+
+ /* Copy output CMAC. */
+ for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
+ ((uint32_t *)cmac)[i] = ((volatile uint32_t *)se->HASH_RESULT_REG)[i];
+ }
+}
+
+void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size) {
+ se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0x202);
+}
+
+void se_aes_256_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
+ if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) {
+ reboot();
+ }
+
+ se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY) | (0x202 << 16);
+ se->CRYPTO_REG = (keyslot << 24) | 0x66;
+ clear_aes_keyslot_iv(keyslot);
+ se->BLOCK_COUNT_REG = (src_size >> 4) - 1;
+ trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
+}
\ No newline at end of file
diff --git a/exosphere/lp0fw/src/se.h b/exosphere/lp0fw/src/se.h
new file mode 100644
index 000000000..c9de02a99
--- /dev/null
+++ b/exosphere/lp0fw/src/se.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_SE_H
+#define EXOSPHERE_WARMBOOT_BIN_SE_H
+
+#define SE_BASE 0x70012000
+#define MAKE_SE_REG(n) MAKE_REG32(SE_BASE + n)
+
+#define KEYSLOT_SWITCH_LP0TZRAMKEY 0x2
+#define KEYSLOT_SWITCH_SRKGENKEY 0x8
+#define KEYSLOT_SWITCH_PACKAGE2KEY 0x8
+#define KEYSLOT_SWITCH_TEMPKEY 0x9
+#define KEYSLOT_SWITCH_SESSIONKEY 0xA
+#define KEYSLOT_SWITCH_RNGKEY 0xB
+#define KEYSLOT_SWITCH_MASTERKEY 0xC
+#define KEYSLOT_SWITCH_DEVICEKEY 0xD
+
+/* This keyslot was added in 4.0.0. */
+#define KEYSLOT_SWITCH_4XNEWDEVICEKEYGENKEY 0xD
+#define KEYSLOT_SWITCH_4XNEWCONSOLEKEYGENKEY 0xE
+#define KEYSLOT_SWITCH_4XOLDDEVICEKEY 0xF
+
+/* This keyslot was added in 5.0.0. */
+#define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA
+
+#define KEYSLOT_AES_MAX 0x10
+#define KEYSLOT_RSA_MAX 0x2
+
+#define KEYSIZE_AES_MAX 0x20
+#define KEYSIZE_RSA_MAX 0x100
+
+#define ALG_SHIFT (12)
+#define ALG_DEC_SHIFT (8)
+#define ALG_NOP (0 << ALG_SHIFT)
+#define ALG_AES_ENC (1 << ALG_SHIFT)
+#define ALG_AES_DEC ((1 << ALG_DEC_SHIFT) | ALG_NOP)
+#define ALG_RNG (2 << ALG_SHIFT)
+#define ALG_SHA (3 << ALG_SHIFT)
+#define ALG_RSA (4 << ALG_SHIFT)
+
+#define DST_SHIFT (2)
+#define DST_MEMORY (0 << DST_SHIFT)
+#define DST_HASHREG (1 << DST_SHIFT)
+#define DST_KEYTAB (2 << DST_SHIFT)
+#define DST_SRK (3 << DST_SHIFT)
+#define DST_RSAREG (4 << DST_SHIFT)
+
+#define ENCMODE_SHIFT (24)
+#define DECMODE_SHIFT (16)
+#define ENCMODE_SHA256 (5 << ENCMODE_SHIFT)
+
+#define HASH_DISABLE (0x0)
+#define HASH_ENABLE (0x1)
+
+#define OP_ABORT 0
+#define OP_START 1
+#define OP_RESTART 2
+#define OP_CTX_SAVE 3
+#define OP_RESTART_IN 4
+
+#define CTX_SAVE_SRC_SHIFT 29
+#define CTX_SAVE_SRC_STICKY_BITS (0 << CTX_SAVE_SRC_SHIFT)
+#define CTX_SAVE_SRC_KEYTABLE_AES (2 << CTX_SAVE_SRC_SHIFT)
+#define CTX_SAVE_SRC_KEYTABLE_RSA (1 << CTX_SAVE_SRC_SHIFT)
+#define CTX_SAVE_SRC_MEM (4 << CTX_SAVE_SRC_SHIFT)
+#define CTX_SAVE_SRC_SRK (6 << CTX_SAVE_SRC_SHIFT)
+
+#define CTX_SAVE_KEY_LOW_BITS 0
+#define CTX_SAVE_KEY_HIGH_BITS 1
+#define CTX_SAVE_KEY_ORIGINAL_IV 2
+#define CTX_SAVE_KEY_UPDATED_IV 3
+
+#define CTX_SAVE_STICKY_BIT_INDEX_SHIFT 24
+#define CTX_SAVE_KEY_INDEX_SHIFT 8
+#define CTX_SAVE_RSA_KEY_INDEX_SHIFT 16
+#define CTX_SAVE_RSA_KEY_BLOCK_INDEX_SHIFT 12
+
+#define RSA_2048_BYTES 0x100
+
+typedef struct {
+ uint32_t _0x0;
+ uint32_t _0x4;
+ uint32_t OPERATION_REG;
+ uint32_t INT_ENABLE_REG;
+ uint32_t INT_STATUS_REG;
+ uint32_t CONFIG_REG;
+ uint32_t IN_LL_ADDR_REG;
+ uint32_t _0x1C;
+ uint32_t _0x20;
+ uint32_t OUT_LL_ADDR_REG;
+ uint32_t _0x28;
+ uint32_t _0x2C;
+ uint8_t HASH_RESULT_REG[0x20];
+ uint8_t _0x50[0x20];
+ uint32_t CONTEXT_SAVE_CONFIG_REG;
+ uint8_t _0x74[0x18C];
+ uint32_t SHA_CONFIG_REG;
+ uint32_t SHA_MSG_LENGTH_REG;
+ uint32_t _0x208;
+ uint32_t _0x20C;
+ uint32_t _0x210;
+ uint32_t SHA_MSG_LEFT_REG;
+ uint32_t _0x218;
+ uint32_t _0x21C;
+ uint32_t _0x220;
+ uint32_t _0x224;
+ uint8_t _0x228[0x58];
+ uint32_t AES_KEY_READ_DISABLE_REG;
+ uint32_t AES_KEYSLOT_FLAGS[0x10];
+ uint8_t _0x2C4[0x3C];
+ uint32_t _0x300;
+ uint32_t CRYPTO_REG;
+ uint32_t CRYPTO_CTR_REG[4];
+ uint32_t BLOCK_COUNT_REG;
+ uint32_t AES_KEYTABLE_ADDR;
+ uint32_t AES_KEYTABLE_DATA;
+ uint32_t _0x324;
+ uint32_t _0x328;
+ uint32_t _0x32C;
+ uint32_t CRYPTO_KEYTABLE_DST_REG;
+ uint8_t _0x334[0xC];
+ uint32_t RNG_CONFIG_REG;
+ uint32_t RNG_SRC_CONFIG_REG;
+ uint32_t RNG_RESEED_INTERVAL_REG;
+ uint8_t _0x34C[0xB4];
+ uint32_t RSA_CONFIG;
+ uint32_t RSA_KEY_SIZE_REG;
+ uint32_t RSA_EXP_SIZE_REG;
+ uint32_t RSA_KEY_READ_DISABLE_REG;
+ uint32_t RSA_KEYSLOT_FLAGS[2];
+ uint32_t _0x418;
+ uint32_t _0x41C;
+ uint32_t RSA_KEYTABLE_ADDR;
+ uint32_t RSA_KEYTABLE_DATA;
+ uint8_t RSA_OUTPUT[0x100];
+ uint8_t _0x528[0x2D8];
+ uint32_t FLAGS_REG;
+ uint32_t ERR_STATUS_REG;
+ uint32_t _0x808;
+ uint32_t SPARE_0;
+ uint32_t _0x810;
+ uint32_t _0x814;
+ uint32_t _0x818;
+ uint32_t _0x81C;
+ uint8_t _0x820[0x17E0];
+} tegra_se_t;
+
+typedef struct {
+ uint32_t address;
+ uint32_t size;
+} se_addr_info_t;
+
+typedef struct {
+ uint32_t num_entries; /* Set to total entries - 1 */
+ se_addr_info_t addr_info; /* This should really be an array...but for our use case it works. */
+} se_ll_t;
+
+static inline volatile tegra_se_t *se_get_regs(void) {
+ return (volatile tegra_se_t *)SE_BASE;
+}
+
+void se_check_error_status_reg(void);
+void se_check_for_error(void);
+
+void se_verify_flags_cleared(void);
+
+void clear_aes_keyslot(unsigned int keyslot);
+void clear_rsa_keyslot(unsigned int keyslot);
+void clear_aes_keyslot_iv(unsigned int keyslot);
+
+void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size);
+void se_aes_256_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
+
+#endif
diff --git a/exosphere/lp0fw/src/secmon.c b/exosphere/lp0fw/src/secmon.c
new file mode 100644
index 000000000..142e7b447
--- /dev/null
+++ b/exosphere/lp0fw/src/secmon.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "utils.h"
+#include "lp0.h"
+#include "secmon.h"
+#include "se.h"
+#include "fuse.h"
+#include "pmc.h"
+
+/* "private" functions. */
+static bool secmon_should_clear_aes_keyslot(unsigned int keyslot);
+static void secmon_clear_unused_keyslots(void);
+static void secmon_decrypt_saved_image(void *dst, const void *src, size_t size);
+
+void secmon_restore_to_tzram(const uint32_t target_firmware) {
+ /* Newer warmboot binaries clear the untouched keyslots for safety. */
+ if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_500) {
+ secmon_clear_unused_keyslots();
+ }
+
+ /* Decrypt Secure Monitor from DRAM into TZRAM. */
+ void *tzram_src = (void *)(0x80010000);
+ void *tzram_dst = (void *)(target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_500 ? 0x7C012000 : 0x7C010000);
+ const size_t tzram_size = 0xE000;
+ secmon_decrypt_saved_image(tzram_dst, tzram_src, tzram_size);
+
+ /* Nintendo clears DRAM, but I'm not sure why, given they lock out BPMP access to DRAM. */
+ for (size_t i = 0; i < tzram_size/sizeof(uint32_t); i++) {
+ ((volatile uint32_t *)tzram_src)[i] = 0;
+ }
+
+ /* Make security engine require secure busmaster. */
+ se_get_regs()->_0x4 = 0;
+
+ /* TODO: se_verify_keys_unreadable(); */
+
+ /* TODO: pmc_lockout_wb_scratch_registers(); */
+
+ /* Disable fuse programming. */
+ fuse_disable_programming();
+}
+
+void secmon_decrypt_saved_image(void *dst, const void *src, size_t size) {
+ /* First, AES-256-CBC decrypt the image into TZRAM. */
+ se_aes_256_cbc_decrypt(KEYSLOT_SWITCH_LP0TZRAMKEY, dst, size, src, size);
+
+ /* Next, calculate CMAC. */
+ uint32_t tzram_cmac[4] = {0, 0, 0, 0};
+ se_compute_aes_256_cmac(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_cmac, sizeof(tzram_cmac), dst, size);
+
+ /* Validate the MAC against saved one in PMC scratch. */
+ if (tzram_cmac[0] != APBDEV_PMC_SECURE_SCRATCH112_0 ||
+ tzram_cmac[1] != APBDEV_PMC_SECURE_SCRATCH113_0 ||
+ tzram_cmac[2] != APBDEV_PMC_SECURE_SCRATCH114_0 ||
+ tzram_cmac[3] != APBDEV_PMC_SECURE_SCRATCH115_0) {
+ reboot();
+ }
+
+ /* Clear the PMC scratch registers that hold the CMAC. */
+ APBDEV_PMC_SECURE_SCRATCH112_0 = 0;
+ APBDEV_PMC_SECURE_SCRATCH113_0 = 0;
+ APBDEV_PMC_SECURE_SCRATCH114_0 = 0;
+ APBDEV_PMC_SECURE_SCRATCH115_0 = 0;
+
+ /* Clear keyslot now that we're done with it. */
+ clear_aes_keyslot(KEYSLOT_SWITCH_LP0TZRAMKEY);
+}
+
+bool secmon_should_clear_aes_keyslot(unsigned int keyslot) {
+ /* We'll just compare keyslot against a hardcoded list of keys. */
+ static const uint8_t saved_keyslots[6] = {
+ KEYSLOT_SWITCH_LP0TZRAMKEY,
+ KEYSLOT_SWITCH_SESSIONKEY,
+ KEYSLOT_SWITCH_RNGKEY,
+ KEYSLOT_SWITCH_MASTERKEY,
+ KEYSLOT_SWITCH_DEVICEKEY,
+ KEYSLOT_SWITCH_4XOLDDEVICEKEY
+ };
+
+ for (unsigned int i = 0; i < sizeof(saved_keyslots)/sizeof(saved_keyslots[0]); i++) {
+ if (keyslot == saved_keyslots[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void secmon_clear_unused_keyslots(void) {
+ /* Clear unused keyslots. */
+ for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
+ if (secmon_should_clear_aes_keyslot(i)) {
+ clear_aes_keyslot(i);
+ }
+ clear_aes_keyslot_iv(i);
+ }
+ for (unsigned int i = 0; i < KEYSLOT_RSA_MAX; i++) {
+ clear_rsa_keyslot(i);
+ }
+}
diff --git a/exosphere/lp0fw/src/secmon.h b/exosphere/lp0fw/src/secmon.h
new file mode 100644
index 000000000..71daac914
--- /dev/null
+++ b/exosphere/lp0fw/src/secmon.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_SECMON_H
+#define EXOSPHERE_WARMBOOT_BIN_SECMON_H
+
+#include
+
+#include "utils.h"
+
+void secmon_restore_to_tzram(const uint32_t target_firmware);
+
+#endif
diff --git a/exosphere/lp0fw/src/start.s b/exosphere/lp0fw/src/start.s
new file mode 100644
index 000000000..17aab0bfc
--- /dev/null
+++ b/exosphere/lp0fw/src/start.s
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+.section .text.start
+
+/* Warmboot header. */
+/* Binary size */
+.word __total_size__
+.rept 3
+.word 0x00000000
+.endr
+/* RSA modulus */
+.rept 0x40
+.word 0xFFFFFFFF
+.endr
+/* Padding */
+.rept 4
+.word 0x00000000
+.endr
+/* RSA signature */
+.rept 0x40
+.word 0xFFFFFFFF
+.endr
+/* Padding */
+.rept 4
+.word 0x00000000
+.endr
+/* Relocation meta */
+.word __total_size__
+.word _start
+.word _start
+.word __executable_size__
+
+.global _start
+_start:
+ b crt0
+
+.global _metadata
+_metadata:
+ .ascii "WBT0" /* Magic number */
+ .word 0x00000000 /* Target firmware. */
+ .word 0x00000000 /* Reserved */
+ .word 0x00000000 /* Reserved */
+
+.global crt0
+.type crt0, %function
+crt0:
+ @ setup to call lp0_entry_main
+ ldr sp, =__stack_top__
+ ldr lr, =reboot
+ ldr r0, =_metadata
+ b lp0_entry_main
diff --git a/exosphere/lp0fw/src/sysreg.h b/exosphere/lp0fw/src/sysreg.h
new file mode 100644
index 000000000..87e0fc0fa
--- /dev/null
+++ b/exosphere/lp0fw/src/sysreg.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_SYSREG_H
+#define EXOSPHERE_WARMBOOT_BIN_SYSREG_H
+
+#include
+
+
+#define SYSREG_BASE (0x6000C000)
+
+#define SB_BASE (SYSREG_BASE + 0x200)
+
+#define MAKE_SYSREG(n) MAKE_REG32(SYSREG_BASE + n)
+#define MAKE_SB_REG(n) MAKE_REG32(SB_BASE + n)
+
+#define AHB_ARBITRATION_DISABLE_0 MAKE_SYSREG(0x004)
+
+#define SB_CSR_0 MAKE_SB_REG(0x00)
+#define SB_PIROM_START_0 MAKE_SB_REG(0x04)
+#define SB_PFCFG_0 MAKE_SB_REG(0x08)
+#define SB_SECURE_SPAREREG_0_0 MAKE_SB_REG(0x0C)
+#define SB_SECURE_SPAREREG_1_0 MAKE_SB_REG(0x10)
+#define SB_SECURE_SPAREREG_2_0 MAKE_SB_REG(0x14)
+#define SB_SECURE_SPAREREG_3_0 MAKE_SB_REG(0x18)
+#define SB_SECURE_SPAREREG_4_0 MAKE_SB_REG(0x1C)
+#define SB_SECURE_SPAREREG_5_0 MAKE_SB_REG(0x20)
+#define SB_SECURE_SPAREREG_6_0 MAKE_SB_REG(0x24)
+#define SB_SECURE_SPAREREG_7_0 MAKE_SB_REG(0x28)
+#define SB_AA64_RESET_LOW_0 MAKE_SB_REG(0x30)
+#define SB_AA64_RESET_HIGH_0 MAKE_SB_REG(0x34)
+
+#endif
diff --git a/exosphere/lp0fw/src/timer.h b/exosphere/lp0fw/src/timer.h
new file mode 100644
index 000000000..14d3b9afd
--- /dev/null
+++ b/exosphere/lp0fw/src/timer.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_TIMER_H
+#define EXOSPHERE_WARMBOOT_BIN_TIMER_H
+
+#include "utils.h"
+
+#define TIMERUS_CNTR_1US_0 MAKE_REG32(0x60005010)
+#define TIMERUS_USEC_CFG_0 MAKE_REG32(0x60005014)
+
+static inline void timer_wait(uint32_t microseconds) {
+ const uint32_t old_time = TIMERUS_CNTR_1US_0;
+ while (TIMERUS_CNTR_1US_0 - old_time <= microseconds) {
+ /* Spin-lock. */
+ }
+}
+
+void spinlock_wait(uint32_t count);
+
+#endif
diff --git a/exosphere/lp0fw/src/utils.h b/exosphere/lp0fw/src/utils.h
new file mode 100644
index 000000000..f1e43cec6
--- /dev/null
+++ b/exosphere/lp0fw/src/utils.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_WARMBOOT_BIN_UTILS_H
+#define EXOSPHERE_WARMBOOT_BIN_UTILS_H
+
+#include
+#include
+#include
+#include
+
+#define BIT(n) (1u << (n))
+#define BITL(n) (1ull << (n))
+#define MASK(n) (BIT(n) - 1)
+#define MASKL(n) (BITL(n) - 1)
+#define MASK2(a,b) (MASK(a) & ~MASK(b))
+#define MASK2L(a,b) (MASKL(a) & ~MASKL(b))
+
+#define MAKE_REG32(a) (*(volatile uint32_t *)(a))
+
+#define ALIGN(m) __attribute__((aligned(m)))
+#define PACKED __attribute__((packed))
+
+#define ALINLINE __attribute__((always_inline))
+
+#endif
diff --git a/exosphere/bpmpfw/Makefile b/exosphere/rebootstub/Makefile
similarity index 100%
rename from exosphere/bpmpfw/Makefile
rename to exosphere/rebootstub/Makefile
diff --git a/exosphere/rebootstub/linker.ld b/exosphere/rebootstub/linker.ld
new file mode 100644
index 000000000..d2e018d4d
--- /dev/null
+++ b/exosphere/rebootstub/linker.ld
@@ -0,0 +1,18 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x4003F000;
+
+ __start__ = ABSOLUTE(.);
+
+ .text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
+ .rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
+ .bss : ALIGN(8) { __bss_start__ = .; *(.bss* COMMON); . = ALIGN(8); __bss_end__ = .; }
+
+ . = ALIGN(4);
+
+ __end__ = ABSOLUTE(.);
+}
\ No newline at end of file
diff --git a/exosphere/rebootstub/linker.specs b/exosphere/rebootstub/linker.specs
new file mode 100644
index 000000000..300990418
--- /dev/null
+++ b/exosphere/rebootstub/linker.specs
@@ -0,0 +1,7 @@
+%rename link old_link
+
+*link:
+%(old_link) -T %:getenv(TOPDIR /linker.ld) --nmagic --gc-sections
+
+*startfile:
+crti%O%s crtbegin%O%s
diff --git a/exosphere/rebootstub/src/i2c.c b/exosphere/rebootstub/src/i2c.c
new file mode 100644
index 000000000..38fed9091
--- /dev/null
+++ b/exosphere/rebootstub/src/i2c.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "max77620.h"
+#include "i2c.h"
+#include "timer.h"
+
+/* Prototypes for internal commands. */
+void i2c_load_config(void);
+int i2c_write(unsigned int device, uint32_t val, unsigned int num_bytes);
+int i2c_read(unsigned int device, void *dst, unsigned num_bytes);
+int i2c_query(uint8_t device, uint8_t r, void *dst, size_t num_bytes);
+int i2c_send_byte_command(unsigned int device, unsigned char reg, unsigned char b);
+
+/* Load hardware config for I2C4. */
+void i2c_load_config(void) {
+ /* Set MSTR_CONFIG_LOAD, TIMEOUT_CONFIG_LOAD, undocumented bit. */
+ I2C_I2C_CONFIG_LOAD_0 = 0x25;
+
+ /* Wait a bit for master config to be loaded. */
+ for (unsigned int i = 0; i < 20; i++) {
+ timer_wait(1);
+ if (!(I2C_I2C_CONFIG_LOAD_0 & 1)) {
+ break;
+ }
+ }
+}
+
+/* Initialize I2C4. */
+void i2c_init(void) {
+ /* Setup divisor, and clear the bus. */
+ I2C_I2C_CLK_DIVISOR_REGISTER_0 = 0x50001;
+ I2C_I2C_BUS_CLEAR_CONFIG_0 = 0x90003;
+
+ /* Load hardware configuration. */
+ i2c_load_config();
+
+ /* Wait a while until BUS_CLEAR_DONE is set. */
+ for (unsigned int i = 0; i < 10; i++) {
+ timer_wait(20000);
+ if (I2C_INTERRUPT_STATUS_REGISTER_0 & 0x800) {
+ break;
+ }
+ }
+
+ /* Read the BUS_CLEAR_STATUS. Result doesn't matter. */
+ I2C_I2C_BUS_CLEAR_STATUS_0;
+
+ /* Read and set the Interrupt Status. */
+ uint32_t int_status = I2C_INTERRUPT_STATUS_REGISTER_0;
+ I2C_INTERRUPT_STATUS_REGISTER_0 = int_status;
+}
+
+/* Writes a value to an i2c device. */
+int i2c_write(unsigned int device, uint32_t val, unsigned int num_bytes) {
+ if (num_bytes > 4) {
+ return 0;
+ }
+
+ /* Set device for 7-bit mode. */
+ I2C_I2C_CMD_ADDR0_0 = device << 1;
+
+ /* Load in data to write. */
+ I2C_I2C_CMD_DATA1_0 = val;
+
+ /* Set config with LENGTH = num_bytes, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
+ I2C_I2C_CNFG_0 = ((num_bytes << 1) - 2) | 0x2800;
+
+ i2c_load_config();
+
+ /* Config |= SEND; */
+ I2C_I2C_CNFG_0 |= 0x200;
+
+
+ while (I2C_I2C_STATUS_0 & 0x100) {
+ /* Wait until not busy. */
+ }
+
+ /* Return CMD1_STAT == SL1_XFER_SUCCESSFUL. */
+ return (I2C_I2C_STATUS_0 & 0xF) == 0;
+}
+
+/* Reads a value from an i2c device. */
+int i2c_read(unsigned device, void *dst, unsigned num_bytes) {
+ if (num_bytes > 4) {
+ return 0;
+ }
+
+ /* Set device for 7-bit read mode. */
+ I2C_I2C_CMD_ADDR0_0 = (device << 1) | 1;
+
+ /* Set config with LENGTH = num_bytes, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
+ I2C_I2C_CNFG_0 = ((num_bytes << 1) - 2) | 0x2840;
+
+ i2c_load_config();
+
+ /* Config |= SEND; */
+ I2C_I2C_CNFG_0 |= 0x200;
+
+
+ while (I2C_I2C_STATUS_0 & 0x100) {
+ /* Wait until not busy. */
+ }
+
+ /* Ensure success. */
+ if ((I2C_I2C_STATUS_0 & 0xF) != 0) {
+ return 0;
+ }
+
+ uint32_t val = I2C_I2C_CMD_DATA1_0;
+ for (size_t i = 0; i < num_bytes; i++) {
+ ((uint8_t *)dst)[i] = ((uint8_t *)&val)[i];
+ }
+ return 1;
+}
+
+/* Queries the value of a register. */
+int i2c_query(uint8_t device, uint8_t r, void *dst, size_t num_bytes) {
+ /* Limit output size to 32-bits. */
+ if (num_bytes > 4) {
+ return 0;
+ }
+
+ /* Write single byte register ID to device. */
+ if (!i2c_write(device, r, 1)) {
+ return 0;
+ }
+
+ return i2c_read(device, dst, num_bytes);
+
+}
+
+/* Writes a byte val to reg for given device. */
+int i2c_send_byte_command(unsigned int device, unsigned char reg, unsigned char b) {
+ uint32_t val = (reg) | (b << 8);
+ /* Write 1 byte (reg) + 1 byte (value) */
+ return i2c_write(device, val, 2);
+}
+
+void i2c_stop_rtc_alarm(void) {
+ i2c_send_byte_command(MAX77620_RTC_I2C_ADDR, MAX77620_REG_RTCUPDATE0, 0x10);
+
+ uint8_t val = 0;
+ for (int i = 0; i < 14; i++) {
+ if (i2c_query(MAX77620_RTC_I2C_ADDR, 0x0E + i, &val, 1)) {
+ val &= 0x7F;
+ i2c_send_byte_command(MAX77620_RTC_I2C_ADDR, 0x0E + i, val);
+ }
+ }
+
+ i2c_send_byte_command(MAX77620_RTC_I2C_ADDR, MAX77620_REG_RTCUPDATE0, 0x01);
+}
+
+void i2c_send_shutdown_cmd(void) {
+ i2c_send_byte_command(MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);
+}
diff --git a/exosphere/rebootstub/src/i2c.h b/exosphere/rebootstub/src/i2c.h
new file mode 100644
index 000000000..2089404a0
--- /dev/null
+++ b/exosphere/rebootstub/src/i2c.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_REBOOTSTUB_I2C_H
+#define EXOSPHERE_REBOOTSTUB_I2C_H
+
+#include "utils.h"
+
+/* I2C_BASE = I2C4. */
+#define I2C_BASE (0x7000D000)
+
+#define MAKE_I2C_REG(ofs) (MAKE_REG32(I2C_BASE + ofs))
+
+#define I2C_I2C_CNFG_0 MAKE_I2C_REG(0x000)
+
+#define I2C_I2C_CMD_ADDR0_0 MAKE_I2C_REG(0x004)
+
+#define I2C_I2C_CMD_DATA1_0 MAKE_I2C_REG(0x00C)
+
+#define I2C_I2C_STATUS_0 MAKE_I2C_REG(0x01C)
+
+#define I2C_INTERRUPT_STATUS_REGISTER_0 MAKE_I2C_REG(0x068)
+
+#define I2C_I2C_CLK_DIVISOR_REGISTER_0 MAKE_I2C_REG(0x06C)
+
+#define I2C_I2C_BUS_CLEAR_CONFIG_0 MAKE_I2C_REG(0x084)
+
+#define I2C_I2C_BUS_CLEAR_STATUS_0 MAKE_I2C_REG(0x088)
+
+
+#define I2C_I2C_CONFIG_LOAD_0 MAKE_I2C_REG(0x08C)
+
+void i2c_init(void);
+
+void i2c_stop_rtc_alarm(void);
+void i2c_send_shutdown_cmd(void);
+
+#endif
diff --git a/exosphere/rebootstub/src/max77620.h b/exosphere/rebootstub/src/max77620.h
new file mode 100644
index 000000000..dcab6c786
--- /dev/null
+++ b/exosphere/rebootstub/src/max77620.h
@@ -0,0 +1,360 @@
+/*
+ * Defining registers address and its bit definitions of MAX77620 and MAX20024
+ *
+ * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef _MFD_MAX77620_H_
+#define _MFD_MAX77620_H_
+
+#define MAX77620_I2C_ADDR 0x3C
+#define MAX77620_RTC_I2C_ADDR 0x68
+
+/* RTC Registers */
+#define MAX77620_REG_RTCINT 0x00
+#define MAX77620_REG_RTCINTM 0x01
+#define MAX77620_REG_RTCCNTLM 0x02
+#define MAX77620_REG_RTCCNTL 0x03
+#define MAX77620_REG_RTCUPDATE0 0x04
+#define MAX77620_REG_RTCUPDATE1 0x05
+#define MAX77620_REG_RTCSMPL 0x06
+#define MAX77620_REG_RTCSEC 0x07
+#define MAX77620_REG_RTCMIN 0x08
+#define MAX77620_REG_RTCHOUR 0x09
+#define MAX77620_REG_RTCDOW 0x0A
+#define MAX77620_REG_RTCMONTH 0x0B
+#define MAX77620_REG_RTCYEAR 0x0C
+#define MAX77620_REG_RTCDOM 0x0D
+#define MAX77620_REG_RTCSECA1 0x0E
+#define MAX77620_REG_RTCMINA1 0x0F
+#define MAX77620_REG_RTCHOURA1 0x10
+#define MAX77620_REG_RTCDOWA1 0x11
+#define MAX77620_REG_RTCMONTHA1 0x12
+#define MAX77620_REG_RTCYEARA1 0x13
+#define MAX77620_REG_RTCDOMA1 0x14
+#define MAX77620_REG_RTCSECA2 0x15
+#define MAX77620_REG_RTCMINA2 0x16
+#define MAX77620_REG_RTCHOURA2 0x17
+#define MAX77620_REG_RTCDOWA2 0x18
+#define MAX77620_REG_RTCMONTHA2 0x19
+#define MAX77620_REG_RTCYEARA2 0x1A
+#define MAX77620_REG_RTCDOMA2 0x1B
+
+/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */
+#define MAX77620_REG_CNFGGLBL1 0x00
+#define MAX77620_REG_CNFGGLBL2 0x01
+#define MAX77620_REG_CNFGGLBL3 0x02
+#define MAX77620_REG_CNFG1_32K 0x03
+#define MAX77620_REG_CNFGBBC 0x04
+#define MAX77620_REG_IRQTOP 0x05
+#define MAX77620_REG_INTLBT 0x06
+#define MAX77620_REG_IRQSD 0x07
+#define MAX77620_REG_IRQ_LVL2_L0_7 0x08
+#define MAX77620_REG_IRQ_LVL2_L8 0x09
+#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A
+#define MAX77620_REG_ONOFFIRQ 0x0B
+#define MAX77620_REG_NVERC 0x0C
+#define MAX77620_REG_IRQTOPM 0x0D
+#define MAX77620_REG_INTENLBT 0x0E
+#define MAX77620_REG_IRQMASKSD 0x0F
+#define MAX77620_REG_IRQ_MSK_L0_7 0x10
+#define MAX77620_REG_IRQ_MSK_L8 0x11
+#define MAX77620_REG_ONOFFIRQM 0x12
+#define MAX77620_REG_STATLBT 0x13
+#define MAX77620_REG_STATSD 0x14
+#define MAX77620_REG_ONOFFSTAT 0x15
+
+/* SD and LDO Registers */
+#define MAX77620_REG_SD0 0x16
+#define MAX77620_REG_SD1 0x17
+#define MAX77620_REG_SD2 0x18
+#define MAX77620_REG_SD3 0x19
+#define MAX77620_REG_SD4 0x1A
+#define MAX77620_REG_DVSSD0 0x1B
+#define MAX77620_REG_DVSSD1 0x1C
+#define MAX77620_REG_SD0_CFG 0x1D
+#define MAX77620_REG_SD1_CFG 0x1E
+#define MAX77620_REG_SD2_CFG 0x1F
+#define MAX77620_REG_SD3_CFG 0x20
+#define MAX77620_REG_SD4_CFG 0x21
+#define MAX77620_REG_SD_CFG2 0x22
+#define MAX77620_REG_LDO0_CFG 0x23
+#define MAX77620_REG_LDO0_CFG2 0x24
+#define MAX77620_REG_LDO1_CFG 0x25
+#define MAX77620_REG_LDO1_CFG2 0x26
+#define MAX77620_REG_LDO2_CFG 0x27
+#define MAX77620_REG_LDO2_CFG2 0x28
+#define MAX77620_REG_LDO3_CFG 0x29
+#define MAX77620_REG_LDO3_CFG2 0x2A
+#define MAX77620_REG_LDO4_CFG 0x2B
+#define MAX77620_REG_LDO4_CFG2 0x2C
+#define MAX77620_REG_LDO5_CFG 0x2D
+#define MAX77620_REG_LDO5_CFG2 0x2E
+#define MAX77620_REG_LDO6_CFG 0x2F
+#define MAX77620_REG_LDO6_CFG2 0x30
+#define MAX77620_REG_LDO7_CFG 0x31
+#define MAX77620_REG_LDO7_CFG2 0x32
+#define MAX77620_REG_LDO8_CFG 0x33
+#define MAX77620_REG_LDO8_CFG2 0x34
+#define MAX77620_REG_LDO_CFG3 0x35
+
+#define MAX77620_LDO_SLEW_RATE_MASK 0x1
+
+/* LDO Configuration 3 */
+#define MAX77620_TRACK4_MASK (1 << 5)
+#define MAX77620_TRACK4_SHIFT 5
+
+/* Voltage */
+#define MAX77620_SDX_VOLT_MASK 0xFF
+#define MAX77620_SD0_VOLT_MASK 0x3F
+#define MAX77620_SD1_VOLT_MASK 0x7F
+#define MAX77620_LDO_VOLT_MASK 0x3F
+
+#define MAX77620_REG_GPIO0 0x36
+#define MAX77620_REG_GPIO1 0x37
+#define MAX77620_REG_GPIO2 0x38
+#define MAX77620_REG_GPIO3 0x39
+#define MAX77620_REG_GPIO4 0x3A
+#define MAX77620_REG_GPIO5 0x3B
+#define MAX77620_REG_GPIO6 0x3C
+#define MAX77620_REG_GPIO7 0x3D
+#define MAX77620_REG_PUE_GPIO 0x3E
+#define MAX77620_REG_PDE_GPIO 0x3F
+#define MAX77620_REG_AME_GPIO 0x40
+#define MAX77620_REG_ONOFFCNFG1 0x41
+#define MAX77620_REG_ONOFFCNFG2 0x42
+
+/* FPS Registers */
+#define MAX77620_REG_FPS_CFG0 0x43
+#define MAX77620_REG_FPS_CFG1 0x44
+#define MAX77620_REG_FPS_CFG2 0x45
+#define MAX77620_REG_FPS_LDO0 0x46
+#define MAX77620_REG_FPS_LDO1 0x47
+#define MAX77620_REG_FPS_LDO2 0x48
+#define MAX77620_REG_FPS_LDO3 0x49
+#define MAX77620_REG_FPS_LDO4 0x4A
+#define MAX77620_REG_FPS_LDO5 0x4B
+#define MAX77620_REG_FPS_LDO6 0x4C
+#define MAX77620_REG_FPS_LDO7 0x4D
+#define MAX77620_REG_FPS_LDO8 0x4E
+#define MAX77620_REG_FPS_SD0 0x4F
+#define MAX77620_REG_FPS_SD1 0x50
+#define MAX77620_REG_FPS_SD2 0x51
+#define MAX77620_REG_FPS_SD3 0x52
+#define MAX77620_REG_FPS_SD4 0x53
+#define MAX77620_REG_FPS_NONE 0
+
+#define MAX77620_FPS_SRC_MASK 0xC0
+#define MAX77620_FPS_SRC_SHIFT 6
+#define MAX77620_FPS_PU_PERIOD_MASK 0x38
+#define MAX77620_FPS_PU_PERIOD_SHIFT 3
+#define MAX77620_FPS_PD_PERIOD_MASK 0x07
+#define MAX77620_FPS_PD_PERIOD_SHIFT 0
+#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
+#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
+#define MAX77620_FPS_EN_SRC_MASK 0x06
+#define MAX77620_FPS_EN_SRC_SHIFT 1
+#define MAX77620_FPS_ENFPS_SW_MASK 0x01
+#define MAX77620_FPS_ENFPS_SW 0x01
+
+/* Minimum and maximum FPS period time (in microseconds) are
+ * different for MAX77620 and Max20024.
+ */
+#define MAX77620_FPS_PERIOD_MIN_US 40
+#define MAX20024_FPS_PERIOD_MIN_US 20
+
+#define MAX77620_FPS_PERIOD_MAX_US 2560
+#define MAX20024_FPS_PERIOD_MAX_US 5120
+
+#define MAX77620_REG_FPS_GPIO1 0x54
+#define MAX77620_REG_FPS_GPIO2 0x55
+#define MAX77620_REG_FPS_GPIO3 0x56
+#define MAX77620_REG_FPS_RSO 0x57
+#define MAX77620_REG_CID0 0x58
+#define MAX77620_REG_CID1 0x59
+#define MAX77620_REG_CID2 0x5A
+#define MAX77620_REG_CID3 0x5B
+#define MAX77620_REG_CID4 0x5C
+#define MAX77620_REG_CID5 0x5D
+
+#define MAX77620_REG_DVSSD4 0x5E
+#define MAX20024_REG_MAX_ADD 0x70
+
+#define MAX77620_CID_DIDM_MASK 0xF0
+#define MAX77620_CID_DIDM_SHIFT 4
+
+/* CNCG2SD */
+#define MAX77620_SD_CNF2_ROVS_EN_SD1 (1 << 1)
+#define MAX77620_SD_CNF2_ROVS_EN_SD0 (1 << 2)
+
+/* Device Identification Metal */
+#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
+/* Device Indentification OTP */
+#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
+
+/* SD CNFG1 */
+#define MAX77620_SD_SR_MASK 0xC0
+#define MAX77620_SD_SR_SHIFT 6
+#define MAX77620_SD_POWER_MODE_MASK 0x30
+#define MAX77620_SD_POWER_MODE_SHIFT 4
+#define MAX77620_SD_CFG1_ADE_MASK (1 << 3)
+#define MAX77620_SD_CFG1_ADE_DISABLE 0
+#define MAX77620_SD_CFG1_ADE_ENABLE (1 << 3)
+#define MAX77620_SD_FPWM_MASK 0x04
+#define MAX77620_SD_FPWM_SHIFT 2
+#define MAX77620_SD_FSRADE_MASK 0x01
+#define MAX77620_SD_FSRADE_SHIFT 0
+#define MAX77620_SD_CFG1_FPWM_SD_MASK (1 << 2)
+#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
+#define MAX77620_SD_CFG1_FPWM_SD_FPWM (1 << 2)
+#define MAX20024_SD_CFG1_MPOK_MASK (1 << 1)
+#define MAX77620_SD_CFG1_FSRADE_SD_MASK (1 << 0)
+#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
+#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE (1 << 0)
+
+/* LDO_CNFG2 */
+#define MAX77620_LDO_POWER_MODE_MASK 0xC0
+#define MAX77620_LDO_POWER_MODE_SHIFT 6
+#define MAX20024_LDO_CFG2_MPOK_MASK (1 << 2)
+#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
+#define MAX77620_LDO_CFG2_ADE_DISABLE 0
+#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
+#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
+#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
+#define MAX77620_LDO_CFG2_SS_SLOW 0
+
+#define MAX77620_IRQ_TOP_GLBL_MASK (1 << 7)
+#define MAX77620_IRQ_TOP_SD_MASK (1 << 6)
+#define MAX77620_IRQ_TOP_LDO_MASK (1 << 5)
+#define MAX77620_IRQ_TOP_GPIO_MASK (1 << 4)
+#define MAX77620_IRQ_TOP_RTC_MASK (1 << 3)
+#define MAX77620_IRQ_TOP_32K_MASK (1 << 2)
+#define MAX77620_IRQ_TOP_ONOFF_MASK (1 << 1)
+
+#define MAX77620_IRQ_LBM_MASK (1 << 3)
+#define MAX77620_IRQ_TJALRM1_MASK (1 << 2)
+#define MAX77620_IRQ_TJALRM2_MASK (1 << 1)
+
+#define MAX77620_CNFG_GPIO_DRV_MASK (1 << 0)
+#define MAX77620_CNFG_GPIO_DRV_PUSHPULL (1 << 0)
+#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN 0
+#define MAX77620_CNFG_GPIO_DIR_MASK (1 << 1)
+#define MAX77620_CNFG_GPIO_DIR_INPUT (1 << 1)
+#define MAX77620_CNFG_GPIO_DIR_OUTPUT 0
+#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK (1 << 2)
+#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK (1 << 3)
+#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH (1 << 3)
+#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW 0
+#define MAX77620_CNFG_GPIO_INT_MASK (0x3 << 4)
+#define MAX77620_CNFG_GPIO_INT_FALLING (1 << 4)
+#define MAX77620_CNFG_GPIO_INT_RISING (1 << 5)
+#define MAX77620_CNFG_GPIO_DBNC_MASK (0x3 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_None (0x0 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
+
+#define MAX77620_IRQ_LVL2_GPIO_EDGE0 (1 << 0)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE1 (1 << 1)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE2 (1 << 2)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE3 (1 << 3)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE4 (1 << 4)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE5 (1 << 5)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE6 (1 << 6)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE7 (1 << 7)
+
+#define MAX77620_CNFG1_32K_OUT0_EN (1 << 2)
+
+#define MAX77620_ONOFFCNFG1_SFT_RST (1 << 7)
+#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
+#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
+#define MAX77620_ONOFFCNFG1_SLPEN (1 << 2)
+#define MAX77620_ONOFFCNFG1_PWR_OFF (1 << 1)
+#define MAX20024_ONOFFCNFG1_CLRSE 0x18
+
+#define MAX77620_ONOFFCNFG2_SFT_RST_WK (1 << 7)
+#define MAX77620_ONOFFCNFG2_WD_RST_WK (1 << 6)
+#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK (1 << 5)
+#define MAX77620_ONOFFCNFG2_WK_ALARM1 (1 << 2)
+#define MAX77620_ONOFFCNFG2_WK_EN0 (1 << 0)
+
+#define MAX77620_GLBLM_MASK (1 << 0)
+
+#define MAX77620_WDTC_MASK 0x3
+#define MAX77620_WDTOFFC (1 << 4)
+#define MAX77620_WDTSLPC (1 << 3)
+#define MAX77620_WDTEN (1 << 2)
+
+#define MAX77620_TWD_MASK 0x3
+#define MAX77620_TWD_2s 0x0
+#define MAX77620_TWD_16s 0x1
+#define MAX77620_TWD_64s 0x2
+#define MAX77620_TWD_128s 0x3
+
+#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7)
+#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
+#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
+#define MAX77620_CNFGGLBL1_LBHYST_N (1 << 4)
+#define MAX77620_CNFGGLBL1_LBDAC 0x0E
+#define MAX77620_CNFGGLBL1_LBDAC_N (1 << 1)
+#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0)
+
+/* CNFG BBC registers */
+#define MAX77620_CNFGBBC_ENABLE (1 << 0)
+#define MAX77620_CNFGBBC_CURRENT_MASK 0x06
+#define MAX77620_CNFGBBC_CURRENT_SHIFT 1
+#define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18
+#define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3
+#define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE (1 << 5)
+#define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0
+#define MAX77620_CNFGBBC_RESISTOR_SHIFT 6
+
+#define MAX77620_FPS_COUNT 3
+
+/* Interrupts */
+enum {
+ MAX77620_IRQ_TOP_GLBL, /* Low-Battery */
+ MAX77620_IRQ_TOP_SD, /* SD power fail */
+ MAX77620_IRQ_TOP_LDO, /* LDO power fail */
+ MAX77620_IRQ_TOP_GPIO, /* TOP GPIO internal int to MAX77620 */
+ MAX77620_IRQ_TOP_RTC, /* RTC */
+ MAX77620_IRQ_TOP_32K, /* 32kHz oscillator */
+ MAX77620_IRQ_TOP_ONOFF, /* ON/OFF oscillator */
+ MAX77620_IRQ_LBT_MBATLOW, /* Thermal alarm status, > 120C */
+ MAX77620_IRQ_LBT_TJALRM1, /* Thermal alarm status, > 120C */
+ MAX77620_IRQ_LBT_TJALRM2, /* Thermal alarm status, > 140C */
+};
+
+/* GPIOs */
+enum {
+ MAX77620_GPIO0,
+ MAX77620_GPIO1,
+ MAX77620_GPIO2,
+ MAX77620_GPIO3,
+ MAX77620_GPIO4,
+ MAX77620_GPIO5,
+ MAX77620_GPIO6,
+ MAX77620_GPIO7,
+ MAX77620_GPIO_NR,
+};
+
+/* FPS Source */
+enum max77620_fps_src {
+ MAX77620_FPS_SRC_0,
+ MAX77620_FPS_SRC_1,
+ MAX77620_FPS_SRC_2,
+ MAX77620_FPS_SRC_NONE,
+ MAX77620_FPS_SRC_DEF,
+};
+
+enum max77620_chip_id {
+ MAX77620,
+ MAX20024,
+};
+
+#endif /* _MFD_MAX77620_H_ */
diff --git a/exosphere/rebootstub/src/shutdown.c b/exosphere/rebootstub/src/shutdown.c
new file mode 100644
index 000000000..e7596e882
--- /dev/null
+++ b/exosphere/rebootstub/src/shutdown.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "utils.h"
+#include "i2c.h"
+#include "timer.h"
+
+void do_shutdown(void) {
+ /* Initialize i2c. */
+ i2c_init();
+
+ /* Stop alarm, shutdown. */
+ i2c_stop_rtc_alarm();
+ i2c_send_shutdown_cmd();
+
+ while (true) { }
+}
\ No newline at end of file
diff --git a/exosphere/rebootstub/src/start.s b/exosphere/rebootstub/src/start.s
new file mode 100644
index 000000000..3fce7d9f2
--- /dev/null
+++ b/exosphere/rebootstub/src/start.s
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+.section .text.start
+.align 4
+.global _start
+_start:
+ ldr r0, reboot_type
+ cmp r0, #0x0
+ beq do_shutdown
+ b jump_to_reboot_payload
+reboot_type:
+.word 0x00000001
+
+.global jump_to_reboot_payload
+.type jump_to_reboot_payload, %function
+jump_to_reboot_payload:
+ @ clear all registers
+ ldr r0, =0x52425430 @ RBT0
+ mov r1, #0x0
+ mov r2, #0x0
+ mov r3, #0x0
+ mov r4, #0x0
+ mov r5, #0x0
+ mov r6, #0x0
+ mov r7, #0x0
+ mov r8, #0x0
+ mov r9, #0x0
+ mov r10, #0x0
+ mov r11, #0x0
+ mov r12, #0x0
+ mov lr, #0x0
+ ldr sp, =0x40010000
+ ldr pc, =0x40010000
+
+
+
diff --git a/exosphere/rebootstub/src/timer.h b/exosphere/rebootstub/src/timer.h
new file mode 100644
index 000000000..939930bde
--- /dev/null
+++ b/exosphere/rebootstub/src/timer.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_REBOOTSTUB_TIMER_H
+#define EXOSPHERE_REBOOTSTUB_TIMER_H
+
+#include "utils.h"
+
+#define TIMERUS_CNTR_1US_0 MAKE_REG32(0x60005010)
+
+static inline void timer_wait(uint32_t microseconds) {
+ uint32_t old_time = TIMERUS_CNTR_1US_0;
+ while (TIMERUS_CNTR_1US_0 - old_time <= microseconds) {
+ /* Spin-lock. */
+ }
+}
+
+void spinlock_wait(uint32_t count);
+
+#endif
diff --git a/exosphere/rebootstub/src/utils.h b/exosphere/rebootstub/src/utils.h
new file mode 100644
index 000000000..531de9fb6
--- /dev/null
+++ b/exosphere/rebootstub/src/utils.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_REBOOTSTUB_UTILS_H
+#define EXOSPHERE_REBOOTSTUB_UTILS_H
+
+#include
+#include
+#include
+
+#define BIT(n) (1u << (n))
+#define BITL(n) (1ull << (n))
+#define MASK(n) (BIT(n) - 1)
+#define MASKL(n) (BITL(n) - 1)
+#define MASK2(a,b) (MASK(a) & ~MASK(b))
+#define MASK2L(a,b) (MASKL(a) & ~MASKL(b))
+
+#define MAKE_REG32(a) (*(volatile uint32_t *)(a))
+
+#define ALIGN(m) __attribute__((aligned(m)))
+#define PACKED __attribute__((packed))
+
+#define ALINLINE __attribute__((always_inline))
+
+#endif
diff --git a/stratosphere/libstratosphere/Makefile b/exosphere/sc7fw/Makefile
similarity index 69%
rename from stratosphere/libstratosphere/Makefile
rename to exosphere/sc7fw/Makefile
index ff0e010e7..0eadd1314 100644
--- a/stratosphere/libstratosphere/Makefile
+++ b/exosphere/sc7fw/Makefile
@@ -2,46 +2,58 @@
.SUFFIXES:
#---------------------------------------------------------------------------------
-ifeq ($(strip $(DEVKITPRO)),)
-$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro")
+ifeq ($(strip $(DEVKITARM)),)
+$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM")
endif
TOPDIR ?= $(CURDIR)
-include $(DEVKITPRO)/libnx/switch_rules
+include $(DEVKITARM)/base_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
+# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
-SOURCES := source
+BUILD := build
+SOURCES := src
DATA := data
-INCLUDES := include
+INCLUDES := include
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
-ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
+ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
-CFLAGS := -g -Wall -O2 -ffunction-sections \
- $(ARCH) $(DEFINES)
+CFLAGS := \
+ -g \
+ -O2 \
+ -ffunction-sections \
+ -fdata-sections \
+ -fomit-frame-pointer \
+ -fno-inline \
+ -std=gnu11 \
+ -Werror \
+ -Wall \
+ $(ARCH) $(DEFINES)
-CFLAGS += $(INCLUDE) -D__SWITCH__
+CFLAGS += $(INCLUDE) -D__BPMP__
-CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
+CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH)
-LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
+LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
-LIBS := -lnx
+LIBS :=
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
-LIBDIRS := $(PORTLIBS) $(LIBNX)
+LIBDIRS :=
+
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
@@ -50,9 +62,14 @@ LIBDIRS := $(PORTLIBS) $(LIBNX)
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
+export OUTPUT := $(CURDIR)/$(TARGET)
+export TOPDIR := $(CURDIR)
+
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
+export DEPSDIR := $(CURDIR)/$(BUILD)
+
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
@@ -74,77 +91,64 @@ endif
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
-export OFILES := $(OFILES_BIN) $(OFILES_SRC)
-export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES)))
+export OFILES := $(OFILES_BIN) $(OFILES_SRC)
+export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
- -I. \
- -iquote $(CURDIR)/include/switch/
+ -I$(CURDIR)/$(BUILD)
-.PHONY: clean all
+export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
+
+.PHONY: $(BUILD) clean all
#---------------------------------------------------------------------------------
-all: lib/$(TARGET).a lib/$(TARGET)d.a
+all: $(BUILD)
-lib:
+$(BUILD):
@[ -d $@ ] || mkdir -p $@
-
-release:
- @[ -d $@ ] || mkdir -p $@
-
-debug:
- @[ -d $@ ] || mkdir -p $@
-
-lib/$(TARGET).a : lib release $(SOURCES) $(INCLUDES)
- @$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
- BUILD_CFLAGS="-DNDEBUG=1 -O2" \
- DEPSDIR=$(CURDIR)/release \
- --no-print-directory -C release \
- -f $(CURDIR)/Makefile
-
-lib/$(TARGET)d.a : lib debug $(SOURCES) $(INCLUDES)
- @$(MAKE) BUILD=debug OUTPUT=$(CURDIR)/$@ \
- BUILD_CFLAGS="-DDEBUG=1 -Og" \
- DEPSDIR=$(CURDIR)/debug \
- --no-print-directory -C debug \
- -f $(CURDIR)/Makefile
-
-dist-bin: all
- @tar --exclude=*~ -cjf $(TARGET).tar.bz2 include lib
-
-dist-src:
- @tar --exclude=*~ -cjf $(TARGET)-src.tar.bz2 include source Makefile
-
-dist: dist-src dist-bin
+ @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
- @rm -fr release debug lib *.bz2
+ @rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
+
#---------------------------------------------------------------------------------
else
+.PHONY: all
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
-$(OUTPUT) : $(OFILES)
+all : $(OUTPUT).bin
-$(OFILES_SRC) : $(HFILES)
+$(OUTPUT).bin : $(OUTPUT).elf
+ $(OBJCOPY) -S -O binary $< $@
+ @echo built ... $(notdir $@)
+
+$(OUTPUT).elf : $(OFILES)
+
+%.elf: $(OFILES)
+ @echo linking $(notdir $@)
+ @$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
+ @$(NM) -CSn $@ > $(notdir $*.lst)
+
+$(OFILES_SRC) : $(HFILES_BIN)
#---------------------------------------------------------------------------------
-%_bin.h %.bin.o : %.bin
+# you need a rule like this for each extension you use as binary data
+#---------------------------------------------------------------------------------
+%.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------
-
diff --git a/exosphere/bpmpfw/linker.ld b/exosphere/sc7fw/linker.ld
similarity index 100%
rename from exosphere/bpmpfw/linker.ld
rename to exosphere/sc7fw/linker.ld
diff --git a/exosphere/sc7fw/linker.specs b/exosphere/sc7fw/linker.specs
new file mode 100644
index 000000000..300990418
--- /dev/null
+++ b/exosphere/sc7fw/linker.specs
@@ -0,0 +1,7 @@
+%rename link old_link
+
+*link:
+%(old_link) -T %:getenv(TOPDIR /linker.ld) --nmagic --gc-sections
+
+*startfile:
+crti%O%s crtbegin%O%s
diff --git a/exosphere/bpmpfw/src/emc.c b/exosphere/sc7fw/src/emc.c
similarity index 73%
rename from exosphere/bpmpfw/src/emc.c
rename to exosphere/sc7fw/src/emc.c
index e8eb293cf..6b6e16635 100644
--- a/exosphere/bpmpfw/src/emc.c
+++ b/exosphere/sc7fw/src/emc.c
@@ -1,5 +1,21 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include "utils.h"
-#include "lp0.h"
+#include "sc7.h"
#include "emc.h"
#include "pmc.h"
#include "timer.h"
diff --git a/exosphere/bpmpfw/src/emc.h b/exosphere/sc7fw/src/emc.h
similarity index 69%
rename from exosphere/bpmpfw/src/emc.h
rename to exosphere/sc7fw/src/emc.h
index d92cf7b4b..30ac6e650 100644
--- a/exosphere/bpmpfw/src/emc.h
+++ b/exosphere/sc7fw/src/emc.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_BPMPFW_EMC_H
#define EXOSPHERE_BPMPFW_EMC_H
diff --git a/exosphere/bpmpfw/src/i2c.c b/exosphere/sc7fw/src/i2c.c
similarity index 79%
rename from exosphere/bpmpfw/src/i2c.c
rename to exosphere/sc7fw/src/i2c.c
index 709e78004..55225c904 100644
--- a/exosphere/bpmpfw/src/i2c.c
+++ b/exosphere/sc7fw/src/i2c.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include "i2c.h"
#include "timer.h"
diff --git a/exosphere/bpmpfw/src/i2c.h b/exosphere/sc7fw/src/i2c.h
similarity index 56%
rename from exosphere/bpmpfw/src/i2c.h
rename to exosphere/sc7fw/src/i2c.h
index f66cee1ce..b2a755adf 100644
--- a/exosphere/bpmpfw/src/i2c.h
+++ b/exosphere/sc7fw/src/i2c.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_BPMPFW_I2C_H
#define EXOSPHERE_BPMPFW_I2C_H
diff --git a/exosphere/bpmpfw/src/pmc.h b/exosphere/sc7fw/src/pmc.h
similarity index 61%
rename from exosphere/bpmpfw/src/pmc.h
rename to exosphere/sc7fw/src/pmc.h
index 7af26681f..6b8120cdb 100644
--- a/exosphere/bpmpfw/src/pmc.h
+++ b/exosphere/sc7fw/src/pmc.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_BPMPFW_PMC_H
#define EXOSPHERE_BPMPFW_PMC_H
diff --git a/exosphere/bpmpfw/src/lp0.c b/exosphere/sc7fw/src/sc7.c
similarity index 82%
rename from exosphere/bpmpfw/src/lp0.c
rename to exosphere/sc7fw/src/sc7.c
index 3fe5586de..4ae84b11c 100644
--- a/exosphere/bpmpfw/src/lp0.c
+++ b/exosphere/sc7fw/src/sc7.c
@@ -1,5 +1,21 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include "utils.h"
-#include "lp0.h"
+#include "sc7.h"
#include "i2c.h"
#include "pmc.h"
#include "emc.h"
@@ -39,7 +55,7 @@ static void set_pmc_dpd_io_pads(void) {
spinlock_wait(32);
}
-void lp0_entry_main(void) {
+void sc7_entry_main(void) {
/* Disable the BPMP Cache. */
CACHE_CTRL |= 0xC00;
diff --git a/exosphere/sc7fw/src/sc7.h b/exosphere/sc7fw/src/sc7.h
new file mode 100644
index 000000000..37f95cb33
--- /dev/null
+++ b/exosphere/sc7fw/src/sc7.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_BPMPFW_SC7_H
+#define EXOSPHERE_BPMPFW_SC7_H
+
+#include "utils.h"
+
+void sc7_entry_main(void);
+
+void reboot(void);
+
+#endif
diff --git a/exosphere/sc7fw/src/start.s b/exosphere/sc7fw/src/start.s
new file mode 100644
index 000000000..c648a10d4
--- /dev/null
+++ b/exosphere/sc7fw/src/start.s
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+.section .text.start
+.align 4
+.global _start
+_start:
+ b crt0
+.global _reboot
+ b reboot
+
+.global crt0
+.type crt0, %function
+crt0:
+ @ setup to call sc7_entry_main
+ msr cpsr_cxsf, #0xD3
+ ldr sp, =__stack_top__
+ ldr lr, =reboot
+ b sc7_entry_main
+
+
+.global spinlock_wait
+.type spinlock_wait, %function
+spinlock_wait:
+ subs r0, r0, #1
+ bgt spinlock_wait
+ bx lr
diff --git a/exosphere/sc7fw/src/timer.h b/exosphere/sc7fw/src/timer.h
new file mode 100644
index 000000000..62ab23cfe
--- /dev/null
+++ b/exosphere/sc7fw/src/timer.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_BPMPFW_TIMER_H
+#define EXOSPHERE_BPMPFW_TIMER_H
+
+#include "utils.h"
+
+#define TIMERUS_CNTR_1US_0 MAKE_REG32(0x60005010)
+
+static inline void timer_wait(uint32_t microseconds) {
+ uint32_t old_time = TIMERUS_CNTR_1US_0;
+ while (TIMERUS_CNTR_1US_0 - old_time <= microseconds) {
+ /* Spin-lock. */
+ }
+}
+
+void spinlock_wait(uint32_t count);
+
+#endif
diff --git a/exosphere/sc7fw/src/utils.h b/exosphere/sc7fw/src/utils.h
new file mode 100644
index 000000000..e0b908e28
--- /dev/null
+++ b/exosphere/sc7fw/src/utils.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_BPMPFW_UTILS_H
+#define EXOSPHERE_BPMPFW_UTILS_H
+
+#include
+#include
+#include
+
+#define BIT(n) (1u << (n))
+#define BITL(n) (1ull << (n))
+#define MASK(n) (BIT(n) - 1)
+#define MASKL(n) (BITL(n) - 1)
+#define MASK2(a,b) (MASK(a) & ~MASK(b))
+#define MASK2L(a,b) (MASKL(a) & ~MASKL(b))
+
+#define MAKE_REG32(a) (*(volatile uint32_t *)(a))
+
+#define ALIGN(m) __attribute__((aligned(m)))
+#define PACKED __attribute__((packed))
+
+#define ALINLINE __attribute__((always_inline))
+
+#endif
diff --git a/exosphere/src/actmon.c b/exosphere/src/actmon.c
index bd28675b6..a6bdbecbe 100644
--- a/exosphere/src/actmon.c
+++ b/exosphere/src/actmon.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "utils.h"
diff --git a/exosphere/src/actmon.h b/exosphere/src/actmon.h
index fdabfff5b..f9fe6832b 100644
--- a/exosphere/src/actmon.h
+++ b/exosphere/src/actmon.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_ACTIVITY_MONITOR_H
#define EXOSPHERE_ACTIVITY_MONITOR_H
diff --git a/exosphere/src/arm.h b/exosphere/src/arm.h
index 63fe6e4a3..56cdc979d 100644
--- a/exosphere/src/arm.h
+++ b/exosphere/src/arm.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_ARM_H
#define EXOSPHERE_ARM_H
diff --git a/exosphere/src/arm.s b/exosphere/src/arm.s
index 7cf4d0cda..1a7cb9c9c 100644
--- a/exosphere/src/arm.s
+++ b/exosphere/src/arm.s
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#define cpuactlr_el1 s3_1_c15_c2_0
#define cpuectlr_el1 s3_1_c15_c2_1
@@ -51,7 +67,7 @@ tlb_invalidate_page_inner_shareable:
*
* This file is based on sample code from ARMv8 ARM.
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0+
*/
/*
@@ -84,7 +100,7 @@ __asm_dcache_level:
/* x5 <- bit position of #ways */
loop_set:
- mov x6, x3 /* x6 <- working copy of #ways */
+ mov x6, x3 /* x6 <- working copy of #ways */
loop_way:
lsl x7, x6, x5
orr x9, x12, x7 /* map way and level to cisw value */
diff --git a/exosphere/src/bootconfig.c b/exosphere/src/bootconfig.c
index dd2cfd870..5a5da0e59 100644
--- a/exosphere/src/bootconfig.c
+++ b/exosphere/src/bootconfig.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include
@@ -138,9 +154,9 @@ void bootconfig_get_package2_hash_for_recovery(uint64_t *out_hash) {
}
bool bootconfig_is_recovery_boot(void) {
- return (g_boot_reason.is_recovery_boot != 0);
+ return ((g_boot_reason.bootloader_attribute & 0x01) != 0);
}
uint64_t bootconfig_get_boot_reason(void) {
- return ((uint64_t)g_boot_reason.boot_reason_high << 24) | (g_boot_reason.boot_reason_low & 0xFFFFFF);
+ return ((uint64_t)g_boot_reason.boot_reason_state << 24) | (g_boot_reason.boot_reason_value & 0xFFFFFF);
}
diff --git a/exosphere/src/bootconfig.h b/exosphere/src/bootconfig.h
index f5505f4ab..45b38053a 100644
--- a/exosphere/src/bootconfig.h
+++ b/exosphere/src/bootconfig.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_BOOTCONFIG_H
#define EXOSPHERE_BOOTCONFIG_H
@@ -26,7 +42,6 @@ typedef struct {
bootconfig_unsigned_config_t unsigned_config;
uint8_t signature[0x100];
bootconfig_signed_config_t signed_config;
- uint8_t unused_space[0x240]; /* remaining space in the evt page */
} bootconfig_t;
static inline bootconfig_t *get_loaded_bootconfig(void) {
@@ -35,11 +50,12 @@ static inline bootconfig_t *get_loaded_bootconfig(void) {
}
typedef struct {
- uint64_t _0x00;
- uint32_t _0x08;
- uint32_t is_recovery_boot;
- uint32_t boot_reason_low;
- uint32_t boot_reason_high;
+ uint32_t bootloader_version;
+ uint32_t bootloader_start_block;
+ uint32_t bootloader_start_page;
+ uint32_t bootloader_attribute;
+ uint32_t boot_reason_value;
+ uint32_t boot_reason_state;
} boot_reason_t;
void bootconfig_load_and_verify(const bootconfig_t *bootconfig);
diff --git a/exosphere/src/bootup.c b/exosphere/src/bootup.c
index 57e18367b..fbaf2bb27 100644
--- a/exosphere/src/bootup.c
+++ b/exosphere/src/bootup.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
@@ -15,6 +31,7 @@
#include "configitem.h"
#include "timers.h"
#include "misc.h"
+#include "uart.h"
#include "bpmp.h"
#include "sysreg.h"
#include "interrupt.h"
@@ -30,6 +47,20 @@
static bool g_has_booted_up = false;
+void setup_dram_magic_numbers(void) {
+ /* These DRAM writes test and set values for the GPU UCODE carveout. */
+ unsigned int target_fw = exosphere_get_target_firmware();
+ (*(volatile uint32_t *)(0x8005FFFC)) = 0xC0EDBBCC; /* Access test value. */
+ flush_dcache_range((void *)0x8005FFFC, (void *)0x80060000);
+ if (ATMOSPHERE_TARGET_FIRMWARE_600 <= target_fw) {
+ (*(volatile uint32_t *)(0x8005FF00)) = 0x00000083; /* SKU code. */
+ (*(volatile uint32_t *)(0x8005FF04)) = 0x00000002;
+ (*(volatile uint32_t *)(0x8005FF08)) = 0x00000210; /* Tegra210 code. */
+ flush_dcache_range((void *)0x8005FF00, (void *)0x8005FF0C);
+ }
+ __dsb_sy();
+}
+
void bootup_misc_mmio(void) {
/* Initialize Fuse registers. */
fuse_init();
@@ -50,47 +81,42 @@ void bootup_misc_mmio(void) {
se_generate_random_key(KEYSLOT_SWITCH_SRKGENKEY, KEYSLOT_SWITCH_RNGKEY);
se_generate_srk(KEYSLOT_SWITCH_SRKGENKEY);
- /* TODO: Why does this DRAM write occur? */
- if (!g_has_booted_up && exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
- /* 4.x writes this magic number into DRAM. Why? */
- (*(volatile uint32_t *)(0x8005FFFC)) = 0xC0EDBBCC;
+ if (!g_has_booted_up && (ATMOSPHERE_TARGET_FIRMWARE_600 > exosphere_get_target_firmware())) {
+ setup_dram_magic_numbers();
}
- /* Todo: What? */
- MAKE_TIMERS_REG(0x1A4) = 0xF1E0;
+ /* Mark TMR5, TMR6, TMR7, TMR8, WDT0, WDT1, WDT2 and WDT3 as secure. */
+ SHARED_TIMER_SECURE_CFG_0 = 0xF1E0;
- FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 = 4; /* ACTIVE_CLUSTER_LOCK. */
- FLOW_CTLR_FLOW_DBG_QUAL_0 = 0x10000000; /* Enable FIQ2CCPLEX */
+ FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 = 4; /* ACTIVE_CLUSTER_LOCK. */
+ FLOW_CTLR_FLOW_DBG_QUAL_0 = 0x10000000; /* Enable FIQ2CCPLEX */
/* Disable Deep Power Down. */
APBDEV_PMC_DPD_ENABLE_0 = 0;
- /* Setup MC. */
- /* TODO: What are these MC reg writes? */
- MAKE_MC_REG(0x984) = 1;
- MAKE_MC_REG(0x648) = 0;
- MAKE_MC_REG(0x64C) = 0;
- MAKE_MC_REG(0x650) = 1;
- MAKE_MC_REG(0x670) = 0;
- MAKE_MC_REG(0x674) = 0;
- MAKE_MC_REG(0x678) = 1;
- MAKE_MC_REG(0x9A0) = 0;
- MAKE_MC_REG(0x9A4) = 0;
- MAKE_MC_REG(0x9A8) = 0;
- MAKE_MC_REG(0x9AC) = 1;
- MC_SECURITY_CFG0_0 = 0;
- MC_SECURITY_CFG1_0 = 0;
- MC_SECURITY_CFG3_0 = 3;
+ /* Setup MC carveouts. */
+ MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_BOM) = 0;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_SIZE_MB) = 0;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_REG_CTRL) = 1;
+ MAKE_MC_REG(MC_SEC_CARVEOUT_BOM) = 0;
+ MAKE_MC_REG(MC_SEC_CARVEOUT_SIZE_MB) = 0;
+ MAKE_MC_REG(MC_SEC_CARVEOUT_REG_CTRL) = 1;
+ MAKE_MC_REG(MC_MTS_CARVEOUT_BOM) = 0;
+ MAKE_MC_REG(MC_MTS_CARVEOUT_SIZE_MB) = 0;
+ MAKE_MC_REG(MC_MTS_CARVEOUT_ADR_HI) = 0;
+ MAKE_MC_REG(MC_MTS_CARVEOUT_REG_CTRL) = 1;
+ MAKE_MC_REG(MC_SECURITY_CFG0) = 0;
+ MAKE_MC_REG(MC_SECURITY_CFG1) = 0;
+ MAKE_MC_REG(MC_SECURITY_CFG3) = 3;
configure_default_carveouts();
-
-
-
+
/* Mark registers secure world only. */
- if (exosphere_get_target_firmware() == EXOSPHERE_TARGET_FIRMWARE_100) {
- /* TODO: Switch these to use the enum. */
- APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 = 0x500244;
- APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 = 0xA3700000;
- APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = 0x304;
+ if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_100) {
+ APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 = APB_SSER0_SATA_AUX | APB_SSER0_DTV | APB_SSER0_QSPI | APB_SSER0_SATA | APB_SSER0_LA;
+ APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 = APB_SSER1_SPI1 | APB_SSER1_SPI2 | APB_SSER1_SPI3 | APB_SSER1_SPI5 | APB_SSER1_SPI6 | APB_SSER1_I2C4 | APB_SSER1_I2C6;
+ APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = 1 << 4 | 1 << 5 | APB_SSER2_DDS; /* bits 4 and 5 are not labeled in 21.1.7.3 */
} else {
/* Mark SATA_AUX, DTV, QSPI, SE, SATA, LA secure only. */
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 = APB_SSER0_SATA_AUX | APB_SSER0_DTV | APB_SSER0_QSPI | APB_SSER0_SE | APB_SSER0_SATA | APB_SSER0_LA;
@@ -104,7 +130,7 @@ void bootup_misc_mmio(void) {
/* Also mark I2C4 secure only, */
sec_disable_1 |= APB_SSER1_I2C4;
}
- if (hardware_type != 0 && exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (hardware_type != 0 && exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
/* Starting on 4.x on non-dev units, mark UARTB, UARTC, SPI4, I2C3 secure only. */
sec_disable_1 |= APB_SSER1_UART_B | APB_SSER1_UART_C | APB_SSER1_SPI4 | APB_SSER1_I2C3;
/* Starting on 4.x on non-dev units, mark SDMMC1 secure only. */
@@ -114,40 +140,50 @@ void bootup_misc_mmio(void) {
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = sec_disable_2;
}
+ /* Reset Translation Enable Registers. */
+ MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_0) = 0xFFFFFFFF;
+ MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_1) = 0xFFFFFFFF;
+ MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_2) = 0xFFFFFFFF;
+ MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_3) = 0xFFFFFFFF;
+ MAKE_MC_REG(MC_SMMU_TRANSLATION_ENABLE_4) = 0xFFFFFFFF;
+
/* TODO: What are these MC reg writes? */
- MAKE_MC_REG(0x228) = 0xFFFFFFFF;
- MAKE_MC_REG(0x22C) = 0xFFFFFFFF;
- MAKE_MC_REG(0x230) = 0xFFFFFFFF;
- MAKE_MC_REG(0x234) = 0xFFFFFFFF;
- MAKE_MC_REG(0xB98) = 0xFFFFFFFF;
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
MAKE_MC_REG(0x038) = 0xE;
} else {
MAKE_MC_REG(0x038) = 0x0;
}
MAKE_MC_REG(0x03C) = 0;
+
+ /* MISC registers. */
MAKE_MC_REG(0x9E0) = 0;
MAKE_MC_REG(0x9E4) = 0;
MAKE_MC_REG(0x9E8) = 0;
MAKE_MC_REG(0x9EC) = 0;
MAKE_MC_REG(0x9F0) = 0;
MAKE_MC_REG(0x9F4) = 0;
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
- MAKE_MC_REG(0x01C) = 0;
+
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
+ MAKE_MC_REG(MC_SMMU_PTB_ASID) = 0;
}
- MAKE_MC_REG(0x020) = 0;
- MAKE_MC_REG(0x014) = 0x30000030;
- MAKE_MC_REG(0x018) = 0x2800003F;
- (void)(MAKE_MC_REG(0x014));
- MAKE_MC_REG(0x034) = 0;
- (void)(MAKE_MC_REG(0x014));
- MAKE_MC_REG(0x030) = 0;
- (void)(MAKE_MC_REG(0x014));
- MAKE_MC_REG(0x010) = 1;
- (void)(MAKE_MC_REG(0x014));
+ MAKE_MC_REG(MC_SMMU_PTB_DATA) = 0;
+ MAKE_MC_REG(MC_SMMU_TLB_CONFIG) = 0x30000030;
+ MAKE_MC_REG(MC_SMMU_PTC_CONFIG) = 0x2800003F;
+ (void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
+ MAKE_MC_REG(MC_SMMU_PTC_FLUSH) = 0;
+ (void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
+ MAKE_MC_REG(MC_SMMU_TLB_FLUSH) = 0;
+ (void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
+ MAKE_MC_REG(MC_SMMU_CONFIG) = 1; /* Enable SMMU. */
+ (void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
/* Clear RESET Vector, setup CPU Secure Boot RESET Vectors. */
- uint32_t reset_vec = TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN);
+ uint32_t reset_vec;
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
+ reset_vec = TZRAM_GET_SEGMENT_5X_PA(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN);
+ } else {
+ reset_vec = TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN);
+ }
EVP_CPU_RESET_VECTOR_0 = 0;
SB_AA64_RESET_LOW_0 = reset_vec | 1;
SB_AA64_RESET_HIGH_0 = 0;
@@ -162,14 +198,14 @@ void bootup_misc_mmio(void) {
/* Setup FIQs. */
-
/* And assign "se_operation_completed" to Interrupt 0x5A. */
intr_set_priority(INTERRUPT_ID_SECURITY_ENGINE, 0);
intr_set_group(INTERRUPT_ID_SECURITY_ENGINE, 0);
intr_set_enabled(INTERRUPT_ID_SECURITY_ENGINE, 1);
intr_set_cpu_mask(INTERRUPT_ID_SECURITY_ENGINE, 8);
intr_set_edge_level(INTERRUPT_ID_SECURITY_ENGINE, 0);
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
intr_set_priority(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
intr_set_group(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0);
intr_set_enabled(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 1);
@@ -178,29 +214,39 @@ void bootup_misc_mmio(void) {
}
if (!g_has_booted_up) {
+ /* N doesn't do this, but we should for compatibility. */
+ uart_select(UART_A);
+ clkrst_reboot(CARDEVICE_UARTA);
+ uart_init(UART_A, 115200);
+
intr_register_handler(INTERRUPT_ID_SECURITY_ENGINE, se_operation_completed);
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
intr_register_handler(INTERRUPT_ID_ACTIVITY_MONITOR_4X, actmon_interrupt_handler);
}
for (unsigned int core = 1; core < NUM_CPU_CORES; core++) {
set_core_is_active(core, false);
}
g_has_booted_up = true;
- } else if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400) {
- /* TODO: What are these MC reg writes? */
- MAKE_MC_REG(0x65C) = 0xFFFFF000;
- MAKE_MC_REG(0x660) = 0;
- MAKE_MC_REG(0x964) |= 1;
+ } else if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400) {
+ /* Disable AHB redirect. */
+ MAKE_MC_REG(MC_IRAM_BOM) = 0xFFFFF000;
+ MAKE_MC_REG(MC_IRAM_TOM) = 0;
+ MAKE_MC_REG(MC_IRAM_REG_CTRL) |= 1;
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 &= 0xFFF7FFFF;
}
}
void setup_4x_mmio(void) {
- /* TODO: What are these MC reg writes? */
- MAKE_MC_REG(0x65C) = 0xFFFFF000;
- MAKE_MC_REG(0x660) = 0;
- MAKE_MC_REG(0x964) |= 1;
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
+ configure_gpu_ucode_carveout();
+ }
+
+ /* Disable AHB redirect. */
+ MAKE_MC_REG(MC_IRAM_BOM) = 0xFFFFF000;
+ MAKE_MC_REG(MC_IRAM_TOM) = 0;
+ MAKE_MC_REG(MC_IRAM_REG_CTRL) |= 1;
CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 &= 0xFFF7FFFF;
+
/* TODO: What are these PMC scratch writes? */
APBDEV_PMC_SECURE_SCRATCH51_0 = (APBDEV_PMC_SECURE_SCRATCH51_0 & 0xFFFF8000) | 0x4000;
APBDEV_PMC_SECURE_SCRATCH16_0 &= 0x3FFFFFFF;
@@ -216,6 +262,7 @@ void setup_4x_mmio(void) {
APBDEV_PMC_SECURE_SCRATCH102_0 = 0x0;
APBDEV_PMC_SECURE_SCRATCH103_0 = 0x0;
APBDEV_PMC_SECURE_SCRATCH39_0 = (APBDEV_PMC_SECURE_SCRATCH39_0 & 0xF8000000) | 0x88;
+
/* TODO: Do we want to bother locking the secure scratch registers? */
/* 4.x Jamais Vu mitigations. */
/* Overwrite exception vectors. */
@@ -227,23 +274,27 @@ void setup_4x_mmio(void) {
BPMP_VECTOR_UNK = BPMP_MITIGATION_RESET_VAL;
BPMP_VECTOR_IRQ = BPMP_MITIGATION_RESET_VAL;
BPMP_VECTOR_FIQ = BPMP_MITIGATION_RESET_VAL;
+
/* Disable AHB arbitration for the BPMP. */
AHB_ARBITRATION_DISABLE_0 |= 2;
+
/* Set SMMU for BPMP/APB-DMA to point to TZRAM. */
- MC_SMMU_PTB_ASID_0 = 1;
- (void)(MAKE_MC_REG(0x014));
- MC_SMMU_PTB_DATA_0 = 0x70012;
- MC_SMMU_AVPC_ASID_0 = 0x80000001;
- MC_SMMU_PPCS1_ASID_0 = 0x80000001;
- (void)(MAKE_MC_REG(0x014));
- MAKE_MC_REG(0x34) = 0;
- (void)(MAKE_MC_REG(0x014));
- MAKE_MC_REG(0x30) = 0;
- (void)(MAKE_MC_REG(0x014));
+ MAKE_MC_REG(MC_SMMU_PTB_ASID) = 1;
+ (void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
+ MAKE_MC_REG(MC_SMMU_PTB_DATA) = 0x70012;
+ MAKE_MC_REG(MC_SMMU_AVPC_ASID) = 0x80000001;
+ MAKE_MC_REG(MC_SMMU_PPCS1_ASID) = 0x80000001;
+ (void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
+ MAKE_MC_REG(MC_SMMU_PTC_FLUSH) = 0;
+ (void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
+ MAKE_MC_REG(MC_SMMU_TLB_FLUSH) = 0;
+ (void)MAKE_MC_REG(MC_SMMU_TLB_CONFIG);
+
/* Wait for the BPMP to halt. */
while ((FLOW_CTLR_HALT_COP_EVENTS_0 >> 29) != 2) {
wait(1);
}
+
/* If not in a debugging context, setup the activity monitor. */
if ((get_debug_authentication_status() & 3) != 3) {
FLOW_CTLR_HALT_COP_EVENTS_0 = 0x40000000;
@@ -263,7 +314,7 @@ void setup_current_core_state(void) {
uint64_t temp_reg;
/* Setup system registers. */
- SET_SYSREG(spsr_el3, 0b1111 << 6 | 0b1001); /* use EL2h+DAIF set initially, may be overwritten later. Not in official code */
+ SET_SYSREG(spsr_el3, 0b1111 << 6 | 0b0101); /* use EL2h+DAIF set initially, may be overwritten later. Not in official code */
SET_SYSREG(actlr_el3, 0x73ull);
SET_SYSREG(actlr_el2, 0x73ull);
@@ -274,7 +325,7 @@ void setup_current_core_state(void) {
__isb();
- SET_SYSREG(cntfrq_el0, MAKE_SYSCTR0_REG(0x20)); /* TODO: Reg name. */
+ SET_SYSREG(cntfrq_el0, SYSCTR0_CNTFID0_0);
SET_SYSREG(cnthctl_el2, 3ull);
__isb();
@@ -309,9 +360,9 @@ void identity_unmap_iram_cd_tzram(void) {
}
void secure_additional_devices(void) {
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_200) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 |= APB_SSER0_PMC; /* make PMC secure-only (2.x+) */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 |= APB_SSER1_MC0 | APB_SSER1_MC1 | APB_SSER1_MCB; /* make MC0, MC1, MCB secure-only (4.x+) */
}
}
diff --git a/exosphere/src/bootup.h b/exosphere/src/bootup.h
index 2f5f0d14b..43f35441f 100644
--- a/exosphere/src/bootup.h
+++ b/exosphere/src/bootup.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_BOOTUP_H
#define EXOSPHERE_BOOTUP_H
@@ -86,6 +102,8 @@ void bootup_misc_mmio(void);
void setup_4x_mmio(void);
+void setup_dram_magic_numbers(void);
+
void setup_current_core_state(void);
void identity_unmap_iram_cd_tzram(void);
diff --git a/exosphere/src/bpmp.h b/exosphere/src/bpmp.h
index e7171bc91..bb4f8e95e 100644
--- a/exosphere/src/bpmp.h
+++ b/exosphere/src/bpmp.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_BPMP_H
#define EXOSPHERE_BPMP_H
diff --git a/exosphere/src/car.c b/exosphere/src/car.c
index 58aeb519d..1ddd30197 100644
--- a/exosphere/src/car.c
+++ b/exosphere/src/car.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "utils.h"
diff --git a/exosphere/src/car.h b/exosphere/src/car.h
index 3fb511bc2..67a665dd3 100644
--- a/exosphere/src/car.h
+++ b/exosphere/src/car.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_CLOCK_AND_RESET_H
#define EXOSPHERE_CLOCK_AND_RESET_H
@@ -14,6 +30,8 @@
#define CLK_RST_CONTROLLER_MISC_CLK_ENB_0 MAKE_CAR_REG(0x048)
#define CLK_RST_CONTROLLER_RST_DEVICES_H_0 MAKE_CAR_REG(0x008)
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 MAKE_CAR_REG(0x3A4)
+#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET_0 MAKE_CAR_REG(0x450)
+#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR_0 MAKE_CAR_REG(0x454)
#define NUM_CAR_BANKS 7
diff --git a/exosphere/src/coldboot_init.c b/exosphere/src/coldboot_init.c
index 5cc2d43e5..275f12f6f 100644
--- a/exosphere/src/coldboot_init.c
+++ b/exosphere/src/coldboot_init.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "utils.h"
#include "arm.h"
@@ -10,7 +26,7 @@
#undef MAILBOX_NX_BOOTLOADER_BASE
#undef TIMERS_BASE
-#define MAILBOX_NX_BOOTLOADER_BASE (MMIO_GET_DEVICE_PA(MMIO_DEVID_NXBOOTLOADER_MAILBOX))
+#define MAILBOX_NX_BOOTLOADER_BASE(targetfw) (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_700) ? (MMIO_GET_DEVICE_7X_PA(MMIO_DEVID_NXBOOTLOADER_MAILBOX)) : (MMIO_GET_DEVICE_PA(MMIO_DEVID_NXBOOTLOADER_MAILBOX))
#define TIMERS_BASE (MMIO_GET_DEVICE_PA(MMIO_DEVID_TMRs_WDTs))
extern const uint8_t __start_cold[];
@@ -18,7 +34,8 @@ extern const uint8_t __start_cold[];
/* warboot_init.c */
extern unsigned int g_exosphere_target_firmware_for_init;
void init_dma_controllers(unsigned int target_firmware);
-void set_memory_registers_enable_mmu(void);
+void set_memory_registers_enable_mmu_1x_ttbr0(void);
+void set_memory_registers_enable_mmu_5x_ttbr0(void);
static void identity_map_all_mappings(uintptr_t *mmu_l1_tbl, uintptr_t *mmu_l3_tbl) {
static const uintptr_t addrs[] = { TUPLE_FOLD_LEFT_0(EVAL(IDENTIY_MAPPING_ID_MAX), _MMAPID, COMMA) };
@@ -31,13 +48,16 @@ static void identity_map_all_mappings(uintptr_t *mmu_l1_tbl, uintptr_t *mmu_l3_t
}
}
-static void mmio_map_all_devices(uintptr_t *mmu_l3_tbl) {
+static void mmio_map_all_devices(uintptr_t *mmu_l3_tbl, unsigned int target_firmware) {
static const uintptr_t pas[] = { TUPLE_FOLD_LEFT_0(EVAL(MMIO_DEVID_MAX), _MMAPDEV, COMMA) };
static const size_t sizes[] = { TUPLE_FOLD_LEFT_1(EVAL(MMIO_DEVID_MAX), _MMAPDEV, COMMA) };
static const bool is_secure[] = { TUPLE_FOLD_LEFT_2(EVAL(MMIO_DEVID_MAX), _MMAPDEV, COMMA) };
+
+ static const uintptr_t pas_7x[] = { TUPLE_FOLD_LEFT_0(EVAL(MMIO_DEVID_MAX), _MMAPDEV7X, COMMA) };
for(size_t i = 0, offset = 0; i < MMIO_DEVID_MAX; i++) {
- mmio_map_device(mmu_l3_tbl, MMIO_BASE + offset, pas[i], sizes[i], is_secure[i]);
+ uintptr_t pa = (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_700) ? pas[i] : pas_7x[i];
+ mmio_map_device(mmu_l3_tbl, MMIO_BASE + offset, pa, sizes[i], is_secure[i]);
offset += sizes[i];
offset += 0x1000;
}
@@ -65,22 +85,34 @@ static void warmboot_map_all_ram_segments(uintptr_t *mmu_l3_tbl) {
}
}
-static void tzram_map_all_segments(uintptr_t *mmu_l3_tbl) {
+static void tzram_map_all_segments(uintptr_t *mmu_l3_tbl, unsigned int target_firmware) {
static const uintptr_t offs[] = { TUPLE_FOLD_LEFT_0(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZS, COMMA) };
static const size_t sizes[] = { TUPLE_FOLD_LEFT_1(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZS, COMMA) };
static const size_t increments[] = { TUPLE_FOLD_LEFT_2(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZS, COMMA) };
static const bool is_executable[] = { TUPLE_FOLD_LEFT_3(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZS, COMMA) };
+ static const uintptr_t offs_5x[] = { TUPLE_FOLD_LEFT_0(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZ5XS, COMMA) };
+
for(size_t i = 0, offset = 0; i < TZRAM_SEGMENT_ID_MAX; i++) {
- tzram_map_segment(mmu_l3_tbl, TZRAM_SEGMENT_BASE + offset, 0x7C010000ull + offs[i], sizes[i], is_executable[i]);
+ uintptr_t off = (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_500) ? offs[i] : offs_5x[i];
+ tzram_map_segment(mmu_l3_tbl, TZRAM_SEGMENT_BASE + offset, 0x7C010000ull + off, sizes[i], is_executable[i]);
offset += increments[i];
}
}
-static void configure_ttbls(void) {
- uintptr_t *mmu_l1_tbl = (uintptr_t *)(TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
- uintptr_t *mmu_l2_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE);
- uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
+static void configure_ttbls(unsigned int target_firmware) {
+ uintptr_t *mmu_l1_tbl;
+ uintptr_t *mmu_l2_tbl;
+ uintptr_t *mmu_l3_tbl;
+ if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_500) {
+ mmu_l1_tbl = (uintptr_t *)(TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
+ mmu_l2_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE);
+ mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
+ } else {
+ mmu_l1_tbl = (uintptr_t *)(TZRAM_GET_SEGMENT_5X_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
+ mmu_l2_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_5X_PA(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE);
+ mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_5X_PA(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
+ }
mmu_init_table(mmu_l1_tbl, 64); /* 33-bit address space */
mmu_init_table(mmu_l2_tbl, 4096);
@@ -98,10 +130,10 @@ static void configure_ttbls(void) {
mmu_map_table(2, mmu_l2_tbl, 0x1F0000000ull, mmu_l3_tbl, 0);
identity_map_all_mappings(mmu_l1_tbl, mmu_l3_tbl);
- mmio_map_all_devices(mmu_l3_tbl);
+ mmio_map_all_devices(mmu_l3_tbl, target_firmware);
lp0_entry_map_all_ram_segments(mmu_l3_tbl);
warmboot_map_all_ram_segments(mmu_l3_tbl);
- tzram_map_all_segments(mmu_l3_tbl);
+ tzram_map_all_segments(mmu_l3_tbl, target_firmware);
}
static void do_relocation(const coldboot_crt0_reloc_list_t *reloc_list, size_t index) {
@@ -117,10 +149,19 @@ static void do_relocation(const coldboot_crt0_reloc_list_t *reloc_list, size_t i
}
}
-uintptr_t get_coldboot_crt0_stack_address(void) {
+uintptr_t get_coldboot_crt0_temp_stack_address(void) {
return TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
}
+uintptr_t get_coldboot_crt0_stack_address(void) {
+ if (exosphere_get_target_firmware_for_init() < ATMOSPHERE_TARGET_FIRMWARE_500) {
+ return TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
+ } else {
+ return TZRAM_GET_SEGMENT_5X_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
+ }
+
+}
+
void coldboot_init(coldboot_crt0_reloc_list_t *reloc_list, uintptr_t start_cold) {
//MAILBOX_NX_SECMON_BOOT_TIME = TIMERUS_CNTR_1US_0;
@@ -154,8 +195,12 @@ void coldboot_init(coldboot_crt0_reloc_list_t *reloc_list, uintptr_t start_cold)
/* TZRAM accesses should work normally after this point. */
init_dma_controllers(g_exosphere_target_firmware_for_init);
- configure_ttbls();
- set_memory_registers_enable_mmu();
+ configure_ttbls(g_exosphere_target_firmware_for_init);
+ if (g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_500) {
+ set_memory_registers_enable_mmu_1x_ttbr0();
+ } else {
+ set_memory_registers_enable_mmu_5x_ttbr0();
+ }
/* Copy or clear the remaining sections */
for(size_t i = 0; i < reloc_list->nb_relocs_post_mmu_init; i++) {
diff --git a/exosphere/src/coldboot_main.c b/exosphere/src/coldboot_main.c
index 4840dc3fc..416a018f5 100644
--- a/exosphere/src/coldboot_main.c
+++ b/exosphere/src/coldboot_main.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "utils.h"
#include "mmu.h"
diff --git a/exosphere/src/configitem.c b/exosphere/src/configitem.c
index 7244fa692..7029297d3 100644
--- a/exosphere/src/configitem.c
+++ b/exosphere/src/configitem.c
@@ -1,4 +1,21 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
+#include
#include "bootconfig.h"
#include "configitem.h"
@@ -9,22 +26,98 @@
#include "utils.h"
#include "masterkey.h"
#include "exocfg.h"
-#include "version.h"
+#include "smc_ams.h"
+#include "arm.h"
+
+#define u8 uint8_t
+#define u32 uint32_t
+#include "rebootstub_bin.h"
+#undef u8
+#undef u32
static bool g_battery_profile = false;
+static bool g_debugmode_override_user = false, g_debugmode_override_priv = false;
-uint32_t configitem_set(ConfigItem item, uint64_t value) {
- if (item != CONFIGITEM_BATTERYPROFILE) {
- return 2;
+uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
+ switch (item) {
+ case CONFIGITEM_BATTERYPROFILE:
+ g_battery_profile = (value != 0);
+ break;
+ case CONFIGITEM_NEEDS_REBOOT:
+ /* Force a reboot, if requested. */
+ {
+ switch (value) {
+ case REBOOT_KIND_NO_REBOOT:
+ return 0;
+ case REBOOT_KIND_TO_RCM:
+ /* Set reboot kind = rcm. */
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x450ull) = 0x2;
+ break;
+ case REBOOT_KIND_TO_WB_PAYLOAD:
+ /* Set reboot kind = warmboot. */
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x450ull) = 0x1;
+ /* Patch SDRAM init to perform an SVC immediately after second write */
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x634ull) = 0x2E38DFFF;
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x638ull) = 0x6001DC28;
+ /* Set SVC handler to jump to reboot stub in IRAM. */
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x520ull) = 0x4003F000;
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x53Cull) = 0x6000F208;
+
+ /* Copy reboot stub payload. */
+ ams_map_irampage(0x4003F000);
+ for (unsigned int i = 0; i < rebootstub_bin_size; i += 4) {
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE) + i) = read32le(rebootstub_bin, i);
+ }
+ ams_unmap_irampage();
+
+ /* Ensure stub is flushed. */
+ flush_dcache_all();
+ break;
+ default:
+ return 2;
+ }
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10;
+ while (1) { }
+ }
+ break;
+ case CONFIGITEM_NEEDS_SHUTDOWN:
+ /* Force a shutdown, if requested. */
+ {
+ if (value == 0) {
+ return 0;
+ }
+ /* Set reboot kind = warmboot. */
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x450ull) = 0x1;
+ /* Patch SDRAM init to perform an SVC immediately after second write */
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x634ull) = 0x2E38DFFF;
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x638ull) = 0x6001DC28;
+ /* Set SVC handler to jump to reboot stub in IRAM. */
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x520ull) = 0x4003F000;
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x53Cull) = 0x6000F208;
+
+ /* Copy reboot stub payload. */
+ ams_map_irampage(0x4003F000);
+ for (unsigned int i = 0; i < rebootstub_bin_size; i += 4) {
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE) + i) = read32le(rebootstub_bin, i);
+ }
+ /* Tell rebootstub to shut down. */
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE) + 0x10) = 0x0;
+ ams_unmap_irampage();
+
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10;
+ while (1) { }
+ }
+ break;
+ default:
+ return 2;
}
- g_battery_profile = (value != 0);
return 0;
}
bool configitem_is_recovery_boot(void) {
uint64_t is_recovery_boot;
- if (configitem_get(CONFIGITEM_ISRECOVERYBOOT, &is_recovery_boot) != 0) {
+ if (configitem_get(true, CONFIGITEM_ISRECOVERYBOOT, &is_recovery_boot) != 0) {
generic_panic();
}
@@ -33,7 +126,7 @@ bool configitem_is_recovery_boot(void) {
bool configitem_is_retail(void) {
uint64_t is_retail;
- if (configitem_get(CONFIGITEM_ISRETAIL, &is_retail) != 0) {
+ if (configitem_get(true, CONFIGITEM_ISRETAIL, &is_retail) != 0) {
generic_panic();
}
@@ -44,15 +137,29 @@ bool configitem_should_profile_battery(void) {
return g_battery_profile;
}
+bool configitem_is_debugmode_priv(void) {
+ uint64_t debugmode = 0;
+ if (configitem_get(true, CONFIGITEM_ISDEBUGMODE, &debugmode) != 0) {
+ generic_panic();
+ }
+
+ return debugmode != 0;
+}
+
uint64_t configitem_get_hardware_type(void) {
uint64_t hardware_type;
- if (configitem_get(CONFIGITEM_HARDWARETYPE, &hardware_type) != 0) {
+ if (configitem_get(true, CONFIGITEM_HARDWARETYPE, &hardware_type) != 0) {
generic_panic();
}
return hardware_type;
}
-uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
+void configitem_set_debugmode_override(bool user, bool priv) {
+ g_debugmode_override_user = user;
+ g_debugmode_override_priv = priv;
+}
+
+uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue) {
uint32_t result = 0;
switch (item) {
case CONFIGITEM_DISABLEPROGRAMVERIFICATION:
@@ -83,7 +190,7 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
break;
case CONFIGITEM_BOOTREASON:
/* For some reason, Nintendo removed it on 4.0 */
- if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400) {
*p_outvalue = bootconfig_get_boot_reason();
} else {
result = 2;
@@ -93,7 +200,11 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
*p_outvalue = bootconfig_get_memory_arrangement();
break;
case CONFIGITEM_ISDEBUGMODE:
- *p_outvalue = (int)(bootconfig_is_debug_mode());
+ if ((privileged && g_debugmode_override_priv) || (!privileged && g_debugmode_override_user)) {
+ *p_outvalue = 1;
+ } else {
+ *p_outvalue = (int)(bootconfig_is_debug_mode());
+ }
break;
case CONFIGITEM_KERNELMEMORYCONFIGURATION:
*p_outvalue = bootconfig_get_kernel_memory_configuration();
@@ -101,9 +212,9 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
case CONFIGITEM_BATTERYPROFILE:
*p_outvalue = (int)g_battery_profile;
break;
- case CONFIGITEM_ODM4BIT10_4X:
- /* Added on 4.x ... where is it being used? */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ case CONFIGITEM_ISQUESTUNIT:
+ /* Added on 3.0, used to determine whether console is a kiosk unit. */
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_300) {
*p_outvalue = (fuse_get_reserved_odm(4) >> 10) & 1;
} else {
result = 2;
@@ -111,7 +222,7 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
break;
case CONFIGITEM_NEWHARDWARETYPE_5X:
/* Added in 5.x, currently hardcoded to 0. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
*p_outvalue = 0;
} else {
result = 2;
@@ -119,7 +230,7 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
break;
case CONFIGITEM_NEWKEYGENERATION_5X:
/* Added in 5.x. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
*p_outvalue = fuse_get_5x_key_generation();
} else {
result = 2;
@@ -127,7 +238,7 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
break;
case CONFIGITEM_PACKAGE2HASH_5X:
/* Added in 5.x. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500 && bootconfig_is_recovery_boot()) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500 && bootconfig_is_recovery_boot()) {
bootconfig_get_package2_hash_for_recovery(p_outvalue);
} else {
result = 2;
@@ -135,7 +246,19 @@ uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue) {
break;
case CONFIGITEM_EXOSPHERE_VERSION:
/* UNOFFICIAL: Gets information about the current exosphere version. */
- *p_outvalue = (EXOSPHERE_RELEASE_VERSION_MAJOR << 24) | (EXOSPHERE_RELEASE_VERSION_MINOR << 16) | (exosphere_get_target_firmware() << 8) | (mkey_get_revision() << 0);
+ *p_outvalue = ((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MAJOR & 0xFF) << 32ull) |
+ ((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MINOR & 0xFF) << 24ull) |
+ ((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MICRO & 0xFF) << 16ull) |
+ ((uint64_t)(exosphere_get_target_firmware() & 0xFF) << 8ull) |
+ ((uint64_t)(mkey_get_revision() & 0xFF) << 0ull);
+ break;
+ case CONFIGITEM_NEEDS_REBOOT:
+ /* UNOFFICIAL: The fact that we are executing means we aren't in the process of rebooting. */
+ *p_outvalue = 0;
+ break;
+ case CONFIGITEM_NEEDS_SHUTDOWN:
+ /* UNOFFICIAL: The fact that we are executing means we aren't in the process of shutting down. */
+ *p_outvalue = 0;
break;
default:
result = 2;
diff --git a/exosphere/src/configitem.h b/exosphere/src/configitem.h
index 8ff65af8a..4bf6f30c1 100644
--- a/exosphere/src/configitem.h
+++ b/exosphere/src/configitem.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_CFG_ITEM_H
#define EXOSPHERE_CFG_ITEM_H
@@ -18,21 +34,30 @@ typedef enum {
CONFIGITEM_ISDEBUGMODE = 11,
CONFIGITEM_KERNELMEMORYCONFIGURATION = 12,
CONFIGITEM_BATTERYPROFILE = 13,
- CONFIGITEM_ODM4BIT10_4X = 14,
+ CONFIGITEM_ISQUESTUNIT = 14,
CONFIGITEM_NEWHARDWARETYPE_5X = 15,
CONFIGITEM_NEWKEYGENERATION_5X = 16,
CONFIGITEM_PACKAGE2HASH_5X = 17,
/* These are unofficial, for usage by Exosphere. */
- CONFIGITEM_EXOSPHERE_VERSION = 65000
+ CONFIGITEM_EXOSPHERE_VERSION = 65000,
+ CONFIGITEM_NEEDS_REBOOT = 65001,
+ CONFIGITEM_NEEDS_SHUTDOWN = 65002,
} ConfigItem;
-uint32_t configitem_set(ConfigItem item, uint64_t value);
-uint32_t configitem_get(ConfigItem item, uint64_t *p_outvalue);
+#define REBOOT_KIND_NO_REBOOT 0
+#define REBOOT_KIND_TO_RCM 1
+#define REBOOT_KIND_TO_WB_PAYLOAD 2
+
+uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value);
+uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue);
bool configitem_is_recovery_boot(void);
bool configitem_is_retail(void);
bool configitem_should_profile_battery(void);
+bool configitem_is_debugmode_priv(void);
+
+void configitem_set_debugmode_override(bool user, bool priv);
uint64_t configitem_get_hardware_type(void);
diff --git a/exosphere/src/cpu_context.c b/exosphere/src/cpu_context.c
index d952d7879..13fb03aab 100644
--- a/exosphere/src/cpu_context.c
+++ b/exosphere/src/cpu_context.c
@@ -1,7 +1,25 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include "arm.h"
#include "cpu_context.h"
+#include "car.h"
+#include "exocfg.h"
#include "flow.h"
#include "pmc.h"
#include "timers.h"
@@ -13,12 +31,12 @@
#define SAVE_SYSREG64(reg) do { __asm__ __volatile__ ("mrs %0, " #reg : "=r"(temp_reg) :: "memory"); g_cpu_contexts[current_core].reg = temp_reg; } while(false)
#define SAVE_SYSREG32(reg) do { __asm__ __volatile__ ("mrs %0, " #reg : "=r"(temp_reg) :: "memory"); g_cpu_contexts[current_core].reg = (uint32_t)temp_reg; } while(false)
#define SAVE_BP_REG(i, _) SAVE_SYSREG64(DBGBVR##i##_EL1); SAVE_SYSREG64(DBGBCR##i##_EL1);
-#define SAVE_WP_REG(i, _) SAVE_SYSREG64(DBGBVR##i##_EL1); SAVE_SYSREG64(DBGBCR##i##_EL1);
+#define SAVE_WP_REG(i, _) SAVE_SYSREG64(DBGWVR##i##_EL1); SAVE_SYSREG64(DBGWCR##i##_EL1);
#define RESTORE_SYSREG64(reg) do { temp_reg = g_cpu_contexts[current_core].reg; __asm__ __volatile__ ("msr " #reg ", %0" :: "r"(temp_reg) : "memory"); } while(false)
#define RESTORE_SYSREG32(reg) RESTORE_SYSREG64(reg)
#define RESTORE_BP_REG(i, _) RESTORE_SYSREG64(DBGBVR##i##_EL1); RESTORE_SYSREG64(DBGBCR##i##_EL1);
-#define RESTORE_WP_REG(i, _) RESTORE_SYSREG64(DBGBVR##i##_EL1); RESTORE_SYSREG64(DBGBCR##i##_EL1);
+#define RESTORE_WP_REG(i, _) RESTORE_SYSREG64(DBGWVR##i##_EL1); RESTORE_SYSREG64(DBGWCR##i##_EL1);
/* start.s */
void __attribute__((noreturn)) __jump_to_lower_el(uint64_t arg, uintptr_t ep, uint32_t spsr);
@@ -79,8 +97,13 @@ uint32_t cpu_on(uint32_t core, uintptr_t entrypoint_addr, uint64_t argument) {
set_core_entrypoint_and_argument(core, entrypoint_addr, argument);
- const uint32_t status_masks[NUM_CPU_CORES] = {0x4000, 0x200, 0x400, 0x800};
- const uint32_t toggle_vals[NUM_CPU_CORES] = {0xE, 0x9, 0xA, 0xB};
+ static const uint32_t status_masks[NUM_CPU_CORES] = {0x4000, 0x200, 0x400, 0x800};
+ static const uint32_t toggle_vals[NUM_CPU_CORES] = {0xE, 0x9, 0xA, 0xB};
+
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
+ /* Reset the core */
+ CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET_0 = (1 << (core + 0x10)) | (1 << core);
+ }
/* Check if we're already in the correct state. */
if ((APBDEV_PMC_PWRGATE_STATUS_0 & status_masks[core]) != status_masks[core]) {
@@ -91,7 +114,7 @@ uint32_t cpu_on(uint32_t core, uintptr_t entrypoint_addr, uint64_t argument) {
wait(1);
counter--;
if (counter < 1) {
- return 0;
+ goto CPU_ON_SUCCESS;
}
}
@@ -108,6 +131,13 @@ uint32_t cpu_on(uint32_t core, uintptr_t entrypoint_addr, uint64_t argument) {
counter--;
}
}
+
+CPU_ON_SUCCESS:
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
+ /* Start the core */
+ CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR_0 = (1 << (core + 0x10)) | (1 << core);
+ }
+
return 0;
}
@@ -145,6 +175,7 @@ void save_current_core_context(void) {
/* Save system registers. */
SAVE_SYSREG32(OSDTRRX_EL1);
+ SAVE_SYSREG32(OSDTRTX_EL1);
SAVE_SYSREG32(MDSCR_EL1);
SAVE_SYSREG32(OSECCR_EL1);
SAVE_SYSREG32(MDCCINT_EL1);
@@ -168,6 +199,7 @@ void restore_current_core_context(void) {
if (g_cpu_contexts[current_core].is_saved) {
RESTORE_SYSREG32(OSDTRRX_EL1);
+ RESTORE_SYSREG32(OSDTRTX_EL1);
RESTORE_SYSREG32(MDSCR_EL1);
RESTORE_SYSREG32(OSECCR_EL1);
RESTORE_SYSREG32(MDCCINT_EL1);
diff --git a/exosphere/src/cpu_context.h b/exosphere/src/cpu_context.h
index 8684f8c16..e6d47b412 100644
--- a/exosphere/src/cpu_context.h
+++ b/exosphere/src/cpu_context.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_CPU_CTX_H
#define EXOSPHERE_CPU_CTX_H
diff --git a/exosphere/src/dbg/fmt.c b/exosphere/src/dbg/fmt.c
deleted file mode 100644
index 3c6e243b8..000000000
--- a/exosphere/src/dbg/fmt.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/* File : barebones/ee_printf.c
- This file contains an implementation of ee_printf that only requires a method to output a char to a UART without pulling in library code.
-This code is based on a file that contains the following:
- Copyright (C) 2002 Michael Ringgaard. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the project nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-*/
-
-//TuxSH's changes: add support for 64-bit numbers, remove floating-point code
-// (C) AuroraWright, TuxSH
-
-#include "../utils.h"
-#include
-
-#include "fmt.h"
-
-#define ZEROPAD (1<<0) //Pad with zero
-#define SIGN (1<<1) //Unsigned/signed long
-#define PLUS (1<<2) //Show plus
-#define SPACE (1<<3) //Spacer
-#define LEFT (1<<4) //Left justified
-#define HEX_PREP (1<<5) //0x
-#define UPPERCASE (1<<6) //'ABCDEF'
-
-#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
-
-static int32_t skipAtoi(const char **s)
-{
- int32_t i = 0;
-
- while(IS_DIGIT(**s)) i = i * 10 + *((*s)++) - '0';
-
- return i;
-}
-
-static char *processNumber(char *str, int64_t num, bool isHex, int32_t size, int32_t precision, uint32_t type)
-{
- char sign = 0;
-
- if(type & SIGN)
- {
- if(num < 0)
- {
- sign = '-';
- num = -num;
- size--;
- }
- else if(type & PLUS)
- {
- sign = '+';
- size--;
- }
- else if(type & SPACE)
- {
- sign = ' ';
- size--;
- }
- }
-
- static const char *lowerDigits = "0123456789abcdef",
- *upperDigits = "0123456789ABCDEF";
-
- int32_t i = 0;
- char tmp[20];
- const char *dig = (type & UPPERCASE) ? upperDigits : lowerDigits;
-
- if(num == 0)
- {
- if(precision != 0) tmp[i++] = '0';
- type &= ~HEX_PREP;
- }
- else
- {
- while(num != 0)
- {
- uint64_t base = isHex ? 16ULL : 10ULL;
- tmp[i++] = dig[(uint64_t)num % base];
- num = (int64_t)((uint64_t)num / base);
- }
- }
-
- if(type & LEFT || precision != -1) type &= ~ZEROPAD;
- if(type & HEX_PREP && isHex) size -= 2;
- if(i > precision) precision = i;
- size -= precision;
- if(!(type & (ZEROPAD | LEFT))) while(size-- > 0) *str++ = ' ';
- if(sign) *str++ = sign;
-
- if(type & HEX_PREP && isHex)
- {
- *str++ = '0';
- *str++ = 'x';
- }
-
- if(type & ZEROPAD) while(size-- > 0) *str++ = '0';
- while(i < precision--) *str++ = '0';
- while(i-- > 0) *str++ = tmp[i];
- while(size-- > 0) *str++ = ' ';
-
- return str;
-}
-
-int visprintf(char *buf, const char *fmt, va_list args)
-{
- char *str;
-
- for(str = buf; *fmt; fmt++)
- {
- if(*fmt != '%')
- {
- *str++ = *fmt;
- continue;
- }
-
- //Process flags
- uint32_t flags = 0; //Flags to number()
- bool loop = true;
-
- while(loop)
- {
- switch(*++fmt)
- {
- case '-': flags |= LEFT; break;
- case '+': flags |= PLUS; break;
- case ' ': flags |= SPACE; break;
- case '#': flags |= HEX_PREP; break;
- case '0': flags |= ZEROPAD; break;
- default: loop = false; break;
- }
- }
-
- //Get field width
- int32_t fieldWidth = -1; //Width of output field
- if(IS_DIGIT(*fmt)) fieldWidth = skipAtoi(&fmt);
- else if(*fmt == '*')
- {
- fmt++;
-
- fieldWidth = va_arg(args, int32_t);
-
- if(fieldWidth < 0)
- {
- fieldWidth = -fieldWidth;
- flags |= LEFT;
- }
- }
-
- //Get the precision
- int32_t precision = -1; //Min. # of digits for integers; max number of chars for from string
- if(*fmt == '.')
- {
- fmt++;
-
- if(IS_DIGIT(*fmt)) precision = skipAtoi(&fmt);
- else if(*fmt == '*')
- {
- fmt++;
- precision = va_arg(args, int32_t);
- }
-
- if(precision < 0) precision = 0;
- }
-
- //Get the conversion qualifier
- uint32_t integerType = 0;
- if(*fmt == 'l')
- {
- if(*++fmt == 'l')
- {
- fmt++;
- integerType = 1;
- }
-
- }
- else if(*fmt == 'h')
- {
- if(*++fmt == 'h')
- {
- fmt++;
- integerType = 3;
- }
- else integerType = 2;
- }
-
- bool isHex;
-
- switch(*fmt)
- {
- case 'c':
- if(!(flags & LEFT)) while(--fieldWidth > 0) *str++ = ' ';
- *str++ = (uint8_t)va_arg(args, int32_t);
- while(--fieldWidth > 0) *str++ = ' ';
- continue;
-
- case 's':
- {
- char *s = va_arg(args, char *);
- if(!s) s = "";
- uint32_t len = (precision != -1) ? strnlen(s, precision) : strlen(s);
- if(!(flags & LEFT)) while((int32_t)len < fieldWidth--) *str++ = ' ';
- for(uint32_t i = 0; i < len; i++) *str++ = *s++;
- while((int32_t)len < fieldWidth--) *str++ = ' ';
- continue;
- }
-
- case 'p':
- if(fieldWidth == -1)
- {
- fieldWidth = 8;
- flags |= ZEROPAD;
- }
- str = processNumber(str, va_arg(args, uint32_t), true, fieldWidth, precision, flags);
- continue;
-
- //Integer number formats - set up the flags and "break"
- case 'X':
- flags |= UPPERCASE;
- //Falls through
- case 'x':
- isHex = true;
- break;
-
- case 'd':
- case 'i':
- flags |= SIGN;
- //Falls through
- case 'u':
- isHex = false;
- break;
-
- default:
- if(*fmt != '%') *str++ = '%';
- if(*fmt) *str++ = *fmt;
- else fmt--;
- continue;
- }
-
- int64_t num;
-
- if(flags & SIGN)
- {
- if(integerType == 1) num = va_arg(args, int64_t);
- else num = va_arg(args, int32_t);
-
- if(integerType == 2) num = (int16_t)num;
- else if(integerType == 3) num = (int8_t)num;
- }
- else
- {
- if(integerType == 1) num = va_arg(args, uint64_t);
- else num = va_arg(args, uint32_t);
-
- if(integerType == 2) num = (uint16_t)num;
- else if(integerType == 3) num = (uint8_t)num;
- }
-
- str = processNumber(str, num, isHex, fieldWidth, precision, flags);
- }
-
- *str = 0;
- return str - buf;
-}
-
-int isprintf(char *buf, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- int res = visprintf(buf, fmt, args);
- va_end(args);
- return res;
-}
diff --git a/exosphere/src/dbg/fmt.h b/exosphere/src/dbg/fmt.h
deleted file mode 100644
index 97391b669..000000000
--- a/exosphere/src/dbg/fmt.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef EXOSPHERE_DBG_FMT_H
-#define EXOSPHERE_DBG_FMT_H
-
-#include
-
-int visprintf(char *buf, const char *fmt, va_list args);
-int isprintf(char *buf, const char *fmt, ...);
-
-#endif
diff --git a/exosphere/src/dbg/log.c b/exosphere/src/dbg/log.c
deleted file mode 100644
index 0f33121c5..000000000
--- a/exosphere/src/dbg/log.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include
-#include
-#include "log.h"
-#include "log_device_null.h"
-#include "log_device_uart.h"
-#include "fmt.h"
-#include "../synchronization.h"
-
-#ifndef NDEBUG
-static atomic_flag g_log_lock = ATOMIC_FLAG_INIT;
-static debug_log_device_t *dev;
-#endif
-
-void dbg_log_initialize(DebugLogDevice device) {
-#ifndef NDEBUG
- static debug_log_device_t *const devs[] = {&g_debug_log_device_null.super, &g_debug_log_device_uart.super};
- dev = device >= DEBUGLOGDEVICE_MAX ? &g_debug_log_device_null.super : devs[device];
-#else
- (void)device;
-#endif
-}
-
-/* NOTE: no bound checks are done */
-void dbg_log_write(const char *fmt, ...) {
-#ifndef NDEBUG
- char buf[DBG_LOG_BUF_SIZE];
- int len;
- va_list args;
- lock_acquire(&g_log_lock);
-
- va_start(args, fmt);
- len = visprintf(buf, fmt, args);
- va_end(args);
-
- dev->write_string(dev, buf, len);
- lock_release(&g_log_lock);
-#else
- (void)fmt;
-#endif
-}
-
-void dbg_log_finalize(void) {
-#ifndef NDEBUG
- dev->finalize(dev);
- dev = NULL;
-#endif
-}
diff --git a/exosphere/src/dbg/log.h b/exosphere/src/dbg/log.h
deleted file mode 100644
index 5ae4fe043..000000000
--- a/exosphere/src/dbg/log.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef EXOSPHERE_DBG_LOG_H
-#define EXOSPHERE_DBG_LOG_H
-
-#include "../utils.h"
-
-#define DBG_LOG_BUF_SIZE 256
-
-typedef enum {
- DEBUGLOGDEVICE_NULL = 0,
- DEBUGLOGDEVICE_UART = 1,
-
- DEBUGLOGDEVICE_MAX = 2,
-} DebugLogDevice;
-
-typedef struct debug_log_device_t {
- void (*initialize)(struct debug_log_device_t *this, ...);
- void (*write_string)(struct debug_log_device_t *this, const char *str, size_t len);
- void (*finalize)(struct debug_log_device_t *this);
-} debug_log_device_t;
-
-void dbg_log_initialize(DebugLogDevice device);
-void dbg_log_write(const char *fmt, ...);
-void dbg_log_finalize(void);
-
-#endif
diff --git a/exosphere/src/dbg/log_device_null.c b/exosphere/src/dbg/log_device_null.c
deleted file mode 100644
index 09c29fe73..000000000
--- a/exosphere/src/dbg/log_device_null.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include "log_device_null.h"
-
-static void initialize(debug_log_device_null_t *this) {
- (void)this;
- /* Do nothing */
-}
-
-static void write_string(debug_log_device_null_t *this, const char *str, size_t len) {
- (void)this;
- (void)str;
- (void)len;
- /* Do nothing */
-}
-
-static void finalize(debug_log_device_null_t *this) {
- (void)this;
- /* Do nothing */
-}
-
-debug_log_device_null_t g_debug_log_device_null = {
- .super = {
- .initialize = (void (*)(debug_log_device_t *, ...))initialize,
- .write_string = (void (*)(debug_log_device_t *, const char *, size_t))write_string,
- .finalize = (void (*)(debug_log_device_t *))finalize,
- },
-};
diff --git a/exosphere/src/dbg/log_device_null.h b/exosphere/src/dbg/log_device_null.h
deleted file mode 100644
index 900316485..000000000
--- a/exosphere/src/dbg/log_device_null.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef EXOSPHERE_DBG_LOG_DEVICE_NULL_H
-#define EXOSPHERE_DBG_LOG_DEVICE_NULL_H
-
-#include "log.h"
-
-typedef struct {
- debug_log_device_t super;
- /* Additonnal attributes go here */
-} debug_log_device_null_t;
-
-extern debug_log_device_null_t g_debug_log_device_null;
-
-#endif
diff --git a/exosphere/src/dbg/log_device_uart.c b/exosphere/src/dbg/log_device_uart.c
deleted file mode 100644
index 7f8d008d8..000000000
--- a/exosphere/src/dbg/log_device_uart.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "log_device_uart.h"
-#include "../car.h"
-#include "../uart.h"
-
-static void initialize(debug_log_device_uart_t *this) {
- if (!this->is_initialized) {
- uart_select(UART_A);
- clkrst_enable(CARDEVICE_UARTA);
- uart_init(UART_A, BAUD_115200); /* is this the correct baud rate for this use-case? */
- this->is_initialized = true;
- }
-}
-
-static void write_string(debug_log_device_uart_t *this, const char *str, size_t len) {
- (void)this;
- uart_send(UART_A, str, len);
-}
-
-static void finalize(debug_log_device_uart_t *this) {
- clkrst_disable(CARDEVICE_UARTA);
-}
-
-debug_log_device_uart_t g_debug_log_device_uart = {
- .super = {
- .initialize = (void (*)(debug_log_device_t *, ...))initialize,
- .write_string = (void (*)(debug_log_device_t *, const char *, size_t))write_string,
- .finalize = (void (*)(debug_log_device_t *))finalize,
- },
-};
diff --git a/exosphere/src/dbg/log_device_uart.h b/exosphere/src/dbg/log_device_uart.h
deleted file mode 100644
index 19abc0aef..000000000
--- a/exosphere/src/dbg/log_device_uart.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef EXOSPHERE_DBG_LOG_DEVICE_UART_H
-#define EXOSPHERE_DBG_LOG_DEVICE_UART_H
-
-#include "log.h"
-
-typedef struct {
- debug_log_device_t super;
- bool is_initialized;
-} debug_log_device_uart_t;
-
-extern debug_log_device_uart_t g_debug_log_device_uart;
-
-#endif
diff --git a/exosphere/src/exocfg.c b/exosphere/src/exocfg.c
index 35c42a8df..71b9cd3be 100644
--- a/exosphere/src/exocfg.c
+++ b/exosphere/src/exocfg.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
@@ -6,14 +22,12 @@
#include "mmu.h"
#include "memory_map.h"
-#define MAILBOX_BASE (MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_NXBOOTLOADER_MAILBOX))
-
-/* TODO: Should this be at a non-static location? */
-#define MAILBOX_EXOSPHERE_CONFIG (*((volatile exosphere_config_t *)(MAILBOX_BASE + 0xE40ULL)))
-
-static exosphere_config_t g_exosphere_cfg = {MAGIC_EXOSPHERE_BOOTCONFIG, EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG};
+static exosphere_config_t g_exosphere_cfg = {MAGIC_EXOSPHERE_CONFIG, ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG, EXOSPHERE_FLAGS_DEFAULT};
static bool g_has_loaded_config = false;
+#define EXOSPHERE_CHECK_FLAG(flag) ((g_exosphere_cfg.flags & flag) != 0)
+
+
/* Read config out of IRAM, return target firmware version. */
unsigned int exosphere_load_config(void) {
if (g_has_loaded_config) {
@@ -21,7 +35,9 @@ unsigned int exosphere_load_config(void) {
}
g_has_loaded_config = true;
- if (MAILBOX_EXOSPHERE_CONFIG.magic == MAGIC_EXOSPHERE_BOOTCONFIG) {
+ const unsigned int magic = MAILBOX_EXOSPHERE_CONFIG.magic;
+
+ if (magic == MAGIC_EXOSPHERE_CONFIG) {
g_exosphere_cfg = MAILBOX_EXOSPHERE_CONFIG;
}
@@ -34,4 +50,28 @@ unsigned int exosphere_get_target_firmware(void) {
}
return g_exosphere_cfg.target_firmware;
-}
\ No newline at end of file
+}
+
+unsigned int exosphere_should_perform_620_keygen(void) {
+ if (!g_has_loaded_config) {
+ generic_panic();
+ }
+
+ return g_exosphere_cfg.target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_620 && EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_PERFORM_620_KEYGEN);
+}
+
+unsigned int exosphere_should_override_debugmode_priv(void) {
+ if (!g_has_loaded_config) {
+ generic_panic();
+ }
+
+ return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV);
+}
+
+unsigned int exosphere_should_override_debugmode_user(void) {
+ if (!g_has_loaded_config) {
+ generic_panic();
+ }
+
+ return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_IS_DEBUGMODE_USER);
+}
diff --git a/exosphere/src/exocfg.h b/exosphere/src/exocfg.h
index f02aa24e0..a2c2580e7 100644
--- a/exosphere/src/exocfg.h
+++ b/exosphere/src/exocfg.h
@@ -1,42 +1,65 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_EXOSPHERE_CONFIG_H
#define EXOSPHERE_EXOSPHERE_CONFIG_H
#include
+#include
#include "utils.h"
#include "memory_map.h"
/* This serves to set configuration for *exosphere itself*, separate from the SecMon Exosphere mimics. */
-/* "XBC0" */
-#define MAGIC_EXOSPHERE_BOOTCONFIG (0x30434258)
+/* "EXO0" */
+#define MAGIC_EXOSPHERE_CONFIG (0x304F5845)
-#define EXOSPHERE_TARGET_FIRMWARE_100 1
-#define EXOSPHERE_TARGET_FIRMWARE_200 2
-#define EXOSPHERE_TARGET_FIRMWARE_300 3
-#define EXOSPHERE_TARGET_FIRMWARE_400 4
-#define EXOSPHERE_TARGET_FIRMWARE_500 5
-
-/* TODO: What should this be, for release? */
-#define EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG EXOSPHERE_TARGET_FIRMWARE_500
#define EXOSPHERE_LOOSEN_PACKAGE2_RESTRICTIONS_FOR_DEBUG 1
-#define MAILBOX_BASE_PHYS (MMIO_GET_DEVICE_PA(MMIO_DEVID_NXBOOTLOADER_MAILBOX))
+#define MAILBOX_EXOSPHERE_CONFIG (*((volatile exosphere_config_t *)(0x8000F000ull)))
-/* TODO: Should this be at a non-static location? */
-#define MAILBOX_EXOSPHERE_CONFIG_PHYS (*((volatile exosphere_config_t *)(MAILBOX_BASE_PHYS + 0xE40ULL)))
+/* Exosphere config in DRAM shares physical/virtual mapping. */
+#define MAILBOX_EXOSPHERE_CONFIG_PHYS MAILBOX_EXOSPHERE_CONFIG
+#define EXOSPHERE_FLAGS_DEFAULT 0x00000000
+#define EXOSPHERE_FLAG_PERFORM_620_KEYGEN (1 << 0u)
+#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
+#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
typedef struct {
unsigned int magic;
unsigned int target_firmware;
+ unsigned int flags;
+ unsigned int reserved;
} exosphere_config_t;
unsigned int exosphere_load_config(void);
unsigned int exosphere_get_target_firmware(void);
+unsigned int exosphere_should_perform_620_keygen(void);
+unsigned int exosphere_should_override_debugmode_priv(void);
+unsigned int exosphere_should_override_debugmode_user(void);
static inline unsigned int exosphere_get_target_firmware_for_init(void) {
- return MAILBOX_EXOSPHERE_CONFIG_PHYS.magic == MAGIC_EXOSPHERE_BOOTCONFIG ? MAILBOX_EXOSPHERE_CONFIG_PHYS.target_firmware : EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG;
+ const unsigned int magic = MAILBOX_EXOSPHERE_CONFIG_PHYS.magic;
+ if (magic == MAGIC_EXOSPHERE_CONFIG) {
+ return MAILBOX_EXOSPHERE_CONFIG_PHYS.target_firmware;
+ } else {
+ return ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG;
+ }
}
#endif
diff --git a/exosphere/src/flow.h b/exosphere/src/flow.h
index 014b42abd..abd1dfad8 100644
--- a/exosphere/src/flow.h
+++ b/exosphere/src/flow.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_FLOW_CTLR_H
#define EXOSPHERE_FLOW_CTLR_H
diff --git a/exosphere/src/fuse.c b/exosphere/src/fuse.c
index 94654c451..b33459f42 100644
--- a/exosphere/src/fuse.c
+++ b/exosphere/src/fuse.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "car.h"
@@ -191,7 +207,7 @@ uint32_t fuse_get_hardware_type(void) {
/* This function is very different between 4.x and < 4.x */
uint32_t hardware_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 2) & 1);
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
static const uint32_t types[] = {0,1,4,3};
hardware_type |= (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 14) & 0x3C;
diff --git a/exosphere/src/fuse.h b/exosphere/src/fuse.h
index c4d1240a7..9176893df 100644
--- a/exosphere/src/fuse.h
+++ b/exosphere/src/fuse.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_FUSE_H
#define EXOSPHERE_FUSE_H
diff --git a/exosphere/src/gcm.c b/exosphere/src/gcm.c
index 7350cd5d6..5891d571d 100644
--- a/exosphere/src/gcm.c
+++ b/exosphere/src/gcm.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
diff --git a/exosphere/src/gcm.h b/exosphere/src/gcm.h
index bd53bc9bf..def7133bf 100644
--- a/exosphere/src/gcm.h
+++ b/exosphere/src/gcm.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_GCM_H
#define EXOSPHERE_GCM_H
diff --git a/exosphere/src/i2c.c b/exosphere/src/i2c.c
index 8dc0ee88a..b2989e7ae 100644
--- a/exosphere/src/i2c.c
+++ b/exosphere/src/i2c.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "i2c.h"
diff --git a/exosphere/src/i2c.h b/exosphere/src/i2c.h
index 267ecd641..8ee43e0f2 100644
--- a/exosphere/src/i2c.h
+++ b/exosphere/src/i2c.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_I2C_H
#define EXOSPHERE_I2C_H
diff --git a/exosphere/src/interrupt.c b/exosphere/src/interrupt.c
index 9ab8343ff..bbf2b4261 100644
--- a/exosphere/src/interrupt.c
+++ b/exosphere/src/interrupt.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
diff --git a/exosphere/src/interrupt.h b/exosphere/src/interrupt.h
index 2968e4708..e070e6d19 100644
--- a/exosphere/src/interrupt.h
+++ b/exosphere/src/interrupt.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_INTERRUPT_H
#define EXOSPHERE_INTERRUPT_H
diff --git a/exosphere/src/lp0.h b/exosphere/src/lp0.h
deleted file mode 100644
index 5b44c804e..000000000
--- a/exosphere/src/lp0.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef EXOSPHERE_LP0_H
-#define EXOSPHERE_LP0_H
-
-#include
-
-/* Exosphere Deep Sleep Entry implementation. */
-
-#define LP0_TZRAM_SAVE_SIZE 0xE000
-
-uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argument);
-
-#endif
\ No newline at end of file
diff --git a/exosphere/src/masterkey.c b/exosphere/src/masterkey.c
index c126a4af3..547323b44 100644
--- a/exosphere/src/masterkey.c
+++ b/exosphere/src/masterkey.c
@@ -1,8 +1,25 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include
#include "utils.h"
+#include "configitem.h"
#include "masterkey.h"
#include "se.h"
@@ -12,9 +29,22 @@ static bool g_determined_mkey_revision = false;
static uint8_t g_old_masterkeys[MASTERKEY_REVISION_MAX][0x10];
static uint8_t g_old_devicekeys[MASTERKEY_NUM_NEW_DEVICE_KEYS - 1][0x10];
-/* TODO: Dev keys. */
/* TODO: Extend with new vectors, as needed. */
+/* Dev unit keys. */
+static const uint8_t mkey_vectors_dev[MASTERKEY_REVISION_MAX][0x10] =
+{
+ {0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE}, /* Zeroes encrypted with Master Key 00. */
+ {0x39, 0x33, 0xF9, 0x31, 0xBA, 0xE4, 0xA7, 0x21, 0x2C, 0xDD, 0xB7, 0xD8, 0xB4, 0x4E, 0x37, 0x23}, /* Master key 00 encrypted with Master key 01. */
+ {0x97, 0x29, 0xB0, 0x32, 0x43, 0x14, 0x8C, 0xA6, 0x85, 0xE9, 0x5A, 0x94, 0x99, 0x39, 0xAC, 0x5D}, /* Master key 01 encrypted with Master key 02. */
+ {0x2C, 0xCA, 0x9C, 0x31, 0x1E, 0x07, 0xB0, 0x02, 0x97, 0x0A, 0xD8, 0x03, 0xA2, 0x76, 0x3F, 0xA3}, /* Master key 02 encrypted with Master key 03. */
+ {0x9B, 0x84, 0x76, 0x14, 0x72, 0x94, 0x52, 0xCB, 0x54, 0x92, 0x9B, 0xC4, 0x8C, 0x5B, 0x0F, 0xBA}, /* Master key 03 encrypted with Master key 04. */
+ {0x78, 0xD5, 0xF1, 0x20, 0x3D, 0x16, 0xE9, 0x30, 0x32, 0x27, 0x34, 0x6F, 0xCF, 0xE0, 0x27, 0xDC}, /* Master key 04 encrypted with Master key 05. */
+ {0x6F, 0xD2, 0x84, 0x1D, 0x05, 0xEC, 0x40, 0x94, 0x5F, 0x18, 0xB3, 0x81, 0x09, 0x98, 0x8D, 0x4E}, /* Master key 05 encrypted with Master key 06. */
+ {0x37, 0xAF, 0xAB, 0x35, 0x79, 0x09, 0xD9, 0x48, 0x29, 0xD2, 0xDB, 0xA5, 0xA5, 0xF5, 0x30, 0x19}, /* Master key 06 encrypted with Master key 07. */
+};
+
+/* Retail unit keys. */
static const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] =
{
{0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D}, /* Zeroes encrypted with Master Key 00. */
@@ -22,16 +52,19 @@ static const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] =
{0xDE, 0xCF, 0xEB, 0xEB, 0x10, 0xAE, 0x74, 0xD8, 0xAD, 0x7C, 0xF4, 0x9E, 0x62, 0xE0, 0xE8, 0x72}, /* Master key 01 encrypted with Master key 02. */
{0x0A, 0x0D, 0xDF, 0x34, 0x22, 0x06, 0x6C, 0xA4, 0xE6, 0xB1, 0xEC, 0x71, 0x85, 0xCA, 0x4E, 0x07}, /* Master key 02 encrypted with Master key 03. */
{0x6E, 0x7D, 0x2D, 0xC3, 0x0F, 0x59, 0xC8, 0xFA, 0x87, 0xA8, 0x2E, 0xD5, 0x89, 0x5E, 0xF3, 0xE9}, /* Master key 03 encrypted with Master key 04. */
+ {0xEB, 0xF5, 0x6F, 0x83, 0x61, 0x9E, 0xF8, 0xFA, 0xE0, 0x87, 0xD7, 0xA1, 0x4E, 0x25, 0x36, 0xEE}, /* Master key 04 encrypted with Master key 05. */
+ {0x1E, 0x1E, 0x22, 0xC0, 0x5A, 0x33, 0x3C, 0xB9, 0x0B, 0xA9, 0x03, 0x04, 0xBA, 0xDB, 0x07, 0x57}, /* Master key 05 encrypted with Master key 06. */
+ {0xA4, 0xD4, 0x52, 0x6F, 0xD1, 0xE4, 0x36, 0xAA, 0x9F, 0xCB, 0x61, 0x27, 0x1C, 0x67, 0x65, 0x1F}, /* Master key 06 encrypted with Master key 07. */
};
-bool check_mkey_revision(unsigned int revision) {
+bool check_mkey_revision(unsigned int revision, bool is_retail) {
uint8_t final_vector[0x10];
unsigned int check_keyslot = KEYSLOT_SWITCH_MASTERKEY;
if (revision > 0) {
/* Generate old master key array. */
for (unsigned int i = revision; i > 0; i--) {
- se_aes_ecb_decrypt_block(check_keyslot, g_old_masterkeys[i-1], 0x10, mkey_vectors[i], 0x10);
+ se_aes_ecb_decrypt_block(check_keyslot, g_old_masterkeys[i-1], 0x10, is_retail ? mkey_vectors[i] : mkey_vectors_dev[i], 0x10);
set_aes_keyslot(KEYSLOT_SWITCH_TEMPKEY, g_old_masterkeys[i-1], 0x10);
check_keyslot = KEYSLOT_SWITCH_TEMPKEY;
}
@@ -52,7 +85,7 @@ void mkey_detect_revision(void) {
}
for (unsigned int rev = 0; rev < MASTERKEY_REVISION_MAX; rev++) {
- if (check_mkey_revision(rev)) {
+ if (check_mkey_revision(rev, configitem_is_retail())) {
g_determined_mkey_revision = true;
g_mkey_revision = rev;
break;
@@ -94,7 +127,7 @@ unsigned int mkey_get_keyslot(unsigned int revision) {
void set_old_devkey(unsigned int revision, const uint8_t *key) {
- if (revision < MASTERKEY_REVISION_400_410 || MASTERKEY_REVISION_500_CURRENT <= revision) {
+ if (revision < MASTERKEY_REVISION_400_410 || MASTERKEY_REVISION_MAX <= revision) {
generic_panic();
}
@@ -111,7 +144,7 @@ unsigned int devkey_get_keyslot(unsigned int revision) {
}
if (revision >= 1) {
- if (revision == MASTERKEY_REVISION_500_CURRENT) {
+ if (revision == MASTERKEY_REVISION_MAX) {
return KEYSLOT_SWITCH_DEVICEKEY;
} else {
/* Load into a temp keyslot. */
diff --git a/exosphere/src/masterkey.h b/exosphere/src/masterkey.h
index 5a6a523bb..5da7cd4c5 100644
--- a/exosphere/src/masterkey.h
+++ b/exosphere/src/masterkey.h
@@ -1,16 +1,35 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_MASTERKEY_H
#define EXOSPHERE_MASTERKEY_H
/* This is glue code to enable master key support across versions. */
-/* TODO: Update to 0x6 on release of new master key. */
-#define MASTERKEY_REVISION_MAX 0x5
+/* TODO: Update to 0x9 on release of new master key. */
+#define MASTERKEY_REVISION_MAX 0x8
#define MASTERKEY_REVISION_100_230 0x00
#define MASTERKEY_REVISION_300 0x01
#define MASTERKEY_REVISION_301_302 0x02
#define MASTERKEY_REVISION_400_410 0x03
-#define MASTERKEY_REVISION_500_CURRENT 0x04
+#define MASTERKEY_REVISION_500_510 0x04
+#define MASTERKEY_REVISION_600_610 0x05
+#define MASTERKEY_REVISION_620 0x06
+#define MASTERKEY_REVISION_700_CURRENT 0x07
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)
diff --git a/exosphere/src/mc.c b/exosphere/src/mc.c
index 74e9886ba..c1979eea3 100644
--- a/exosphere/src/mc.c
+++ b/exosphere/src/mc.c
@@ -1,9 +1,35 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "memory_map.h"
#include "mc.h"
#include "exocfg.h"
+typedef struct {
+ uint64_t address;
+ uint64_t size;
+} saved_carveout_info_t;
+
+static saved_carveout_info_t g_saved_carveouts[2] = {
+ {0x80060000ull, KERNEL_CARVEOUT_SIZE_MAX},
+ {0x00000000ull, 0x00000000ull}
+};
+
volatile security_carveout_t *get_carveout_by_id(unsigned int carveout) {
if (CARVEOUT_ID_MIN <= carveout && carveout <= CARVEOUT_ID_MAX) {
return (volatile security_carveout_t *)(MC_BASE + 0xC08ull + 0x50 * (carveout - CARVEOUT_ID_MIN));
@@ -12,82 +38,90 @@ volatile security_carveout_t *get_carveout_by_id(unsigned int carveout) {
return NULL;
}
+void configure_gpu_ucode_carveout(void) {
+ /* Starting in 6.0.0, Carveout 2 is configured later on and adds read permission to TSEC. */
+ /* This is a helper function to make this easier... */
+ volatile security_carveout_t *carveout = get_carveout_by_id(2);
+ carveout->paddr_low = 0x80020000;
+ carveout->paddr_high = 0;
+ carveout->size_big_pages = 2; /* 0x40000 */
+ carveout->client_access_0 = 0;
+ carveout->client_access_1 = 0;
+ carveout->client_access_2 = (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) ? (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR) | BIT(CSR_TSECSRD)) : (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
+ carveout->client_access_3 = 0;
+ carveout->client_access_4 = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
+ carveout->client_force_internal_access_0 = 0;
+ carveout->client_force_internal_access_1 = 0;
+ carveout->client_force_internal_access_2 = 0;
+ carveout->client_force_internal_access_3 = 0;
+ carveout->client_force_internal_access_4 = 0;
+ carveout->config = 0x440167E;
+}
+
void configure_default_carveouts(void) {
/* Configure Carveout 1 (UNUSED) */
volatile security_carveout_t *carveout = get_carveout_by_id(1);
carveout->paddr_low = 0;
carveout->paddr_high = 0;
carveout->size_big_pages = 0;
- carveout->flags_0 = 0;
- carveout->flags_1 = 0;
- carveout->flags_2 = 0;
- carveout->flags_3 = 0;
- carveout->flags_4 = 0;
- carveout->flags_5 = 0;
- carveout->flags_6 = 0;
- carveout->flags_7 = 0;
- carveout->flags_8 = 0;
- carveout->flags_9 = 0;
- carveout->allowed_clients = 0x04000006;
+ carveout->client_access_0 = 0;
+ carveout->client_access_1 = 0;
+ carveout->client_access_2 = 0;
+ carveout->client_access_3 = 0;
+ carveout->client_access_4 = 0;
+ carveout->client_force_internal_access_0 = 0;
+ carveout->client_force_internal_access_1 = 0;
+ carveout->client_force_internal_access_2 = 0;
+ carveout->client_force_internal_access_3 = 0;
+ carveout->client_force_internal_access_4 = 0;
+ carveout->config = 0x4000006;
/* Configure Carveout 2 (GPU UCODE) */
- carveout = get_carveout_by_id(2);
- carveout->paddr_low = 0x80020000;
- carveout->paddr_high = 0;
- carveout->size_big_pages = 2; /* 0x40000 */
- carveout->flags_0 = 0;
- carveout->flags_1 = 0;
- carveout->flags_2 = 0x3000000;
- carveout->flags_3 = 0;
- carveout->flags_4 = 0x300;
- carveout->flags_5 = 0;
- carveout->flags_6 = 0;
- carveout->flags_7 = 0;
- carveout->flags_8 = 0;
- carveout->flags_9 = 0;
- carveout->allowed_clients = 0x440167E;
+ if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_600) {
+ configure_gpu_ucode_carveout();
+ }
/* Configure Carveout 3 (UNUSED GPU) */
carveout = get_carveout_by_id(3);
carveout->paddr_low = 0;
carveout->paddr_high = 0;
carveout->size_big_pages = 0;
- carveout->flags_0 = 0;
- carveout->flags_1 = 0;
- carveout->flags_2 = 0x3000000;
- carveout->flags_3 = 0;
- carveout->flags_4 = 0x300;
- carveout->flags_5 = 0;
- carveout->flags_6 = 0;
- carveout->flags_7 = 0;
- carveout->flags_8 = 0;
- carveout->flags_9 = 0;
- carveout->allowed_clients = 0x4401E7E;
+ carveout->client_access_0 = 0;
+ carveout->client_access_1 = 0;
+ carveout->client_access_2 = (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
+ carveout->client_access_3 = 0;
+ carveout->client_access_4 = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
+ carveout->client_force_internal_access_0 = 0;
+ carveout->client_force_internal_access_1 = 0;
+ carveout->client_force_internal_access_2 = 0;
+ carveout->client_force_internal_access_3 = 0;
+ carveout->client_force_internal_access_4 = 0;
+ carveout->config = 0x4401E7E;
/* Configure default Kernel carveouts based on 2.0.0+. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_200) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
/* Configure Carveout 4 (KERNEL_BUILTINS) */
- configure_kernel_carveout(4, 0x80060000, KERNEL_CARVEOUT_SIZE_MAX);
+ configure_kernel_carveout(4, g_saved_carveouts[0].address, g_saved_carveouts[0].size);
/* Configure Carveout 5 (KERNEL_UNUSED) */
- configure_kernel_carveout(5, 0, 0);
+ configure_kernel_carveout(5, g_saved_carveouts[1].address, g_saved_carveouts[1].size);
} else {
for (unsigned int i = 4; i <= 5; i++) {
carveout = get_carveout_by_id(i);
carveout->paddr_low = 0;
carveout->paddr_high = 0;
carveout->size_big_pages = 0;
- carveout->flags_0 = 0;
- carveout->flags_1 = 0;
- carveout->flags_2 = 0;
- carveout->flags_3 = 0;
- carveout->flags_4 = 0;
- carveout->flags_5 = 0;
- carveout->flags_6 = 0;
- carveout->flags_7 = 0;
- carveout->flags_8 = 0;
- carveout->flags_9 = 0;
- carveout->allowed_clients = 0x4000006;
+ carveout->client_access_0 = 0;
+ carveout->client_access_1 = 0;
+ carveout->client_access_2 = 0;
+ carveout->client_access_3 = 0;
+ carveout->client_access_4 = 0;
+ carveout->client_force_internal_access_0 = 0;
+ carveout->client_force_internal_access_1 = 0;
+ carveout->client_force_internal_access_2 = 0;
+ carveout->client_force_internal_access_3 = 0;
+ carveout->client_force_internal_access_4 = 0;
+ carveout->config = 0x4000006;
}
}
}
@@ -96,20 +130,23 @@ void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint6
if (carveout_id != 4 && carveout_id != 5) {
generic_panic();
}
+
+ g_saved_carveouts[carveout_id-4].address = address;
+ g_saved_carveouts[carveout_id-4].size = size;
volatile security_carveout_t *carveout = get_carveout_by_id(carveout_id);
carveout->paddr_low = (uint32_t)(address & 0xFFFFFFFF);
carveout->paddr_high = (uint32_t)(address >> 32);
carveout->size_big_pages = (uint32_t)(size >> 17);
- carveout->flags_0 = 0x70E3407F;
- carveout->flags_1 = 0x1A620880;
- carveout->flags_2 = 0x303C00;
- carveout->flags_3 = 0xCF0830BB;
- carveout->flags_4 = 0x3;
- carveout->flags_5 = exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400 && carveout_id == 4 ? 0x8000 : 0;
- carveout->flags_6 = exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400 && carveout_id == 4 ? 0x40000 : 0;
- carveout->flags_7 = 0;
- carveout->flags_8 = 0;
- carveout->flags_9 = 0;
- carveout->allowed_clients = 0x8B;
+ carveout->client_access_0 = (BIT(CSR_PTCR) | BIT(CSR_DISPLAY0A) | BIT(CSR_DISPLAY0AB) | BIT(CSR_DISPLAY0B) | BIT(CSR_DISPLAY0BB) | BIT(CSR_DISPLAY0C) | BIT(CSR_DISPLAY0CB) | BIT(CSR_AFIR) | BIT(CSR_DISPLAYHC) | BIT(CSR_DISPLAYHCB) | BIT(CSR_HDAR) | BIT(CSR_HOST1XDMAR) | BIT(CSR_HOST1XR) | BIT(CSR_NVENCSRD) | BIT(CSR_PPCSAHBDMAR) | BIT(CSR_PPCSAHBSLVR));
+ carveout->client_access_1 = (BIT(CSR_MPCORER) | BIT(CSW_NVENCSWR) | BIT(CSW_AFIW) | BIT(CSW_HDAW) | BIT(CSW_HOST1XW) | BIT(CSW_MPCOREW) | BIT(CSW_PPCSAHBDMAW) | BIT(CSW_PPCSAHBSLVW));
+ carveout->client_access_2 = (BIT(CSR_XUSB_HOSTR) | BIT(CSW_XUSB_HOSTW) | BIT(CSR_XUSB_DEVR) | BIT(CSW_XUSB_DEVW) | BIT(CSR_TSECSRD) | BIT(CSW_TSECSWR));
+ carveout->client_access_3 = (BIT(CSR_SDMMCRA) | BIT(CSR_SDMMCRAA) | BIT(CSR_SDMMCRAB) | BIT(CSW_SDMMCWA) | BIT(CSW_SDMMCWAA) | BIT(CSW_SDMMCWAB) | BIT(CSR_VICSRD) | BIT(CSW_VICSWR) | BIT(CSR_DISPLAYD) | BIT(CSR_NVDECSRD) | BIT(CSW_NVDECSWR) | BIT(CSR_APER) | BIT(CSW_APEW) | BIT(CSR_NVJPGSRD) | BIT(CSW_NVJPGSWR));
+ carveout->client_access_4 = (BIT(CSR_SESRD) | BIT(CSW_SESWR));
+ carveout->client_force_internal_access_0 = ((exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) && (carveout_id == 4)) ? BIT(CSR_AVPCARM7R) : 0;
+ carveout->client_force_internal_access_1 = ((exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) && (carveout_id == 4)) ? BIT(CSW_AVPCARM7W) : 0;
+ carveout->client_force_internal_access_2 = 0;
+ carveout->client_force_internal_access_3 = 0;
+ carveout->client_force_internal_access_4 = 0;
+ carveout->config = 0x8B;
}
diff --git a/exosphere/src/mc.h b/exosphere/src/mc.h
index de5141700..6d467d655 100644
--- a/exosphere/src/mc.h
+++ b/exosphere/src/mc.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_MC_H
#define EXOSPHERE_MC_H
@@ -11,46 +27,597 @@ static inline uintptr_t get_mc_base(void) {
}
#define MC_BASE (get_mc_base())
-
#define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n)
-#define MC_SMMU_PTB_ASID_0 MAKE_MC_REG(0x01C)
-#define MC_SMMU_PTB_DATA_0 MAKE_MC_REG(0x020)
-#define MC_SMMU_AVPC_ASID_0 MAKE_MC_REG(0x23C)
-#define MC_SMMU_PPCS1_ASID_0 MAKE_MC_REG(0x298)
+#define MC_INTSTATUS 0x0
+#define MC_INTMASK 0x4
+#define MC_ERR_STATUS 0x8
+#define MC_ERR_ADR 0xc
+#define MC_SMMU_CONFIG 0x10
+#define MC_SMMU_TLB_CONFIG 0x14
+#define MC_SMMU_PTC_CONFIG 0x18
+#define MC_SMMU_PTB_ASID 0x1c
+#define MC_SMMU_PTB_DATA 0x20
+#define MC_SMMU_TLB_FLUSH 0x30
+#define MC_SMMU_PTC_FLUSH 0x34
+#define MC_SMMU_AFI_ASID 0x238
+#define MC_SMMU_AVPC_ASID 0x23c
+#define MC_SMMU_PPCS1_ASID 0x298
+#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
+#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
+#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
+#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
+#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
+#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0
+#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
+#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
+#define MC_PCFIFO_CLIENT_CONFIG3 0xddc
+#define MC_PCFIFO_CLIENT_CONFIG4 0xde0
+#define MC_EMEM_CFG 0x50
+#define MC_EMEM_ADR_CFG 0x54
+#define MC_EMEM_ADR_CFG_DEV0 0x58
+#define MC_EMEM_ADR_CFG_DEV1 0x5c
+#define MC_EMEM_ADR_CFG_CHANNEL_MASK 0x60
+#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64
+#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68
+#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c
+#define MC_SECURITY_CFG0 0x70
+#define MC_SECURITY_CFG1 0x74
+#define MC_SECURITY_CFG3 0x9bc
+#define MC_SECURITY_RSV 0x7c
+#define MC_EMEM_ARB_CFG 0x90
+#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
+#define MC_EMEM_ARB_TIMING_RCD 0x98
+#define MC_EMEM_ARB_TIMING_RP 0x9c
+#define MC_EMEM_ARB_TIMING_RC 0xa0
+#define MC_EMEM_ARB_TIMING_RAS 0xa4
+#define MC_EMEM_ARB_TIMING_FAW 0xa8
+#define MC_EMEM_ARB_TIMING_RRD 0xac
+#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
+#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
+#define MC_EMEM_ARB_TIMING_R2R 0xb8
+#define MC_EMEM_ARB_TIMING_W2W 0xbc
+#define MC_EMEM_ARB_TIMING_R2W 0xc0
+#define MC_EMEM_ARB_TIMING_W2R 0xc4
+#define MC_EMEM_ARB_TIMING_RFCPB 0x6c0
+#define MC_EMEM_ARB_TIMING_CCDMW 0x6c4
+#define MC_EMEM_ARB_REFPB_HP_CTRL 0x6f0
+#define MC_EMEM_ARB_REFPB_BANK_CTRL 0x6f4
+#define MC_EMEM_ARB_DA_TURNS 0xd0
+#define MC_EMEM_ARB_DA_COVERS 0xd4
+#define MC_EMEM_ARB_MISC0 0xd8
+#define MC_EMEM_ARB_MISC1 0xdc
+#define MC_EMEM_ARB_MISC2 0xc8
+#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
+#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
+#define MC_EMEM_ARB_NISO_THROTTLE 0x6b0
+#define MC_EMEM_ARB_OVERRIDE 0xe8
+#define MC_EMEM_ARB_RSV 0xec
+#define MC_CLKEN_OVERRIDE 0xf4
+#define MC_TIMING_CONTROL_DBG 0xf8
+#define MC_TIMING_CONTROL 0xfc
+#define MC_STAT_CONTROL 0x100
+#define MC_STAT_STATUS 0x104
+#define MC_STAT_EMC_CLOCK_LIMIT 0x108
+#define MC_STAT_EMC_CLOCK_LIMIT_MSBS 0x10c
+#define MC_STAT_EMC_CLOCKS 0x110
+#define MC_STAT_EMC_CLOCKS_MSBS 0x114
+#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 0x118
+#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 0x158
+#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 0x11c
+#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 0x15c
+#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER 0xa20
+#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER 0xa24
+#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 0x198
+#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 0x1a8
+#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 0x19c
+#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 0x1ac
+#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER 0xa28
+#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER 0xa2c
+#define MC_STAT_EMC_FILTER_SET0_ASID 0x1a0
+#define MC_STAT_EMC_FILTER_SET1_ASID 0x1b0
+#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 0x120
+#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 0x160
+#define MC_STAT_EMC_FILTER_SET0_CLIENT_0 0x128
+#define MC_STAT_EMC_FILTER_SET1_CLIENT_0 0x168
+#define MC_STAT_EMC_FILTER_SET0_CLIENT_1 0x12c
+#define MC_STAT_EMC_FILTER_SET1_CLIENT_1 0x16c
+#define MC_STAT_EMC_FILTER_SET0_CLIENT_2 0x130
+#define MC_STAT_EMC_FILTER_SET1_CLIENT_2 0x170
+#define MC_STAT_EMC_FILTER_SET0_CLIENT_3 0x134
+#define MC_STAT_EMC_FILTER_SET0_CLIENT_4 0xb88
+#define MC_STAT_EMC_FILTER_SET1_CLIENT_3 0x174
+#define MC_STAT_EMC_FILTER_SET1_CLIENT_4 0xb8c
+#define MC_STAT_EMC_SET0_COUNT 0x138
+#define MC_STAT_EMC_SET0_COUNT_MSBS 0x13c
+#define MC_STAT_EMC_SET1_COUNT 0x178
+#define MC_STAT_EMC_SET1_COUNT_MSBS 0x17c
+#define MC_STAT_EMC_SET0_SLACK_ACCUM 0x140
+#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 0x144
+#define MC_STAT_EMC_SET1_SLACK_ACCUM 0x180
+#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 0x184
+#define MC_STAT_EMC_SET0_HISTO_COUNT 0x148
+#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 0x14c
+#define MC_STAT_EMC_SET1_HISTO_COUNT 0x188
+#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 0x18c
+#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 0x150
+#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 0x190
+#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 0x1b8
+#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 0x1bc
+#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 0x1c8
+#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 0x1cc
+#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 0x1c0
+#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 0x1d0
+#define MC_CLIENT_HOTRESET_CTRL 0x200
+#define MC_CLIENT_HOTRESET_CTRL_1 0x970
+#define MC_CLIENT_HOTRESET_STATUS 0x204
+#define MC_CLIENT_HOTRESET_STATUS_1 0x974
+#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208
+#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c
+#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210
+#define MC_EMEM_ARB_ISOCHRONOUS_3 0x214
+#define MC_EMEM_ARB_ISOCHRONOUS_4 0xb94
+#define MC_EMEM_ARB_HYSTERESIS_0 0x218
+#define MC_EMEM_ARB_HYSTERESIS_1 0x21c
+#define MC_EMEM_ARB_HYSTERESIS_2 0x220
+#define MC_EMEM_ARB_HYSTERESIS_3 0x224
+#define MC_EMEM_ARB_HYSTERESIS_4 0xb84
+#define MC_EMEM_ARB_DHYSTERESIS_0 0xbb0
+#define MC_EMEM_ARB_DHYSTERESIS_1 0xbb4
+#define MC_EMEM_ARB_DHYSTERESIS_2 0xbb8
+#define MC_EMEM_ARB_DHYSTERESIS_3 0xbbc
+#define MC_EMEM_ARB_DHYSTERESIS_4 0xbc0
+#define MC_EMEM_ARB_DHYST_CTRL 0xbcc
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xbd0
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xbd4
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xbd8
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xbdc
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xbe0
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xbe4
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xbe8
+#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xbec
+#define MC_RESERVED_RSV 0x3fc
+#define MC_DISB_EXTRA_SNAP_LEVELS 0x408
+#define MC_APB_EXTRA_SNAP_LEVELS 0x2a4
+#define MC_AHB_EXTRA_SNAP_LEVELS 0x2a0
+#define MC_USBD_EXTRA_SNAP_LEVELS 0xa18
+#define MC_ISP_EXTRA_SNAP_LEVELS 0xa08
+#define MC_AUD_EXTRA_SNAP_LEVELS 0xa10
+#define MC_MSE_EXTRA_SNAP_LEVELS 0x40c
+#define MC_GK2_EXTRA_SNAP_LEVELS 0xa40
+#define MC_A9AVPPC_EXTRA_SNAP_LEVELS 0x414
+#define MC_FTOP_EXTRA_SNAP_LEVELS 0x2bc
+#define MC_JPG_EXTRA_SNAP_LEVELS 0xa3c
+#define MC_HOST_EXTRA_SNAP_LEVELS 0xa14
+#define MC_SAX_EXTRA_SNAP_LEVELS 0x2c0
+#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac
+#define MC_VICPC_EXTRA_SNAP_LEVELS 0xa1c
+#define MC_HDAPC_EXTRA_SNAP_LEVELS 0xa48
+#define MC_AVP_EXTRA_SNAP_LEVELS 0x2a8
+#define MC_USBX_EXTRA_SNAP_LEVELS 0x404
+#define MC_PCX_EXTRA_SNAP_LEVELS 0x2b8
+#define MC_SD_EXTRA_SNAP_LEVELS 0xa04
+#define MC_DFD_EXTRA_SNAP_LEVELS 0xa4c
+#define MC_VE_EXTRA_SNAP_LEVELS 0x2d8
+#define MC_GK_EXTRA_SNAP_LEVELS 0xa00
+#define MC_VE2_EXTRA_SNAP_LEVELS 0x410
+#define MC_SDM_EXTRA_SNAP_LEVELS 0xa44
+#define MC_VIDEO_PROTECT_BOM 0x648
+#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
+#define MC_VIDEO_PROTECT_BOM_ADR_HI 0x978
+#define MC_VIDEO_PROTECT_REG_CTRL 0x650
+#define MC_ERR_VPR_STATUS 0x654
+#define MC_ERR_VPR_ADR 0x658
+#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418
+#define MC_VIDEO_PROTECT_VPR_OVERRIDE1 0x590
+#define MC_IRAM_BOM 0x65c
+#define MC_IRAM_TOM 0x660
+#define MC_IRAM_ADR_HI 0x980
+#define MC_IRAM_REG_CTRL 0x964
+#define MC_EMEM_CFG_ACCESS_CTRL 0x664
+#define MC_TZ_SECURITY_CTRL 0x668
+#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c
+#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO 0x6b4
+#define MC_EMEM_ARB_RING0_THROTTLE_MASK 0x6bc
+#define MC_EMEM_ARB_NISO_THROTTLE_MASK 0x6b8
+#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1 0xb80
+#define MC_SEC_CARVEOUT_BOM 0x670
+#define MC_SEC_CARVEOUT_SIZE_MB 0x674
+#define MC_SEC_CARVEOUT_ADR_HI 0x9d4
+#define MC_SEC_CARVEOUT_REG_CTRL 0x678
+#define MC_ERR_SEC_STATUS 0x67c
+#define MC_ERR_SEC_ADR 0x680
+#define MC_PC_IDLE_CLOCK_GATE_CONFIG 0x684
+#define MC_STUTTER_CONTROL 0x688
+#define MC_RESERVED_RSV_1 0x958
+#define MC_DVFS_PIPE_SELECT 0x95c
+#define MC_AHB_PTSA_MIN 0x4e0
+#define MC_AUD_PTSA_MIN 0x54c
+#define MC_MLL_MPCORER_PTSA_RATE 0x44c
+#define MC_RING2_PTSA_RATE 0x440
+#define MC_USBD_PTSA_RATE 0x530
+#define MC_USBX_PTSA_MIN 0x528
+#define MC_USBD_PTSA_MIN 0x534
+#define MC_APB_PTSA_MAX 0x4f0
+#define MC_JPG_PTSA_RATE 0x584
+#define MC_DIS_PTSA_MIN 0x420
+#define MC_AVP_PTSA_MAX 0x4fc
+#define MC_AVP_PTSA_RATE 0x4f4
+#define MC_RING1_PTSA_MIN 0x480
+#define MC_DIS_PTSA_MAX 0x424
+#define MC_SD_PTSA_MAX 0x4d8
+#define MC_MSE_PTSA_RATE 0x4c4
+#define MC_VICPC_PTSA_MIN 0x558
+#define MC_PCX_PTSA_MAX 0x4b4
+#define MC_ISP_PTSA_RATE 0x4a0
+#define MC_A9AVPPC_PTSA_MIN 0x48c
+#define MC_RING2_PTSA_MAX 0x448
+#define MC_AUD_PTSA_RATE 0x548
+#define MC_HOST_PTSA_MIN 0x51c
+#define MC_MLL_MPCORER_PTSA_MAX 0x454
+#define MC_SD_PTSA_MIN 0x4d4
+#define MC_RING1_PTSA_RATE 0x47c
+#define MC_JPG_PTSA_MIN 0x588
+#define MC_HDAPC_PTSA_MIN 0x62c
+#define MC_AVP_PTSA_MIN 0x4f8
+#define MC_JPG_PTSA_MAX 0x58c
+#define MC_VE_PTSA_MAX 0x43c
+#define MC_DFD_PTSA_MAX 0x63c
+#define MC_VICPC_PTSA_RATE 0x554
+#define MC_GK_PTSA_MAX 0x544
+#define MC_VICPC_PTSA_MAX 0x55c
+#define MC_SDM_PTSA_MAX 0x624
+#define MC_SAX_PTSA_RATE 0x4b8
+#define MC_PCX_PTSA_MIN 0x4b0
+#define MC_APB_PTSA_MIN 0x4ec
+#define MC_GK2_PTSA_MIN 0x614
+#define MC_PCX_PTSA_RATE 0x4ac
+#define MC_RING1_PTSA_MAX 0x484
+#define MC_HDAPC_PTSA_RATE 0x628
+#define MC_MLL_MPCORER_PTSA_MIN 0x450
+#define MC_GK2_PTSA_MAX 0x618
+#define MC_AUD_PTSA_MAX 0x550
+#define MC_GK2_PTSA_RATE 0x610
+#define MC_ISP_PTSA_MAX 0x4a8
+#define MC_DISB_PTSA_RATE 0x428
+#define MC_VE2_PTSA_MAX 0x49c
+#define MC_DFD_PTSA_MIN 0x638
+#define MC_FTOP_PTSA_RATE 0x50c
+#define MC_A9AVPPC_PTSA_RATE 0x488
+#define MC_VE2_PTSA_MIN 0x498
+#define MC_USBX_PTSA_MAX 0x52c
+#define MC_DIS_PTSA_RATE 0x41c
+#define MC_USBD_PTSA_MAX 0x538
+#define MC_A9AVPPC_PTSA_MAX 0x490
+#define MC_USBX_PTSA_RATE 0x524
+#define MC_FTOP_PTSA_MAX 0x514
+#define MC_HDAPC_PTSA_MAX 0x630
+#define MC_SD_PTSA_RATE 0x4d0
+#define MC_DFD_PTSA_RATE 0x634
+#define MC_FTOP_PTSA_MIN 0x510
+#define MC_SDM_PTSA_RATE 0x61c
+#define MC_AHB_PTSA_RATE 0x4dc
+#define MC_SMMU_SMMU_PTSA_MAX 0x460
+#define MC_RING2_PTSA_MIN 0x444
+#define MC_SDM_PTSA_MIN 0x620
+#define MC_APB_PTSA_RATE 0x4e8
+#define MC_MSE_PTSA_MIN 0x4c8
+#define MC_HOST_PTSA_RATE 0x518
+#define MC_VE_PTSA_RATE 0x434
+#define MC_AHB_PTSA_MAX 0x4e4
+#define MC_SAX_PTSA_MIN 0x4bc
+#define MC_SMMU_SMMU_PTSA_MIN 0x45c
+#define MC_ISP_PTSA_MIN 0x4a4
+#define MC_HOST_PTSA_MAX 0x520
+#define MC_SAX_PTSA_MAX 0x4c0
+#define MC_VE_PTSA_MIN 0x438
+#define MC_GK_PTSA_MIN 0x540
+#define MC_MSE_PTSA_MAX 0x4cc
+#define MC_DISB_PTSA_MAX 0x430
+#define MC_DISB_PTSA_MIN 0x42c
+#define MC_SMMU_SMMU_PTSA_RATE 0x458
+#define MC_VE2_PTSA_RATE 0x494
+#define MC_GK_PTSA_RATE 0x53c
+#define MC_PTSA_GRANT_DECREMENT 0x960
+#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
+#define MC_LATENCY_ALLOWANCE_AXIAP_0 0x3a0
+#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
+#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384
+#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc
+#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8
+#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
+#define MC_LATENCY_ALLOWANCE_SE_0 0x3e0
+#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
+#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
+#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
+#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
+#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3d8
+#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
+#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
+#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 0x694
+#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
+#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
+#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
+#define MC_LATENCY_ALLOWANCE_TSECB_0 0x3f0
+#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 0x698
+#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
+#define MC_LATENCY_ALLOWANCE_APE_0 0x3dc
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 0x6a0
+#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4
+#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3e8
+#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
+#define MC_LATENCY_ALLOWANCE_HC_1 0x314
+#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0
+#define MC_LATENCY_ALLOWANCE_NVJPG_0 0x3e4
+#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
+#define MC_LATENCY_ALLOWANCE_ETR_0 0x3ec
+#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
+#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 0x69c
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 0x6a4
+#define MC_LATENCY_ALLOWANCE_SATA_0 0x350
+#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 0x690
+#define MC_LATENCY_ALLOWANCE_HC_0 0x310
+#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8
+#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac
+#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4
+#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388
+#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328
+#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
+#define MC_MIN_LENGTH_APE_0 0xb34
+#define MC_MIN_LENGTH_DCB_2 0x8a8
+#define MC_MIN_LENGTH_A9AVP_0 0x950
+#define MC_MIN_LENGTH_TSEC_0 0x93c
+#define MC_MIN_LENGTH_DC_1 0x898
+#define MC_MIN_LENGTH_AXIAP_0 0x94c
+#define MC_MIN_LENGTH_ISP2B_0 0x930
+#define MC_MIN_LENGTH_VI2_0 0x944
+#define MC_MIN_LENGTH_DCB_0 0x8a0
+#define MC_MIN_LENGTH_DCB_1 0x8a4
+#define MC_MIN_LENGTH_PPCS_1 0x8f4
+#define MC_MIN_LENGTH_NVJPG_0 0xb3c
+#define MC_MIN_LENGTH_HDA_0 0x8c4
+#define MC_MIN_LENGTH_NVENC_0 0x8d4
+#define MC_MIN_LENGTH_SDMMC_0 0xb18
+#define MC_MIN_LENGTH_ISP2B_1 0x934
+#define MC_MIN_LENGTH_HC_1 0x8c0
+#define MC_MIN_LENGTH_DC_3 0xb20
+#define MC_MIN_LENGTH_AVPC_0 0x890
+#define MC_MIN_LENGTH_VIC_0 0x940
+#define MC_MIN_LENGTH_ISP2_0 0x91c
+#define MC_MIN_LENGTH_HC_0 0x8bc
+#define MC_MIN_LENGTH_SE_0 0xb38
+#define MC_MIN_LENGTH_NVDEC_0 0xb30
+#define MC_MIN_LENGTH_SATA_0 0x8fc
+#define MC_MIN_LENGTH_DC_0 0x894
+#define MC_MIN_LENGTH_XUSB_1 0x92c
+#define MC_MIN_LENGTH_DC_2 0x89c
+#define MC_MIN_LENGTH_SDMMCAA_0 0xb14
+#define MC_MIN_LENGTH_GPU_0 0xb04
+#define MC_MIN_LENGTH_ETR_0 0xb44
+#define MC_MIN_LENGTH_AFI_0 0x88c
+#define MC_MIN_LENGTH_PPCS_0 0x8f0
+#define MC_MIN_LENGTH_ISP2_1 0x920
+#define MC_MIN_LENGTH_XUSB_0 0x928
+#define MC_MIN_LENGTH_MPCORE_0 0x8cc
+#define MC_MIN_LENGTH_TSECB_0 0xb48
+#define MC_MIN_LENGTH_SDMMCA_0 0xb10
+#define MC_MIN_LENGTH_GPU2_0 0xb40
+#define MC_MIN_LENGTH_SDMMCAB_0 0xb1c
+#define MC_MIN_LENGTH_PTC_0 0x8f8
+#define MC_EMEM_ARB_OVERRIDE_1 0x968
+#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0 0x984
+#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1 0x988
+#define MC_EMEM_ARB_STATS_0 0x990
+#define MC_EMEM_ARB_STATS_1 0x994
+#define MC_MTS_CARVEOUT_BOM 0x9a0
+#define MC_MTS_CARVEOUT_SIZE_MB 0x9a4
+#define MC_MTS_CARVEOUT_ADR_HI 0x9a8
+#define MC_MTS_CARVEOUT_REG_CTRL 0x9ac
+#define MC_ERR_MTS_STATUS 0x9b0
+#define MC_ERR_MTS_ADR 0x9b4
+#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
+#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
+#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 0xd74
+#define MC_SECURITY_CARVEOUT4_CFG0 0xcf8
+#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 0xd10
+#define MC_SECURITY_CARVEOUT4_SIZE_128KB 0xd04
+#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 0xc28
+#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 0xc30
+#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 0xc8c
+#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 0xd1c
+#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 0xd70
+#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 0xc2c
+#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 0xd7c
+#define MC_SECURITY_CARVEOUT3_SIZE_128KB 0xcb4
+#define MC_SECURITY_CARVEOUT2_CFG0 0xc58
+#define MC_SECURITY_CARVEOUT1_CFG0 0xc08
+#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 0xc84
+#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 0xc68
+#define MC_SECURITY_CARVEOUT3_BOM 0xcac
+#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 0xc70
+#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 0xd78
+#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 0xc7c
+#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 0xd18
+#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 0xcbc
+#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 0xc38
+#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 0xc34
+#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 0xcc0
+#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 0xd60
+#define MC_SECURITY_CARVEOUT3_CFG0 0xca8
+#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 0xcb8
+#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 0xc88
+#define MC_SECURITY_CARVEOUT2_SIZE_128KB 0xc64
+#define MC_SECURITY_CARVEOUT5_BOM_HI 0xd50
+#define MC_SECURITY_CARVEOUT1_SIZE_128KB 0xc14
+#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 0xd14
+#define MC_SECURITY_CARVEOUT1_BOM 0xc0c
+#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 0xd2c
+#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 0xd68
+#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 0xcc8
+#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 0xd58
+#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 0xd24
+#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 0xcc4
+#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 0xc78
+#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 0xc1c
+#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 0xc18
+#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 0xd28
+#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 0xd5c
+#define MC_SECURITY_CARVEOUT3_BOM_HI 0xcb0
+#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 0xcd8
+#define MC_SECURITY_CARVEOUT2_BOM_HI 0xc60
+#define MC_SECURITY_CARVEOUT4_BOM_HI 0xd00
+#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 0xd64
+#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 0xcdc
+#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 0xc80
+#define MC_SECURITY_CARVEOUT5_SIZE_128KB 0xd54
+#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 0xd20
+#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 0xcd4
+#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 0xd0c
+#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 0xc74
+#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 0xccc
+#define MC_SECURITY_CARVEOUT4_BOM 0xcfc
+#define MC_SECURITY_CARVEOUT5_CFG0 0xd48
+#define MC_SECURITY_CARVEOUT2_BOM 0xc5c
+#define MC_SECURITY_CARVEOUT5_BOM 0xd4c
+#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 0xc24
+#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 0xd6c
+#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 0xcd0
+#define MC_SECURITY_CARVEOUT1_BOM_HI 0xc10
+#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 0xc20
+#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 0xc3c
+#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c
+#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08
+#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
+#define MC_DA_CONFIG0 0x9dc
-#define MC_SECURITY_CFG0_0 MAKE_MC_REG(0x070)
-#define MC_SECURITY_CFG1_0 MAKE_MC_REG(0x074)
-#define MC_SECURITY_CFG3_0 MAKE_MC_REG(0x9BC)
+/* Virtual aliases */
+#define VIRT_MC_SECURITY_CFG3 MAKE_MC_REG(MC_SECURITY_CFG3)
+/* Memory Controller clients */
+#define CLIENT_ACCESS_NUM_CLIENTS 32
+typedef enum {
+ /* _ACCESS0 */
+ CSR_PTCR = (0 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0A = (1 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0AB = (2 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0B = (3 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0BB = (4 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0C = (5 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0CB = (6 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_AFIR = (14 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_AVPCARM7R = (15 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAYHC = (16 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAYHCB = (17 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_HDAR = (21 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_HOST1XDMAR = (22 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_HOST1XR = (23 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_NVENCSRD = (28 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_PPCSAHBDMAR = (29 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_PPCSAHBSLVR = (30 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_SATAR = (31 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+
+ /* _ACCESS1 */
+ CSR_VDEBSEVR = (34 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_VDEMBER = (35 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_VDEMCER = (36 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_VDETPER = (37 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_MPCORELPR = (38 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_MPCORER = (39 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_NVENCSWR = (43 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_AFIW = (49 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_AVPCARM7W = (50 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_HDAW = (53 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_HOST1XW = (54 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_MPCORELPW = (56 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_MPCOREW = (57 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_PPCSAHBDMAW = (59 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_PPCSAHBSLVW = (60 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_SATAW = (61 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_VDEBSEVW = (62 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_VDEDBGW = (63 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+
+ /* _ACCESS2 */
+ CSW_VDEMBEW = (64 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_VDETPMW = (65 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_ISPRA = (68 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWA = (70 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWB = (71 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_XUSB_HOSTR = (74 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_XUSB_HOSTW = (75 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_XUSB_DEVR = (76 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_XUSB_DEVW = (77 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_ISPRAB = (78 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWAB = (80 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWBB = (81 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_TSECSRD = (84 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_TSECSWR = (85 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_A9AVPSCR = (86 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_A9AVPSCW = (87 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_GPUSRD = (88 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_GPUSWR = (89 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_DISPLAYT = (90 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+
+ /* _ACCESS3 */
+ CSR_SDMMCRA = (96 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_SDMMCRAA = (97 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_SDMMCR = (98 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_SDMMCRAB = (99 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCWA = (100 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCWAA = (101 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCW = (102 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCWAB = (103 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_VICSRD = (108 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_VICSWR = (109 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_VIW = (114 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_DISPLAYD = (115 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_NVDECSRD = (120 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_NVDECSWR = (121 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_APER = (122 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_APEW = (123 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_NVJPGSRD = (126 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_NVJPGSWR = (127 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+
+ /* _ACCESS4 */
+ CSR_SESRD = (128 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_SESWR = (129 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_AXIAPR = (130 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_AXIAPW = (131 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_ETRR = (132 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_ETRW = (133 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_TSECSRDB = (134 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_TSECSWRB = (135 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_GPUSRD2 = (136 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_GPUSWR2 = (137 - (CLIENT_ACCESS_NUM_CLIENTS * 4))
+} McClient;
+/* Memory Controller carveouts */
#define CARVEOUT_ID_MIN 1
#define CARVEOUT_ID_MAX 5
-
#define KERNEL_CARVEOUT_SIZE_MAX 0x1FFE0000
-
typedef struct {
- uint32_t allowed_clients;
+ uint32_t config;
uint32_t paddr_low;
uint32_t paddr_high;
uint32_t size_big_pages;
- uint32_t flags_0;
- uint32_t flags_1;
- uint32_t flags_2;
- uint32_t flags_3;
- uint32_t flags_4;
- uint32_t flags_5;
- uint32_t flags_6;
- uint32_t flags_7;
- uint32_t flags_8;
- uint32_t flags_9;
+ uint32_t client_access_0;
+ uint32_t client_access_1;
+ uint32_t client_access_2;
+ uint32_t client_access_3;
+ uint32_t client_access_4;
+ uint32_t client_force_internal_access_0;
+ uint32_t client_force_internal_access_1;
+ uint32_t client_force_internal_access_2;
+ uint32_t client_force_internal_access_3;
+ uint32_t client_force_internal_access_4;
uint8_t padding[0x18];
} security_carveout_t;
-
volatile security_carveout_t *get_carveout_by_id(unsigned int carveout);
void configure_default_carveouts(void);
+void configure_gpu_ucode_carveout(void);
void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint64_t size);
-
-#endif
+#endif
\ No newline at end of file
diff --git a/exosphere/src/memory_map.h b/exosphere/src/memory_map.h
index 723fc758a..83ceca4e9 100644
--- a/exosphere/src/memory_map.h
+++ b/exosphere/src/memory_map.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_MEMORY_MAP_H
#define EXOSPHERE_MEMORY_MAP_H
@@ -32,7 +48,32 @@
#define _MMAPDEV15 ( 0x6000D000ull, 0x1000ull, true ) /* GPIO-1 - GPIO-8 */
#define _MMAPDEV16 ( 0x7000C000ull, 0x1000ull, true ) /* I2C-I2C4 */
#define _MMAPDEV17 ( 0x6000F000ull, 0x1000ull, true ) /* Exception vectors */
-#define _MMAPDEV18 ( 0x40038000ull, 0x8000ull, true ) /* DEBUG: IRAM */
+#define _MMAPDEV18 ( 0x00000000ull, 0x1000ull, true ) /* AMS irampage, NOT mapped at startup */
+#define _MMAPDEV19 ( 0x00000000ull, 0x1000ull, true ) /* AMS userpage, NOT mapped at startup */
+#define _MMAPDEV20 ( 0x40038000ull, 0x5000ull, true ) /* DEBUG: IRAM */
+
+/* MMIO 7.0.0+. (addr). */
+#define _MMAPDEV7X0 ( 0x50041000ull ) /* ARM Interrupt Distributor */
+#define _MMAPDEV7X1 ( 0x50042000ull ) /* Interrupt Controller Physical CPU interface */
+#define _MMAPDEV7X2 ( 0x70006000ull ) /* UART */
+#define _MMAPDEV7X3 ( 0x60006000ull ) /* Clock and Reset */
+#define _MMAPDEV7X4 ( 0x7000E000ull ) /* RTC, PMC */
+#define _MMAPDEV7X5 ( 0x60005000ull ) /* TMRs, WDTs */
+#define _MMAPDEV7X6 ( 0x6000C000ull ) /* System Registers */
+#define _MMAPDEV7X7 ( 0x70012000ull ) /* SE */
+#define _MMAPDEV7X8 ( 0x700F0000ull ) /* SYSCTR0 */
+#define _MMAPDEV7X9 ( 0x70019000ull ) /* MC */
+#define _MMAPDEV7X10 ( 0x7000F000ull ) /* FUSE (0x7000F800) */
+#define _MMAPDEV7X11 ( 0x70000000ull ) /* MISC */
+#define _MMAPDEV7X12 ( 0x60007000ull ) /* Flow Controller */
+#define _MMAPDEV7X13 ( 0x40000000ull ) /* NX bootloader mailbox page */
+#define _MMAPDEV7X14 ( 0x7000D000ull ) /* I2C-5,6 - SPI 2B-1 to 4 */
+#define _MMAPDEV7X15 ( 0x6000D000ull ) /* GPIO-1 - GPIO-8 */
+#define _MMAPDEV7X16 ( 0x7000C000ull ) /* I2C-I2C4 */
+#define _MMAPDEV7X17 ( 0x6000F000ull ) /* Exception vectors */
+#define _MMAPDEV7X18 ( 0x00000000ull ) /* AMS irampage, NOT mapped at startup */
+#define _MMAPDEV7X19 ( 0x00000000ull ) /* AMS userpage, NOT mapped at startup */
+#define _MMAPDEV7X20 ( 0x40038000ull ) /* DEBUG: IRAM */
/* LP0 entry ram segments (addr, size, additional attributes) */
#define _MMAPLP0ES0 ( 0x40020000ull, 0x10000ull, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE ) /* Encrypted TZRAM */
@@ -53,6 +94,16 @@
#define _MMAPTZS6 ( 0x1000ull, 0x1000ull, 0x02000ull, false ) /* L2 translation table */
#define _MMAPTZS7 ( 0x2000ull, 0x1000ull, 0x02000ull, false ) /* L3 translation table */
+/* TZRAM segments for 5.0.0+. (offset). */
+#define _MMAPTZ5XS0 ( 0x3000ull ) /* Warmboot crt0 sections and main code segment */
+#define _MMAPTZ5XS1 ( 0ull ) /* pk2ldr segment */
+#define _MMAPTZ5XS2 ( 0ull ) /* SPL .bss buffer, NOT mapped at startup */
+#define _MMAPTZ5XS3 ( 0ull ) /* Core 0ull1,2 stack */
+#define _MMAPTZ5XS4 ( 0x1000ull ) /* Core 3 stack */
+#define _MMAPTZ5XS5 ( 0x2000ull ) /* Secure Monitor exception vectors, some init stacks */
+#define _MMAPTZ5XS6 ( 0x10000 - 0x2000ull ) /* L2 translation table */
+#define _MMAPTZ5XS7 ( 0x10000 - 0x1000ull ) /* L3 translation table */
+
#define MMIO_BASE 0x1F0080000ull
#define LP0_ENTRY_RAM_SEGMENT_BASE (MMIO_BASE + 0x000100000ull)
#define WARMBOOT_RAM_SEGMENT_BASE (LP0_ENTRY_RAM_SEGMENT_BASE + 0x000047000ull) /* increment seems to be arbitrary ? */
@@ -82,8 +133,10 @@
#define MMIO_DEVID_GPIO 15
#define MMIO_DEVID_DTV_I2C234 16
#define MMIO_DEVID_EXCEPTION_VECTORS 17
-#define MMIO_DEVID_DEBUG_IRAM 18
-#define MMIO_DEVID_MAX 19
+#define MMIO_DEVID_AMS_IRAM_PAGE 18
+#define MMIO_DEVID_AMS_USER_PAGE 19
+#define MMIO_DEVID_DEBUG_IRAM 20
+#define MMIO_DEVID_MAX 21
#define LP0_ENTRY_RAM_SEGMENT_ID_ENCRYPTED_TZRAM 0
#define LP0_ENTRY_RAM_SEGMENT_ID_LP0_ENTRY_CODE 1
@@ -110,6 +163,7 @@
#define IDENTITY_IS_MAPPING_BLOCK_RANGE(mapping_id) (TUPLE_ELEM_3(CAT(_MMAPID, EVAL(mapping_id))))
#define MMIO_GET_DEVICE_PA(device_id) (TUPLE_ELEM_0(CAT(_MMAPDEV, EVAL(device_id))))
+#define MMIO_GET_DEVICE_7X_PA(device_id) (TUPLE_ELEM_0(CAT(_MMAPDEV, EVAL(device_id))))
#define MMIO_GET_DEVICE_ADDRESS(device_id)\
(\
(TUPLE_FOLD_LEFT_1(EVAL(device_id), _MMAPDEV, PLUS) EVAL(MMIO_BASE)) +\
@@ -129,6 +183,7 @@
#define WARMBOOT_GET_RAM_SEGMENT_ATTRIBS(segment_id) (TUPLE_ELEM_2(CAT(_MMAPWBS, EVAL(segment_id))))
#define TZRAM_GET_SEGMENT_PA(segment_id) (0x7C010000ull + (TUPLE_ELEM_0(CAT(_MMAPTZS, EVAL(segment_id)))))
+#define TZRAM_GET_SEGMENT_5X_PA(segment_id) (0x7C010000ull + (TUPLE_ELEM_0(CAT(_MMAPTZ5XS, EVAL(segment_id)))))
#define TZRAM_GET_SEGMENT_ADDRESS(segment_id) (TUPLE_FOLD_LEFT_2(EVAL(segment_id), _MMAPTZS, PLUS) EVAL(TZRAM_SEGMENT_BASE))
#define TZRAM_GET_SEGMENT_SIZE(segment_id) (TUPLE_ELEM_1(CAT(_MMAPTZS, EVAL(segment_id))))
#define TZRAM_IS_SEGMENT_EXECUTABLE(segment_id) (TUPLE_ELEM_3(CAT(_MMAPTZS, EVAL(segment_id))))
diff --git a/exosphere/src/misc.h b/exosphere/src/misc.h
index 7d667524c..1f56b5161 100644
--- a/exosphere/src/misc.h
+++ b/exosphere/src/misc.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_MISC_H
#define EXOSPHERE_MISC_H
diff --git a/exosphere/src/mmu.h b/exosphere/src/mmu.h
index ed9b885bc..a85569308 100644
--- a/exosphere/src/mmu.h
+++ b/exosphere/src/mmu.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_MMU_H
#define EXOSPHERE_MMU_H
@@ -149,6 +165,10 @@ static inline void mmu_unmap(unsigned int level, uintptr_t *tbl, uintptr_t base_
tbl[mmu_compute_index(level, base_addr)] = MMU_PTE_TYPE_FAULT;
}
+static inline void mmu_unmap_page(uintptr_t *tbl, uintptr_t base_addr) {
+ tbl[mmu_compute_index(3, base_addr)] = MMU_PTE_TYPE_FAULT;
+}
+
static inline void mmu_map_block_range(unsigned int level, uintptr_t *tbl, uintptr_t base_addr, uintptr_t phys_addr, size_t size, uint64_t attrs) {
size = ((size + (BITL(MMU_Lx_SHIFT(level)) - 1)) >> MMU_Lx_SHIFT(level)) << MMU_Lx_SHIFT(level);
for(size_t offset = 0; offset < size; offset += BITL(MMU_Lx_SHIFT(level))) {
diff --git a/exosphere/src/my_libc.c b/exosphere/src/my_libc.c
new file mode 100644
index 000000000..35bd35bbb
--- /dev/null
+++ b/exosphere/src/my_libc.c
@@ -0,0 +1,1141 @@
+/* Note: copied from newlib */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include
+
+/*
+ * Copyright (C) 2004 CodeSourcery, LLC
+ *
+ * Permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies.
+ *
+ * This file is distributed WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Handle ELF .{pre_init,init,fini}_array sections. */
+#include
+
+#ifndef HAVE_INITFINI_ARRAY
+#define HAVE_INITFINI_ARRAY
+#endif
+
+#undef HAVE_INIT_FINI
+
+#ifdef HAVE_INITFINI_ARRAY
+
+/* These magic symbols are provided by the linker. */
+extern void (*__preinit_array_start []) (void) __attribute__((weak));
+extern void (*__preinit_array_end []) (void) __attribute__((weak));
+extern void (*__init_array_start []) (void) __attribute__((weak));
+extern void (*__init_array_end []) (void) __attribute__((weak));
+
+#ifdef HAVE_INIT_FINI
+extern void _init (void);
+#endif
+
+/* Iterate over all the init routines. */
+void
+__libc_init_array (void)
+{
+ size_t count;
+ size_t i;
+
+ count = __preinit_array_end - __preinit_array_start;
+ for (i = 0; i < count; i++)
+ __preinit_array_start[i] ();
+
+#ifdef HAVE_INIT_FINI
+ _init ();
+#endif
+
+ count = __init_array_end - __init_array_start;
+ for (i = 0; i < count; i++)
+ __init_array_start[i] ();
+}
+#endif
+
+#ifdef HAVE_INITFINI_ARRAY
+extern void (*__fini_array_start []) (void) __attribute__((weak));
+extern void (*__fini_array_end []) (void) __attribute__((weak));
+
+#ifdef HAVE_INIT_FINI
+extern void _fini (void);
+#endif
+
+/* Run all the cleanup routines. */
+void
+__libc_fini_array (void)
+{
+ size_t count;
+ size_t i;
+
+ count = __fini_array_end - __fini_array_start;
+ for (i = count; i > 0; i--)
+ __fini_array_start[i-1] ();
+
+#ifdef HAVE_INIT_FINI
+ _fini ();
+#endif
+}
+#endif
+
+/*
+FUNCTION
+ <>---move possibly overlapping memory
+INDEX
+ memmove
+SYNOPSIS
+ #include
+ void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
+DESCRIPTION
+ This function moves <[length]> characters from the block of
+ memory starting at <<*<[src]>>> to the memory starting at
+ <<*<[dst]>>>. <> reproduces the characters correctly
+ at <<*<[dst]>>> even if the two areas overlap.
+RETURNS
+ The function returns <[dst]> as passed.
+PORTABILITY
+<> is ANSI C.
+<> requires no supporting OS subroutines.
+QUICKREF
+ memmove ansi pure
+*/
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+/* How many bytes are copied each iteration of the 4X unrolled loop. */
+#define BIGBLOCKSIZE (sizeof (long) << 2)
+
+/* How many bytes are copied each iteration of the word copy loop. */
+#define LITTLEBLOCKSIZE (sizeof (long))
+
+/* Threshhold for punting to the byte copier. */
+#undef TOO_SMALL
+#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
+
+/*SUPPRESS 20*/
+void *
+//__inhibit_loop_to_libcall
+memmove (void *dst_void,
+ const void *src_void,
+ size_t length)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ char *dst = dst_void;
+ const char *src = src_void;
+
+ if (src < dst && dst < src + length)
+ {
+ /* Have to copy backwards */
+ src += length;
+ dst += length;
+ while (length--)
+ {
+ *--dst = *--src;
+ }
+ }
+ else
+ {
+ while (length--)
+ {
+ *dst++ = *src++;
+ }
+ }
+
+ return dst_void;
+#else
+ char *dst = dst_void;
+ const char *src = src_void;
+ long *aligned_dst;
+ const long *aligned_src;
+
+ if (src < dst && dst < src + length)
+ {
+ /* Destructive overlap...have to copy backwards */
+ src += length;
+ dst += length;
+ while (length--)
+ {
+ *--dst = *--src;
+ }
+ }
+ else
+ {
+ /* Use optimizing algorithm for a non-destructive copy to closely
+ match memcpy. If the size is small or either SRC or DST is unaligned,
+ then punt into the byte copy loop. This should be rare. */
+ if (!TOO_SMALL(length) && !UNALIGNED (src, dst))
+ {
+ aligned_dst = (long*)dst;
+ aligned_src = (long*)src;
+
+ /* Copy 4X long words at a time if possible. */
+ while (length >= BIGBLOCKSIZE)
+ {
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ length -= BIGBLOCKSIZE;
+ }
+
+ /* Copy one long word at a time if possible. */
+ while (length >= LITTLEBLOCKSIZE)
+ {
+ *aligned_dst++ = *aligned_src++;
+ length -= LITTLEBLOCKSIZE;
+ }
+
+ /* Pick up any residual with a byte copier. */
+ dst = (char*)aligned_dst;
+ src = (char*)aligned_src;
+ }
+
+ while (length--)
+ {
+ *dst++ = *src++;
+ }
+ }
+
+ return dst_void;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
+
+/*
+FUNCTION
+ <>---copy memory regions
+SYNOPSIS
+ #include
+ void* memcpy(void *restrict <[out]>, const void *restrict <[in]>,
+ size_t <[n]>);
+DESCRIPTION
+ This function copies <[n]> bytes from the memory region
+ pointed to by <[in]> to the memory region pointed to by
+ <[out]>.
+ If the regions overlap, the behavior is undefined.
+RETURNS
+ <> returns a pointer to the first byte of the <[out]>
+ region.
+PORTABILITY
+<> is ANSI C.
+<> requires no supporting OS subroutines.
+QUICKREF
+ memcpy ansi pure
+ */
+
+void *
+memcpy (void * dst0,
+ const void * __restrict src0,
+ size_t len0)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ char *dst = (char *) dst0;
+ char *src = (char *) src0;
+
+ void *save = dst0;
+
+ while (len0--)
+ {
+ *dst++ = *src++;
+ }
+
+ return save;
+#else
+ char *dst = dst0;
+ const char *src = src0;
+ long *aligned_dst;
+ const long *aligned_src;
+
+ /* If the size is small, or either SRC or DST is unaligned,
+ then punt into the byte copy loop. This should be rare. */
+ if (!TOO_SMALL(len0) && !UNALIGNED (src, dst))
+ {
+ aligned_dst = (long*)dst;
+ aligned_src = (long*)src;
+
+ /* Copy 4X long words at a time if possible. */
+ while (len0 >= BIGBLOCKSIZE)
+ {
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ *aligned_dst++ = *aligned_src++;
+ len0 -= BIGBLOCKSIZE;
+ }
+
+ /* Copy one long word at a time if possible. */
+ while (len0 >= LITTLEBLOCKSIZE)
+ {
+ *aligned_dst++ = *aligned_src++;
+ len0 -= LITTLEBLOCKSIZE;
+ }
+
+ /* Pick up any residual with a byte copier. */
+ dst = (char*)aligned_dst;
+ src = (char*)aligned_src;
+ }
+
+ while (len0--)
+ *dst++ = *src++;
+
+ return dst0;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
+
+/*
+FUNCTION
+ <>---set an area of memory
+INDEX
+ memset
+SYNOPSIS
+ #include
+ void *memset(void *<[dst]>, int <[c]>, size_t <[length]>);
+DESCRIPTION
+ This function converts the argument <[c]> into an unsigned
+ char and fills the first <[length]> characters of the array
+ pointed to by <[dst]> to the value.
+RETURNS
+ <> returns the value of <[dst]>.
+PORTABILITY
+<> is ANSI C.
+ <> requires no supporting OS subroutines.
+QUICKREF
+ memset ansi pure
+*/
+
+#include
+
+#undef LBLOCKSIZE
+#undef UNALIGNED
+#undef TOO_SMALL
+
+#define LBLOCKSIZE (sizeof(long))
+#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
+#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
+
+void *
+memset (void *m,
+ int c,
+ size_t n)
+{
+ char *s = (char *) m;
+
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
+ unsigned int i;
+ unsigned long buffer;
+ unsigned long *aligned_addr;
+ unsigned int d = c & 0xff; /* To avoid sign extension, copy C to an
+ unsigned variable. */
+
+ while (UNALIGNED (s))
+ {
+ if (n--)
+ *s++ = (char) c;
+ else
+ return m;
+ }
+
+ if (!TOO_SMALL (n))
+ {
+ /* If we get this far, we know that n is large and s is word-aligned. */
+ aligned_addr = (unsigned long *) s;
+
+ /* Store D into each char sized location in BUFFER so that
+ we can set large blocks quickly. */
+ buffer = (d << 8) | d;
+ buffer |= (buffer << 16);
+ for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
+ buffer = (buffer << i) | buffer;
+
+ /* Unroll the loop. */
+ while (n >= LBLOCKSIZE*4)
+ {
+ *aligned_addr++ = buffer;
+ *aligned_addr++ = buffer;
+ *aligned_addr++ = buffer;
+ *aligned_addr++ = buffer;
+ n -= 4*LBLOCKSIZE;
+ }
+
+ while (n >= LBLOCKSIZE)
+ {
+ *aligned_addr++ = buffer;
+ n -= LBLOCKSIZE;
+ }
+ /* Pick up the remainder with a bytewise loop. */
+ s = (char*)aligned_addr;
+ }
+
+#endif /* not PREFER_SIZE_OVER_SPEED */
+
+ while (n--)
+ *s++ = (char) c;
+
+ return m;
+}
+
+/*
+FUNCTION
+ <>---find character in memory
+INDEX
+ memchr
+SYNOPSIS
+ #include
+ void *memchr(const void *<[src]>, int <[c]>, size_t <[length]>);
+DESCRIPTION
+ This function searches memory starting at <<*<[src]>>> for the
+ character <[c]>. The search only ends with the first
+ occurrence of <[c]>, or after <[length]> characters; in
+ particular, <> does not terminate the search.
+RETURNS
+ If the character <[c]> is found within <[length]> characters
+ of <<*<[src]>>>, a pointer to the character is returned. If
+ <[c]> is not found, then <> is returned.
+PORTABILITY
+<> is ANSI C.
+<> requires no supporting OS subroutines.
+QUICKREF
+ memchr ansi pure
+*/
+
+#undef LBLOCKSIZE
+#undef UNALIGNED
+#undef TOO_SMALL
+
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
+
+/* How many bytes are loaded each iteration of the word copy loop. */
+#define LBLOCKSIZE (sizeof (long))
+
+/* Threshhold for punting to the bytewise iterator. */
+#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
+
+#if LONG_MAX == 2147483647L
+#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#else
+#if LONG_MAX == 9223372036854775807L
+/* Nonzero if X (a long int) contains a NULL byte. */
+#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
+#else
+#error long int is not a 32bit or 64bit type.
+#endif
+#endif
+
+#ifndef DETECTNULL
+#error long int is not a 32bit or 64bit byte
+#endif
+
+/* DETECTCHAR returns nonzero if (long)X contains the byte used
+ to fill (long)MASK. */
+#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
+
+void *
+memchr (const void *src_void,
+ int c,
+ size_t length)
+{
+ const unsigned char *src = (const unsigned char *) src_void;
+ unsigned char d = c;
+
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
+ unsigned long *asrc;
+ unsigned long mask;
+ unsigned int i;
+
+ while (UNALIGNED (src))
+ {
+ if (!length--)
+ return NULL;
+ if (*src == d)
+ return (void *) src;
+ src++;
+ }
+
+ if (!TOO_SMALL (length))
+ {
+ /* If we get this far, we know that length is large and src is
+ word-aligned. */
+ /* The fast code reads the source one word at a time and only
+ performs the bytewise search on word-sized segments if they
+ contain the search character, which is detected by XORing
+ the word-sized segment with a word-sized block of the search
+ character and then detecting for the presence of NUL in the
+ result. */
+ asrc = (unsigned long *) src;
+ mask = d << 8 | d;
+ mask = mask << 16 | mask;
+ for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
+ mask = (mask << i) | mask;
+
+ while (length >= LBLOCKSIZE)
+ {
+ if (DETECTCHAR (*asrc, mask))
+ break;
+ length -= LBLOCKSIZE;
+ asrc++;
+ }
+
+ /* If there are fewer than LBLOCKSIZE characters left,
+ then we resort to the bytewise loop. */
+
+ src = (unsigned char *) asrc;
+ }
+
+#endif /* not PREFER_SIZE_OVER_SPEED */
+
+ while (length--)
+ {
+ if (*src == d)
+ return (void *) src;
+ src++;
+ }
+
+ return NULL;
+}
+
+/*
+FUNCTION
+ <>---compare two memory areas
+INDEX
+ memcmp
+SYNOPSIS
+ #include
+ int memcmp(const void *<[s1]>, const void *<[s2]>, size_t <[n]>);
+DESCRIPTION
+ This function compares not more than <[n]> characters of the
+ object pointed to by <[s1]> with the object pointed to by <[s2]>.
+RETURNS
+ The function returns an integer greater than, equal to or
+ less than zero according to whether the object pointed to by
+ <[s1]> is greater than, equal to or less than the object
+ pointed to by <[s2]>.
+PORTABILITY
+<> is ANSI C.
+<> requires no supporting OS subroutines.
+QUICKREF
+ memcmp ansi pure
+*/
+
+
+#undef LBLOCKSIZE
+#undef UNALIGNED
+#undef TOO_SMALL
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+/* How many bytes are copied each iteration of the word copy loop. */
+#define LBLOCKSIZE (sizeof (long))
+
+/* Threshhold for punting to the byte copier. */
+#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
+
+int
+memcmp (const void *m1,
+ const void *m2,
+ size_t n)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ unsigned char *s1 = (unsigned char *) m1;
+ unsigned char *s2 = (unsigned char *) m2;
+
+ while (n--)
+ {
+ if (*s1 != *s2)
+ {
+ return *s1 - *s2;
+ }
+ s1++;
+ s2++;
+ }
+ return 0;
+#else
+ unsigned char *s1 = (unsigned char *) m1;
+ unsigned char *s2 = (unsigned char *) m2;
+ unsigned long *a1;
+ unsigned long *a2;
+
+ /* If the size is too small, or either pointer is unaligned,
+ then we punt to the byte compare loop. Hopefully this will
+ not turn up in inner loops. */
+ if (!TOO_SMALL(n) && !UNALIGNED(s1,s2))
+ {
+ /* Otherwise, load and compare the blocks of memory one
+ word at a time. */
+ a1 = (unsigned long*) s1;
+ a2 = (unsigned long*) s2;
+ while (n >= LBLOCKSIZE)
+ {
+ if (*a1 != *a2)
+ break;
+ a1++;
+ a2++;
+ n -= LBLOCKSIZE;
+ }
+
+ /* check m mod LBLOCKSIZE remaining characters */
+
+ s1 = (unsigned char*)a1;
+ s2 = (unsigned char*)a2;
+ }
+
+ while (n--)
+ {
+ if (*s1 != *s2)
+ return *s1 - *s2;
+ s1++;
+ s2++;
+ }
+
+ return 0;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
+
+/*
+FUNCTION
+ <>---search for character in string
+INDEX
+ strchr
+SYNOPSIS
+ #include
+ char * strchr(const char *<[string]>, int <[c]>);
+DESCRIPTION
+ This function finds the first occurence of <[c]> (converted to
+ a char) in the string pointed to by <[string]> (including the
+ terminating null character).
+RETURNS
+ Returns a pointer to the located character, or a null pointer
+ if <[c]> does not occur in <[string]>.
+PORTABILITY
+<> is ANSI C.
+<> requires no supporting OS subroutines.
+QUICKREF
+ strchr ansi pure
+*/
+
+#undef LBLOCKSIZE
+#undef UNALIGNED
+#undef TOO_SMALL
+
+
+/* Nonzero if X is not aligned on a "long" boundary. */
+#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
+
+/* How many bytes are loaded each iteration of the word copy loop. */
+#define LBLOCKSIZE (sizeof (long))
+
+char *
+strchr (const char *s1,
+ int i)
+{
+ const unsigned char *s = (const unsigned char *)s1;
+ unsigned char c = i;
+
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
+ unsigned long mask,j;
+ unsigned long *aligned_addr;
+
+ /* Special case for finding 0. */
+ if (!c)
+ {
+ while (UNALIGNED (s))
+ {
+ if (!*s)
+ return (char *) s;
+ s++;
+ }
+ /* Operate a word at a time. */
+ aligned_addr = (unsigned long *) s;
+ while (!DETECTNULL (*aligned_addr))
+ aligned_addr++;
+ /* Found the end of string. */
+ s = (const unsigned char *) aligned_addr;
+ while (*s)
+ s++;
+ return (char *) s;
+ }
+
+ /* All other bytes. Align the pointer, then search a long at a time. */
+ while (UNALIGNED (s))
+ {
+ if (!*s)
+ return NULL;
+ if (*s == c)
+ return (char *) s;
+ s++;
+ }
+
+ mask = c;
+ for (j = 8; j < LBLOCKSIZE * 8; j <<= 1)
+ mask = (mask << j) | mask;
+
+ aligned_addr = (unsigned long *) s;
+ while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask))
+ aligned_addr++;
+
+ /* The block of bytes currently pointed to by aligned_addr
+ contains either a null or the target char, or both. We
+ catch it using the bytewise search. */
+
+ s = (unsigned char *) aligned_addr;
+
+#endif /* not PREFER_SIZE_OVER_SPEED */
+
+ while (*s && *s != c)
+ s++;
+ if (*s == c)
+ return (char *)s;
+ return NULL;
+}
+
+/*
+FUNCTION
+ <>---character string compare
+
+INDEX
+ strcmp
+SYNOPSIS
+ #include
+ int strcmp(const char *<[a]>, const char *<[b]>);
+DESCRIPTION
+ <> compares the string at <[a]> to
+ the string at <[b]>.
+RETURNS
+ If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>,
+ <> returns a number greater than zero. If the two
+ strings match, <> returns zero. If <<*<[a]>>>
+ sorts lexicographically before <<*<[b]>>>, <> returns a
+ number less than zero.
+PORTABILITY
+<> is ANSI C.
+<> requires no supporting OS subroutines.
+QUICKREF
+ strcmp ansi pure
+*/
+
+#undef LBLOCKSIZE
+#undef UNALIGNED
+#undef TOO_SMALL
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+int
+strcmp (const char *s1,
+ const char *s2)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ while (*s1 != '\0' && *s1 == *s2)
+ {
+ s1++;
+ s2++;
+ }
+
+ return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+#else
+ unsigned long *a1;
+ unsigned long *a2;
+
+ /* If s1 or s2 are unaligned, then compare bytes. */
+ if (!UNALIGNED (s1, s2))
+ {
+ /* If s1 and s2 are word-aligned, compare them a word at a time. */
+ a1 = (unsigned long*)s1;
+ a2 = (unsigned long*)s2;
+ while (*a1 == *a2)
+ {
+ /* To get here, *a1 == *a2, thus if we find a null in *a1,
+ then the strings must be equal, so return zero. */
+ if (DETECTNULL (*a1))
+ return 0;
+
+ a1++;
+ a2++;
+ }
+
+ /* A difference was detected in last few bytes of s1, so search bytewise */
+ s1 = (char*)a1;
+ s2 = (char*)a2;
+ }
+
+ while (*s1 != '\0' && *s1 == *s2)
+ {
+ s1++;
+ s2++;
+ }
+ return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
+
+/*
+FUNCTION
+ <>---copy string
+INDEX
+ strcpy
+SYNOPSIS
+ #include
+ char *strcpy(char *<[dst]>, const char *<[src]>);
+DESCRIPTION
+ <> copies the string pointed to by <[src]>
+ (including the terminating null character) to the array
+ pointed to by <[dst]>.
+RETURNS
+ This function returns the initial value of <[dst]>.
+PORTABILITY
+<> is ANSI C.
+<> requires no supporting OS subroutines.
+QUICKREF
+ strcpy ansi pure
+*/
+
+/*SUPPRESS 560*/
+/*SUPPRESS 530*/
+
+#undef LBLOCKSIZE
+#undef UNALIGNED
+#undef TOO_SMALL
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary. */
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+char*
+strcpy (char *dst0,
+ const char *src0)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ char *s = dst0;
+
+ while (*dst0++ = *src0++)
+ ;
+
+ return s;
+#else
+ char *dst = dst0;
+ const char *src = src0;
+ long *aligned_dst;
+ const long *aligned_src;
+
+ /* If SRC or DEST is unaligned, then copy bytes. */
+ if (!UNALIGNED (src, dst))
+ {
+ aligned_dst = (long*)dst;
+ aligned_src = (long*)src;
+
+ /* SRC and DEST are both "long int" aligned, try to do "long int"
+ sized copies. */
+ while (!DETECTNULL(*aligned_src))
+ {
+ *aligned_dst++ = *aligned_src++;
+ }
+
+ dst = (char*)aligned_dst;
+ src = (char*)aligned_src;
+ }
+
+ while ((*dst++ = *src++))
+ ;
+ return dst0;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
+
+/*
+FUNCTION
+ <>---character string length
+INDEX
+ strlen
+SYNOPSIS
+ #include
+ size_t strlen(const char *<[str]>);
+DESCRIPTION
+ The <> function works out the length of the string
+ starting at <<*<[str]>>> by counting chararacters until it
+ reaches a <> character.
+RETURNS
+ <> returns the character count.
+PORTABILITY
+<> is ANSI C.
+<> requires no supporting OS subroutines.
+QUICKREF
+ strlen ansi pure
+*/
+
+#undef LBLOCKSIZE
+#undef UNALIGNED
+#undef TOO_SMALL
+
+#define LBLOCKSIZE (sizeof (long))
+#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
+size_t
+strlen (const char *str)
+{
+ const char *start = str;
+
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
+ unsigned long *aligned_addr;
+
+ /* Align the pointer, so we can search a word at a time. */
+ while (UNALIGNED (str))
+ {
+ if (!*str)
+ return str - start;
+ str++;
+ }
+
+ /* If the string is word-aligned, we can check for the presence of
+ a null in each word-sized block. */
+ aligned_addr = (unsigned long *)str;
+ while (!DETECTNULL (*aligned_addr))
+ aligned_addr++;
+
+ /* Once a null is detected, we check each byte in that block for a
+ precise position of the null. */
+ str = (char *) aligned_addr;
+
+#endif /* not PREFER_SIZE_OVER_SPEED */
+
+ while (*str)
+ str++;
+ return str - start;
+}
+
+/*
+FUNCTION
+ <>---character string compare
+
+INDEX
+ strncmp
+SYNOPSIS
+ #include
+ int strncmp(const char *<[a]>, const char * <[b]>, size_t <[length]>);
+DESCRIPTION
+ <> compares up to <[length]> characters
+ from the string at <[a]> to the string at <[b]>.
+RETURNS
+ If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>,
+ <> returns a number greater than zero. If the two
+ strings are equivalent, <> returns zero. If <<*<[a]>>>
+ sorts lexicographically before <<*<[b]>>>, <> returns a
+ number less than zero.
+PORTABILITY
+<> is ANSI C.
+<> requires no supporting OS subroutines.
+QUICKREF
+ strncmp ansi pure
+*/
+
+#undef LBLOCKSIZE
+#undef UNALIGNED
+#undef TOO_SMALL
+
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+int
+strncmp (const char *s1,
+ const char *s2,
+ size_t n)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ if (n == 0)
+ return 0;
+
+ while (n-- != 0 && *s1 == *s2)
+ {
+ if (n == 0 || *s1 == '\0')
+ break;
+ s1++;
+ s2++;
+ }
+
+ return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+#else
+ unsigned long *a1;
+ unsigned long *a2;
+
+ if (n == 0)
+ return 0;
+
+ /* If s1 or s2 are unaligned, then compare bytes. */
+ if (!UNALIGNED (s1, s2))
+ {
+ /* If s1 and s2 are word-aligned, compare them a word at a time. */
+ a1 = (unsigned long*)s1;
+ a2 = (unsigned long*)s2;
+ while (n >= sizeof (long) && *a1 == *a2)
+ {
+ n -= sizeof (long);
+
+ /* If we've run out of bytes or hit a null, return zero
+ since we already know *a1 == *a2. */
+ if (n == 0 || DETECTNULL (*a1))
+ return 0;
+
+ a1++;
+ a2++;
+ }
+
+ /* A difference was detected in last few bytes of s1, so search bytewise */
+ s1 = (char*)a1;
+ s2 = (char*)a2;
+ }
+
+ while (n-- > 0 && *s1 == *s2)
+ {
+ /* If we've run out of bytes or hit a null, return zero
+ since we already know *s1 == *s2. */
+ if (n == 0 || *s1 == '\0')
+ return 0;
+ s1++;
+ s2++;
+ }
+ return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
+
+/*
+FUNCTION
+ <>---counted copy string
+INDEX
+ strncpy
+SYNOPSIS
+ #include
+ char *strncpy(char *restrict <[dst]>, const char *restrict <[src]>,
+ size_t <[length]>);
+DESCRIPTION
+ <> copies not more than <[length]> characters from the
+ the string pointed to by <[src]> (including the terminating
+ null character) to the array pointed to by <[dst]>. If the
+ string pointed to by <[src]> is shorter than <[length]>
+ characters, null characters are appended to the destination
+ array until a total of <[length]> characters have been
+ written.
+RETURNS
+ This function returns the initial value of <[dst]>.
+PORTABILITY
+<> is ANSI C.
+<> requires no supporting OS subroutines.
+QUICKREF
+ strncpy ansi pure
+*/
+
+/*SUPPRESS 560*/
+/*SUPPRESS 530*/
+
+#undef LBLOCKSIZE
+#undef UNALIGNED
+#undef TOO_SMALL
+
+#define UNALIGNED(X, Y) \
+ (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+#define TOO_SMALL(LEN) ((LEN) < sizeof (long))
+
+char *
+strncpy (char *__restrict dst0,
+ const char *__restrict src0,
+ size_t count)
+{
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+ char *dscan;
+ const char *sscan;
+
+ dscan = dst0;
+ sscan = src0;
+ while (count > 0)
+ {
+ --count;
+ if ((*dscan++ = *sscan++) == '\0')
+ break;
+ }
+ while (count-- > 0)
+ *dscan++ = '\0';
+
+ return dst0;
+#else
+ char *dst = dst0;
+ const char *src = src0;
+ long *aligned_dst;
+ const long *aligned_src;
+
+ /* If SRC and DEST is aligned and count large enough, then copy words. */
+ if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
+ {
+ aligned_dst = (long*)dst;
+ aligned_src = (long*)src;
+
+ /* SRC and DEST are both "long int" aligned, try to do "long int"
+ sized copies. */
+ while (count >= sizeof (long int) && !DETECTNULL(*aligned_src))
+ {
+ count -= sizeof (long int);
+ *aligned_dst++ = *aligned_src++;
+ }
+
+ dst = (char*)aligned_dst;
+ src = (char*)aligned_src;
+ }
+
+ while (count > 0)
+ {
+ --count;
+ if ((*dst++ = *src++) == '\0')
+ break;
+ }
+
+ while (count-- > 0)
+ *dst++ = '\0';
+
+ return dst0;
+#endif /* not PREFER_SIZE_OVER_SPEED */
+}
+
+/*
+FUNCTION
+ <>---character string length
+
+INDEX
+ strnlen
+SYNOPSIS
+ #include
+ size_t strnlen(const char *<[str]>, size_t <[n]>);
+DESCRIPTION
+ The <> function works out the length of the string
+ starting at <<*<[str]>>> by counting chararacters until it
+ reaches a NUL character or the maximum: <[n]> number of
+ characters have been inspected.
+RETURNS
+ <> returns the character count or <[n]>.
+PORTABILITY
+<> is a GNU extension.
+<> requires no supporting OS subroutines.
+*/
+
+size_t
+strnlen (const char *str,
+ size_t n)
+{
+ const char *start = str;
+
+ while (n-- > 0 && *str)
+ str++;
+
+ return str - start;
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
diff --git a/exosphere/src/package2.c b/exosphere/src/package2.c
index 507acb1fa..eccec5df7 100644
--- a/exosphere/src/package2.c
+++ b/exosphere/src/package2.c
@@ -1,8 +1,23 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "utils.h"
#include "memory_map.h"
-
#include "bootup.h"
#include "cpu_context.h"
#include "package2.h"
@@ -22,20 +37,61 @@
extern void *__start_cold_addr;
extern size_t __bin_size;
+static const uint8_t new_device_key_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
+ {0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */
+ {0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.x New Device Key Source. */
+ {0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */
+ {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. */
+};
+
+static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
+ {0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D}, /* 4.x New Device Keygen Source. */
+ {0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E}, /* 5.x New Device Keygen Source. */
+ {0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF}, /* 6.x New Device Keygen Source. */
+ {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. */
+};
+
+static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
+ {0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34}, /* 4.x New Device Keygen Source. */
+ {0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8}, /* 5.x New Device Keygen Source. */
+ {0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5}, /* 6.x New Device Keygen Source. */
+ {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}, /* 6.2.0 New Device Keygen Source. */
+};
+
+static const uint8_t new_master_kek_sources[MASTERKEY_REVISION_700_CURRENT - MASTERKEY_REVISION_600_610][0x10] = {
+ {0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, /* 6.2.0 Master Kek Source. */
+ {0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, /* 7.0.0 Master Kek Source. */
+};
+
+static const uint8_t keyblob_key_seed_00[0x10] = {
+ 0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3
+};
+
+static const uint8_t devicekey_seed[0x10] = {
+ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78
+};
+
+static const uint8_t devicekey_4x_seed[0x10] = {
+ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28
+};
+
+static const uint8_t masterkey_seed[0x10] = {
+ 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C
+};
+
+static const uint8_t devicekek_4x_seed[0x10] = {
+ 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66
+};
+
static void derive_new_device_keys(unsigned int keygen_keyslot) {
uint8_t work_buffer[0x10];
- static const uint8_t new_device_key_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
- {0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */
- {0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C} /* 5.x New Device Key Source. */
- };
-
- static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
- {0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D}, /* 4.x New Device Keygen Source. */
- {0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E} /* 5.x New Device Keygen Source. */
- };
+ bool is_retail = configitem_is_retail();
for (unsigned int revision = 0; revision < MASTERKEY_NUM_NEW_DEVICE_KEYS; revision++) {
se_aes_ecb_decrypt_block(keygen_keyslot, work_buffer, 0x10, new_device_key_sources[revision], 0x10);
- decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, mkey_get_keyslot(0), new_device_keygen_sources[revision], 0x10);
+ decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, mkey_get_keyslot(0), is_retail ? new_device_keygen_sources[revision] : new_device_keygen_sources_dev[revision], 0x10);
if (revision < MASTERKEY_NUM_NEW_DEVICE_KEYS - 1) {
se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10, work_buffer, 0x10);
set_old_devkey(revision + MASTERKEY_REVISION_400_410, work_buffer);
@@ -58,15 +114,15 @@ static void setup_se(void) {
intr_initialize_gic_nonsecure();
/* Perform some sanity initialization. */
- volatile security_engine_t *p_security_engine = get_security_engine();
- p_security_engine->_0x0 &= 0xFFFEFFFF; /* Clear bit 16. */
- (void)(SECURITY_ENGINE->FLAGS_REG);
+ volatile tegra_se_t *se = se_get_regs();
+ se->_0x0 &= 0xFFFEFFFF; /* Clear bit 16. */
+ (void)(se->FLAGS_REG);
__dsb_sy();
- p_security_engine->_0x4 = 0;
- p_security_engine->AES_KEY_READ_DISABLE_REG = 0;
- p_security_engine->RSA_KEY_READ_DISABLE_REG = 0;
- p_security_engine->_0x0 &= 0xFFFFFFFB;
+ se->_0x4 = 0;
+ se->AES_KEY_READ_DISABLE_REG = 0;
+ se->RSA_KEY_READ_DISABLE_REG = 0;
+ se->_0x0 &= 0xFFFFFFFB;
/* Currently unknown what each flag does. */
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
@@ -80,20 +136,49 @@ static void setup_se(void) {
for (unsigned int i = 0; i < KEYSLOT_RSA_MAX; i++) {
set_rsa_keyslot_flags(i, 0x41);
}
+
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_620 && exosphere_should_perform_620_keygen()) {
+ unsigned int master_kek_source_ind;
+ switch (exosphere_get_target_firmware()) {
+ case ATMOSPHERE_TARGET_FIRMWARE_620:
+ master_kek_source_ind = MASTERKEY_REVISION_620 - MASTERKEY_REVISION_620;
+ break;
+ case ATMOSPHERE_TARGET_FIRMWARE_700:
+ master_kek_source_ind = MASTERKEY_REVISION_700_CURRENT - MASTERKEY_REVISION_620;
+ break;
+ default:
+ generic_panic();
+ break;
+ }
+ /* Start by generating device keys. */
+ se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_6XTSECKEY, work_buffer, 0x10, keyblob_key_seed_00, 0x10);
+ decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XOLDDEVICEKEY, KEYSLOT_SWITCH_6XSBK, work_buffer, 0x10);
+ decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XNEWCONSOLEKEYGENKEY, KEYSLOT_SWITCH_4XOLDDEVICEKEY, devicekey_4x_seed, 0x10);
+ decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XOLDDEVICEKEY, KEYSLOT_SWITCH_4XOLDDEVICEKEY, devicekey_seed, 0x10);
+
+ /* Next, generate the master kek, and from there master key/device kek. We use different keyslots than Nintendo, here. */
+ decrypt_data_into_keyslot(KEYSLOT_SWITCH_6XTSECROOTKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, new_master_kek_sources[master_kek_source_ind], 0x10);
+ decrypt_data_into_keyslot(KEYSLOT_SWITCH_MASTERKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, masterkey_seed, 0x10);
+ decrypt_data_into_keyslot(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, devicekek_4x_seed, 0x10);
+ clear_aes_keyslot(KEYSLOT_SWITCH_6XTSECROOTKEY);
+ }
/* Detect Master Key revision. */
mkey_detect_revision();
/* Derive new device keys. */
switch (exosphere_get_target_firmware()) {
- case EXOSPHERE_TARGET_FIRMWARE_100:
- case EXOSPHERE_TARGET_FIRMWARE_200:
- case EXOSPHERE_TARGET_FIRMWARE_300:
+ case ATMOSPHERE_TARGET_FIRMWARE_100:
+ case ATMOSPHERE_TARGET_FIRMWARE_200:
+ case ATMOSPHERE_TARGET_FIRMWARE_300:
break;
- case EXOSPHERE_TARGET_FIRMWARE_400:
+ case ATMOSPHERE_TARGET_FIRMWARE_400:
derive_new_device_keys(KEYSLOT_SWITCH_4XNEWDEVICEKEYGENKEY);
break;
- case EXOSPHERE_TARGET_FIRMWARE_500:
+ case ATMOSPHERE_TARGET_FIRMWARE_500:
+ case ATMOSPHERE_TARGET_FIRMWARE_600:
+ case ATMOSPHERE_TARGET_FIRMWARE_620:
+ case ATMOSPHERE_TARGET_FIRMWARE_700:
derive_new_device_keys(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY);
break;
}
@@ -111,8 +196,7 @@ static void setup_se(void) {
set_aes_keyslot_flags(KEYSLOT_SWITCH_SESSIONKEY, 0xFF);
/* Generate test vector for our keys. */
- se_generate_stored_vector();
-
+ se_generate_stored_vector();
}
static void setup_boot_config(void) {
@@ -120,14 +204,18 @@ static void setup_boot_config(void) {
if (configitem_is_retail()) {
bootconfig_clear();
} else {
- flush_dcache_range((uint8_t *)NX_BOOTLOADER_BOOTCONFIG_POINTER, (uint8_t *)NX_BOOTLOADER_BOOTCONFIG_POINTER + sizeof(bootconfig_t));
- bootconfig_load_and_verify((bootconfig_t *)NX_BOOTLOADER_BOOTCONFIG_POINTER);
+ void *bootconfig_ptr = NX_BOOTLOADER_BOOTCONFIG_POINTER;
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
+ bootconfig_ptr = NX_BOOTLOADER_BOOTCONFIG_POINTER_6X;
+ }
+ flush_dcache_range((uint8_t *)bootconfig_ptr, (uint8_t *)bootconfig_ptr + sizeof(bootconfig_t));
+ bootconfig_load_and_verify((bootconfig_t *)bootconfig_ptr);
}
}
static void package2_crypt_ctr(unsigned int master_key_rev, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) {
/* Derive package2 key. */
- const uint8_t package2_key_source[0x10] = {0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7};
+ static const uint8_t package2_key_source[0x10] = {0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7};
flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + dst_size);
flush_dcache_range((uint8_t *)src, (uint8_t *)src + src_size);
unsigned int keyslot = mkey_get_keyslot(master_key_rev);
@@ -137,7 +225,6 @@ static void package2_crypt_ctr(unsigned int master_key_rev, void *dst, size_t ds
se_aes_ctr_crypt(KEYSLOT_SWITCH_PACKAGE2KEY, dst, dst_size, src, src_size, ctr, ctr_size);
}
-
static void verify_header_signature(package2_header_t *header) {
const uint8_t *modulus;
@@ -276,7 +363,7 @@ static bool validate_package2_metadata(package2_meta_t *metadata) {
/* Perform version checks. */
/* We will be compatible with all package2s released before current, but not newer ones. */
- if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_500_CURRENT) {
+ if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_700_CURRENT) {
return true;
}
@@ -303,7 +390,7 @@ static uint32_t decrypt_and_validate_header(package2_header_t *header) {
}
/* Ensure we successfully decrypted the header. */
- if (mkey_rev > mkey_get_revision()) {
+ if (mkey_rev > mkey_get_revision()) {
panic(0xFAF00003);
}
} else if (!validate_package2_metadata(&header->metadata)) {
@@ -382,13 +469,51 @@ static void load_package2_sections(package2_meta_t *metadata, uint32_t master_ke
memset(load_buf, 0, PACKAGE2_SIZE_MAX);
}
+static void copy_warmboot_bin_to_dram() {
+ uint8_t *warmboot_src;
+ switch (exosphere_get_target_firmware()) {
+ case ATMOSPHERE_TARGET_FIRMWARE_100:
+ case ATMOSPHERE_TARGET_FIRMWARE_200:
+ case ATMOSPHERE_TARGET_FIRMWARE_300:
+ default:
+ generic_panic();
+ break;
+ case ATMOSPHERE_TARGET_FIRMWARE_400:
+ case ATMOSPHERE_TARGET_FIRMWARE_500:
+ warmboot_src = (uint8_t *)0x4003B000;
+ break;
+ case ATMOSPHERE_TARGET_FIRMWARE_600:
+ case ATMOSPHERE_TARGET_FIRMWARE_620:
+ warmboot_src = (uint8_t *)0x4003D800;
+ break;
+ case ATMOSPHERE_TARGET_FIRMWARE_700:
+ warmboot_src = (uint8_t *)0x4003E000;
+ break;
+ }
+ uint8_t *warmboot_dst = (uint8_t *)0x8000D000;
+ const size_t warmboot_size = 0x2000;
+
+ /* Flush cache, to ensure warmboot is where we need it to be. */
+ flush_dcache_range(warmboot_src, warmboot_src + warmboot_size);
+ __dsb_sy();
+
+ /* Copy warmboot. */
+ for (size_t i = 0; i < warmboot_size; i += sizeof(uint32_t)) {
+ write32le(warmboot_dst, i, read32le(warmboot_src, i));
+ }
+
+ /* Flush cache, to ensure warmboot is where we need it to be. */
+ flush_dcache_range(warmboot_dst, warmboot_dst + warmboot_size);
+ __dsb_sy();
+}
+
static void sync_with_nx_bootloader(int state) {
- while (MAILBOX_NX_BOOTLOADER_SETUP_STATE < state) {
+ while (MAILBOX_NX_BOOTLOADER_SETUP_STATE(exosphere_get_target_firmware()) < state) {
wait(100);
}
}
-static void indentity_unmap_dram(void) {
+static void identity_unmap_dram(void) {
uintptr_t *mmu_l1_tbl = (uintptr_t *)(TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
mmu_unmap_range(1, mmu_l1_tbl, IDENTITY_GET_MAPPING_ADDRESS(IDENTITY_MAPPING_DRAM), IDENTITY_GET_MAPPING_SIZE(IDENTITY_MAPPING_DRAM));
@@ -404,16 +529,34 @@ uintptr_t get_pk2ldr_stack_address(void) {
void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
/* Load Exosphere-specific config. */
exosphere_load_config();
+ configitem_set_debugmode_override(exosphere_should_override_debugmode_user() != 0, exosphere_should_override_debugmode_priv() != 0);
/* Setup the Security Engine. */
setup_se();
/* Perform initial PMC register writes, if relevant. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
+ MAKE_REG32(PMC_BASE + 0x054) = 0x8000D000;
MAKE_REG32(PMC_BASE + 0x0A0) &= 0xFFF3FFFF;
MAKE_REG32(PMC_BASE + 0x818) &= 0xFFFFFFFE;
- MAKE_REG32(PMC_BASE + 0x334) |= 0x10;
- MAKE_REG32(PMC_BASE + 0x360) = 6;
+ MAKE_REG32(PMC_BASE + 0x334) |= 0x10;
+ switch (exosphere_get_target_firmware()) {
+ case ATMOSPHERE_TARGET_FIRMWARE_400:
+ MAKE_REG32(PMC_BASE + 0x360) = 0x105;
+ break;
+ case ATMOSPHERE_TARGET_FIRMWARE_500:
+ MAKE_REG32(PMC_BASE + 0x360) = 6;
+ break;
+ case ATMOSPHERE_TARGET_FIRMWARE_600:
+ MAKE_REG32(PMC_BASE + 0x360) = 0x87;
+ break;
+ case ATMOSPHERE_TARGET_FIRMWARE_620:
+ MAKE_REG32(PMC_BASE + 0x360) = 0xA8;
+ break;
+ case ATMOSPHERE_TARGET_FIRMWARE_700:
+ MAKE_REG32(PMC_BASE + 0x360) = 0x129;
+ break;
+ }
}
wait(1000);
@@ -423,15 +566,16 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
setup_current_core_state();
/* Save boot reason to global. */
- bootconfig_load_boot_reason((volatile boot_reason_t *)(MAILBOX_NX_BOOTLOADER_BOOT_REASON));
+ bootconfig_load_boot_reason((volatile boot_reason_t *)(MAILBOX_NX_BOOTLOADER_BOOT_REASON(exosphere_get_target_firmware())));
/* Initialize cache'd random bytes for kernel. */
randomcache_init();
/* memclear the initial copy of Exosphere running in IRAM (relocated to TZRAM by earlier code). */
- memset((void *)reloc_list->reloc_base, 0, reloc_list->loaded_bin_size);
+ /* memset((void *)reloc_list->reloc_base, 0, reloc_list->loaded_bin_size); */
+
/* Let NX Bootloader know that we're running. */
- MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 1;
+ MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE(exosphere_get_target_firmware()) = 1;
/* Wait for 1 second, to allow time for NX_BOOTLOADER to draw to the screen. This is useful for debugging. */
/* wait(1000000); */
@@ -443,7 +587,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
setup_boot_config();
/* Set sysctr0 registers based on bootconfig. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
uint64_t sysctr0_val = bootconfig_get_value_for_sysctr0();
MAKE_SYSCTR0_REG(0x8) = (uint32_t)((sysctr0_val >> 0) & 0xFFFFFFFFULL);
MAKE_SYSCTR0_REG(0xC) = (uint32_t)((sysctr0_val >> 32) & 0xFFFFFFFFULL);
@@ -451,9 +595,12 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
}
/* Synchronize with NX BOOTLOADER. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X);
- /* TODO: copy_warmboot_bin_to_dram(); */
+ copy_warmboot_bin_to_dram();
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
+ setup_dram_magic_numbers();
+ }
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_LOADED_PACKAGE2_4X);
} else {
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_LOADED_PACKAGE2);
@@ -461,7 +608,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
/* Make PMC (2.x+), MC (4.x+) registers secure-only */
secure_additional_devices();
-
+
/* Remove the identity mapping for iRAM-C+D & TZRAM */
/* For our crt0 to work, this doesn't actually unmap TZRAM */
identity_unmap_iram_cd_tzram();
@@ -499,10 +646,12 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
set_core_entrypoint_and_argument(0, DRAM_BASE_PHYSICAL + header.metadata.entrypoint, 0);
/* Remove the DRAM identity mapping. */
- indentity_unmap_dram();
+ if (0) {
+ identity_unmap_dram();
+ }
/* Synchronize with NX BOOTLOADER. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_FINISHED_4X);
setup_4x_mmio();
} else {
diff --git a/exosphere/src/package2.h b/exosphere/src/package2.h
index 156ab52c3..05212f20a 100644
--- a/exosphere/src/package2.h
+++ b/exosphere/src/package2.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_PACKAGE2_H
#define EXOSPHERE_PACKAGE2_H
@@ -5,18 +21,19 @@
#include "utils.h"
#include "bootconfig.h"
+#include "exocfg.h"
#include "memory_map.h"
/* Physaddr 0x40002EF8 */
-static inline uintptr_t get_nx_bootloader_mailbox_base(void) {
- return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_NXBOOTLOADER_MAILBOX);
+static inline uintptr_t get_nx_bootloader_mailbox_base(unsigned int targetfw) {
+ return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_NXBOOTLOADER_MAILBOX) + ((targetfw >= ATMOSPHERE_TARGET_FIRMWARE_700) ? (0x000ull) : (0xE00ull));
}
-#define MAILBOX_NX_BOOTLOADER_BASE (get_nx_bootloader_mailbox_base())
+#define MAILBOX_NX_BOOTLOADER_BASE(targetfw) (get_nx_bootloader_mailbox_base(targetfw))
-#define MAILBOX_NX_SECMON_BOOT_TIME MAKE_REG32(MAILBOX_NX_BOOTLOADER_BASE + 0xE08ull)
+#define MAILBOX_NX_SECMON_BOOT_TIME(targetfw) MAKE_REG32(MAILBOX_NX_BOOTLOADER_BASE(targetfw) + 0x08ull)
-#define MAILBOX_NX_BOOTLOADER_SETUP_STATE MAKE_REG32(MAILBOX_NX_BOOTLOADER_BASE + 0xEF8ull)
+#define MAILBOX_NX_BOOTLOADER_SETUP_STATE(targetfw) MAKE_REG32(MAILBOX_NX_BOOTLOADER_BASE(targetfw) + 0xF8ull)
#define NX_BOOTLOADER_STATE_INIT 0
#define NX_BOOTLOADER_STATE_MOVED_BOOTCONFIG 1
@@ -29,11 +46,12 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(void) {
#define NX_BOOTLOADER_STATE_FINISHED_4X 4
/* Physaddr 0x40002EFC */
-#define MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE MAKE_REG32(MAILBOX_NX_BOOTLOADER_BASE + 0xEFCULL)
+#define MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE(targetfw) MAKE_REG32(MAILBOX_NX_BOOTLOADER_BASE(targetfw) + 0xFCULL)
-#define MAILBOX_NX_BOOTLOADER_BOOT_REASON (MAILBOX_NX_BOOTLOADER_BASE + 0xE10ULL)
+#define MAILBOX_NX_BOOTLOADER_BOOT_REASON(targetfw) (MAILBOX_NX_BOOTLOADER_BASE(targetfw) + 0x10ULL)
#define NX_BOOTLOADER_BOOTCONFIG_POINTER ((void *)(0x4003D000ull))
+#define NX_BOOTLOADER_BOOTCONFIG_POINTER_6X ((void *)(0x4003F800ull))
#define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull))
@@ -49,14 +67,20 @@ static inline uintptr_t get_nx_bootloader_mailbox_base(void) {
#define PACKAGE2_MAXVER_300 0x4
#define PACKAGE2_MAXVER_302 0x5
#define PACKAGE2_MAXVER_400_410 0x6
-#define PACKAGE2_MAXVER_500_CURRENT 0x7
+#define PACKAGE2_MAXVER_500_510 0x7
+#define PACKAGE2_MAXVER_600_610 0x8
+#define PACKAGE2_MAXVER_620 0x9
+#define PACKAGE2_MAXVER_700_CURRENT 0xA
#define PACKAGE2_MINVER_100 0x3
#define PACKAGE2_MINVER_200 0x4
#define PACKAGE2_MINVER_300 0x5
#define PACKAGE2_MINVER_302 0x6
#define PACKAGE2_MINVER_400_410 0x7
-#define PACKAGE2_MINVER_500_CURRENT 0x8
+#define PACKAGE2_MINVER_500_510 0x8
+#define PACKAGE2_MINVER_600_610 0x9
+#define PACKAGE2_MINVER_620 0xA
+#define PACKAGE2_MINVER_700_CURRENT 0xB
typedef struct {
union {
diff --git a/exosphere/src/panic_color.h b/exosphere/src/panic_color.h
index a310b139b..84a8a8772 100644
--- a/exosphere/src/panic_color.h
+++ b/exosphere/src/panic_color.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_PANIC_COLOR_H
#define EXOSPHERE_PANIC_COLOR_H
diff --git a/exosphere/src/pmc.h b/exosphere/src/pmc.h
index 5b274a9bc..17fd63526 100644
--- a/exosphere/src/pmc.h
+++ b/exosphere/src/pmc.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_PMC_H
#define EXOSPHERE_PMC_H
diff --git a/exosphere/src/randomcache.c b/exosphere/src/randomcache.c
index 88dcbb4fc..d715782eb 100644
--- a/exosphere/src/randomcache.c
+++ b/exosphere/src/randomcache.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
diff --git a/exosphere/src/randomcache.h b/exosphere/src/randomcache.h
index 7d0ddc8d2..4a7b1e371 100644
--- a/exosphere/src/randomcache.h
+++ b/exosphere/src/randomcache.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_RANDOM_CACHE_H
#define EXOSPHERE_RANDOM_CACHE_H
diff --git a/exosphere/src/lp0.c b/exosphere/src/sc7.c
similarity index 58%
rename from exosphere/src/lp0.c
rename to exosphere/src/sc7.c
index 33041e9d9..a7908c6f6 100644
--- a/exosphere/src/lp0.c
+++ b/exosphere/src/sc7.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include
@@ -12,82 +28,23 @@
#include "flow.h"
#include "fuse.h"
#include "i2c.h"
-#include "lp0.h"
+#include "sc7.h"
#include "masterkey.h"
#include "pmc.h"
#include "se.h"
#include "smc_api.h"
#include "timers.h"
#include "misc.h"
+#include "uart.h"
#include "exocfg.h"
#define u8 uint8_t
#define u32 uint32_t
-#include "bpmpfw_bin.h"
+#include "sc7fw_bin.h"
#undef u8
#undef u32
-/* Save security engine, and go to sleep. */
-void save_se_and_power_down_cpu(void) {
- uint32_t tzram_cmac[0x4] = {0};
-
- uint8_t *tzram_encryption_dst = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_ENCRYPTED_TZRAM));
- uint8_t *tzram_encryption_src = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_CURRENT_TZRAM));
- uint8_t *tzram_store_address = (uint8_t *)(WARMBOOT_GET_RAM_SEGMENT_ADDRESS(WARMBOOT_RAM_SEGMENT_ID_TZRAM));
- clear_priv_smc_in_progress();
-
- /* Flush cache. */
- flush_dcache_all();
-
- /* Encrypt and save TZRAM into DRAM using a random aes-256 key. */
- se_generate_random_key(KEYSLOT_SWITCH_LP0TZRAMKEY, KEYSLOT_SWITCH_RNGKEY);
-
- 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);
-
- /* 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);
- flush_dcache_range(tzram_encryption_dst, tzram_encryption_dst + LP0_TZRAM_SAVE_SIZE);
-
- /* Copy encrypted TZRAM from IRAM to DRAM. */
- memcpy(tzram_store_address, tzram_encryption_dst, LP0_TZRAM_SAVE_SIZE);
- flush_dcache_range(tzram_store_address, tzram_store_address + LP0_TZRAM_SAVE_SIZE);
-
- /* Compute CMAC. */
- se_compute_aes_256_cmac(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_cmac, sizeof(tzram_cmac), tzram_encryption_src, LP0_TZRAM_SAVE_SIZE);
-
- /* Write CMAC, lock registers. */
- APBDEV_PMC_SECURE_SCRATCH112_0 = tzram_cmac[0];
- APBDEV_PMC_SECURE_SCRATCH113_0 = tzram_cmac[1];
- APBDEV_PMC_SECURE_SCRATCH114_0 = tzram_cmac[2];
- APBDEV_PMC_SECURE_SCRATCH115_0 = tzram_cmac[3];
- APBDEV_PMC_SEC_DISABLE8_0 = 0x550000;
-
- /* Save security engine state. */
- uint8_t *se_state_dst = (uint8_t *)(WARMBOOT_GET_RAM_SEGMENT_ADDRESS(WARMBOOT_RAM_SEGMENT_ID_SE_STATE));
- se_check_error_status_reg();
- se_set_in_context_save_mode(true);
- se_save_context(KEYSLOT_SWITCH_SRKGENKEY, KEYSLOT_SWITCH_RNGKEY, se_state_dst);
- flush_dcache_range(se_state_dst, se_state_dst + 0x840);
- APBDEV_PMC_SCRATCH43_0 = (uint32_t)(WARMBOOT_GET_RAM_SEGMENT_PA(WARMBOOT_RAM_SEGMENT_ID_SE_STATE));
- se_set_in_context_save_mode(false);
- se_check_error_status_reg();
-
- if (!configitem_is_retail()) {
- /* TODO: uart_log("OYASUMI"); */
- }
-
- finalize_powerdown();
-}
-
-uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argument) {
- /* Ensure SMC call is to enter deep sleep. */
- if ((power_state & 0x17FFF) != 0x1001B) {
- return 0xFFFFFFFD;
- }
-
- unsigned int current_core = get_core_id();
-
+static void configure_battery_hi_z_mode(void) {
clkrst_reboot(CARDEVICE_I2C1);
if (configitem_should_profile_battery() && !i2c_query_ti_charger_bit_7()) {
@@ -107,34 +64,39 @@ uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argumen
}
}
clkrst_disable(CARDEVICE_I2C1);
+}
- /* Enable LP0 Wake Event Detection. */
+static void enable_lp0_wake_events(void) {
wait(75);
APBDEV_PMC_CNTRL2_0 |= 0x200; /* Set WAKE_DET_EN. */
wait(75);
APBDEV_PM_0 = 0xFFFFFFFF; /* Set all wake events. */
APBDEV_PMC_WAKE2_STATUS_0 = 0xFFFFFFFF; /* Set all wake events. */
wait(75);
+}
+static void notify_pmic_shutdown(void) {
clkrst_reboot(CARDEVICE_I2C5);
if (fuse_get_bootrom_patch_version() >= 0x7F) {
i2c_send_pmic_cpu_shutdown_cmd();
}
+}
+static void mitigate_jamais_vu(void) {
/* Jamais Vu mitigation #1: Ensure all other cores are off. */
if (APBDEV_PMC_PWRGATE_STATUS_0 & 0xE00) {
generic_panic();
}
/* For debugging, make this check always pass. */
- if ((exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400 || (get_debug_authentication_status() & 3) == 3)) {
+ if ((exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400 || (get_debug_authentication_status() & 3) == 3)) {
FLOW_CTLR_HALT_COP_EVENTS_0 = 0x50000000;
} else {
FLOW_CTLR_HALT_COP_EVENTS_0 = 0x40000000;
}
/* Jamais Vu mitigation #2: Ensure the BPMP is halted. */
- if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400 || (get_debug_authentication_status() & 3) == 3) {
+ if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400 || (get_debug_authentication_status() & 3) == 3) {
/* BPMP should just be plainly halted, in debugging conditions. */
if (FLOW_CTLR_HALT_COP_EVENTS_0 != 0x50000000) {
generic_panic();
@@ -150,13 +112,14 @@ uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argumen
if ((CLK_RST_CONTROLLER_RST_DEVICES_H_0 & 0x4000004) != 0x4000004) {
generic_panic();
}
+}
- /* Signal to bootrom the next reset should be a warmboot. */
+static void configure_pmc_for_deep_powerdown(void) {
APBDEV_PMC_SCRATCH0_0 = 1;
APBDEV_PMC_DPD_ENABLE_0 |= 2;
+}
- /* Prepare to boot the BPMP running our deep sleep firmware. */
-
+static void setup_bpmp_sc7_firmware(void) {
/* Mark PMC registers as not secure-world only, so BPMP can access them. */
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 &= 0xFFFFDFFF;
@@ -169,31 +132,173 @@ uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argumen
BPMP_VECTOR_UNK = 0x40003004; /* Reboot. */
BPMP_VECTOR_IRQ = 0x40003004; /* Reboot. */
BPMP_VECTOR_FIQ = 0x40003004; /* Reboot. */
-
+
/* Hold the BPMP in reset. */
MAKE_CAR_REG(0x300) = 2;
/* Copy BPMP firmware. */
uint8_t *lp0_entry_code = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_LP0_ENTRY_CODE));
- memcpy(lp0_entry_code, bpmpfw_bin, bpmpfw_bin_size);
- flush_dcache_range(lp0_entry_code, lp0_entry_code + bpmpfw_bin_size);
+ for (unsigned int i = 0; i < sc7fw_bin_size; i += 4) {
+ write32le(lp0_entry_code, i, read32le(sc7fw_bin, i));
+ }
+
+ flush_dcache_range(lp0_entry_code, lp0_entry_code + sc7fw_bin_size);
/* Take the BPMP out of reset. */
MAKE_CAR_REG(0x304) = 2;
/* Start executing BPMP firmware. */
FLOW_CTLR_HALT_COP_EVENTS_0 = 0;
- /* Prepare the current core for sleep. */
+}
+
+static void configure_flow_regs_for_sleep(void) {
+ unsigned int current_core = get_core_id();
flow_set_cc4_ctrl(current_core, 0);
flow_set_halt_events(current_core, false);
FLOW_CTLR_L2FLUSH_CONTROL_0 = 0;
flow_set_csr(current_core, 2);
+}
+static void save_tzram_state(void) {
+ /* TODO: Remove set suspend call once exo warmboots fully */
+ set_suspend_for_debug();
+ uint32_t tzram_cmac[0x4] = {0};
+
+ uint8_t *tzram_encryption_dst = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_ENCRYPTED_TZRAM));
+ uint8_t *tzram_encryption_src = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_CURRENT_TZRAM));
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
+ tzram_encryption_src += 0x2000ull;
+ }
+ uint8_t *tzram_store_address = (uint8_t *)(WARMBOOT_GET_RAM_SEGMENT_ADDRESS(WARMBOOT_RAM_SEGMENT_ID_TZRAM));
+ clear_priv_smc_in_progress();
+
+ /* Flush cache. */
+ flush_dcache_all();
+
+ /* Encrypt and save TZRAM into DRAM using a random aes-256 key. */
+ se_generate_random_key(KEYSLOT_SWITCH_LP0TZRAMKEY, KEYSLOT_SWITCH_RNGKEY);
+
+ 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);
+
+ /* 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);
+ flush_dcache_range(tzram_encryption_dst, tzram_encryption_dst + LP0_TZRAM_SAVE_SIZE);
+
+ /* Copy encrypted TZRAM from IRAM to DRAM. */
+ for (unsigned int i = 0; i < LP0_TZRAM_SAVE_SIZE; i += 4) {
+ write32le(tzram_store_address, i, read32le(tzram_encryption_dst, i));
+ }
+
+ flush_dcache_range(tzram_store_address, tzram_store_address + LP0_TZRAM_SAVE_SIZE);
+
+ /* Compute CMAC. */
+ se_compute_aes_256_cmac(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_cmac, sizeof(tzram_cmac), tzram_encryption_src, LP0_TZRAM_SAVE_SIZE);
+
+ /* Write CMAC, lock registers. */
+ APBDEV_PMC_SECURE_SCRATCH112_0 = tzram_cmac[0];
+ APBDEV_PMC_SECURE_SCRATCH113_0 = tzram_cmac[1];
+ APBDEV_PMC_SECURE_SCRATCH114_0 = tzram_cmac[2];
+ APBDEV_PMC_SECURE_SCRATCH115_0 = tzram_cmac[3];
+ APBDEV_PMC_SEC_DISABLE8_0 = 0x550000;
+
+ /* Perform pre-2.0.0 PMC writes. */
+ if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_200) {
+ /* TODO: Give these writes appropriate defines in pmc.h */
+
+ /* Save Encrypted context location + lock scratch register. */
+ MAKE_REG32(PMC_BASE + 0x360) = WARMBOOT_GET_RAM_SEGMENT_PA(WARMBOOT_RAM_SEGMENT_ID_TZRAM);
+ MAKE_REG32(PMC_BASE + 0x2D8) = 0x10000;
+
+ /* Save Encryption parameters (where to copy TZRAM to, source, destination, size) */
+ MAKE_REG32(PMC_BASE + 0x340) = LP0_ENTRY_GET_RAM_SEGMENT_PA(LP0_ENTRY_RAM_SEGMENT_ID_CURRENT_TZRAM);
+ MAKE_REG32(PMC_BASE + 0x344) = 0;
+ MAKE_REG32(PMC_BASE + 0x348) = LP0_ENTRY_GET_RAM_SEGMENT_PA(LP0_ENTRY_RAM_SEGMENT_ID_CURRENT_TZRAM);
+ MAKE_REG32(PMC_BASE + 0x34C) = 0;
+ MAKE_REG32(PMC_BASE + 0x350) = LP0_ENTRY_GET_RAM_SEGMENT_PA(LP0_ENTRY_RAM_SEGMENT_ID_CURRENT_TZRAM);
+ MAKE_REG32(PMC_BASE + 0x354) = LP0_TZRAM_SAVE_SIZE;
+
+ /* Lock scratch registers. */
+ MAKE_REG32(PMC_BASE + 0x2D8) = 0x555;
+ }
+}
+
+static void save_se_state(void) {
+ /* Save security engine state. */
+ uint8_t *se_state_dst = (uint8_t *)(WARMBOOT_GET_RAM_SEGMENT_ADDRESS(WARMBOOT_RAM_SEGMENT_ID_SE_STATE));
+ se_check_error_status_reg();
+ se_set_in_context_save_mode(true);
+ se_save_context(KEYSLOT_SWITCH_SRKGENKEY, KEYSLOT_SWITCH_RNGKEY, se_state_dst);
+ flush_dcache_range(se_state_dst, se_state_dst + 0x840);
+ APBDEV_PMC_SCRATCH43_0 = (uint32_t)(WARMBOOT_GET_RAM_SEGMENT_PA(WARMBOOT_RAM_SEGMENT_ID_SE_STATE));
+ se_set_in_context_save_mode(false);
+ se_check_error_status_reg();
+}
+
+/* Save security engine, and go to sleep. */
+void save_se_and_power_down_cpu(void) {
+ /* Save context for warmboot to restore. */
+ save_tzram_state();
+ save_se_state();
+
+ /* Patch the bootrom to disable warmboot signature checks. */
+ MAKE_REG32(PMC_BASE + 0x118) = 0x2202E012;
+ MAKE_REG32(PMC_BASE + 0x11C) = 0x6001DC28;
+
+ if (!configitem_is_retail()) {
+ uart_send(UART_A, "OYASUMI", 8);
+ }
+
+ finalize_powerdown();
+}
+
+uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argument) {
+ /* TODO: 6.0.0 introduces heavy deja vu mitigations. */
+ /* Exosphere may want to implement these. */
+
+ /* Ensure SMC call is to enter deep sleep. */
+ if ((power_state & 0x17FFF) != 0x1001B) {
+ return 0xFFFFFFFD;
+ }
+
+ /* Perform I2C comms with TI charger if required. */
+ configure_battery_hi_z_mode();
+
+ /* Enable LP0 Wake Event Detection. */
+ enable_lp0_wake_events();
+
+ /* Alert the PMC of an iminent shutdown. */
+ notify_pmic_shutdown();
+
+ /* Validate that the shutdown has correct context. */
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
+ mitigate_jamais_vu();
+ }
+
+ /* Signal to bootrom the next reset should be a warmboot. */
+ configure_pmc_for_deep_powerdown();
+
+ /* Ensure that BPMP SC7 firmware is active. */
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
+ setup_bpmp_sc7_firmware();
+ }
+
+ /* Prepare the current core for sleep. */
+ configure_flow_regs_for_sleep();
+
/* Save core context. */
- set_core_entrypoint_and_argument(current_core, entrypoint, argument);
+ set_core_entrypoint_and_argument(get_core_id(), entrypoint, argument);
save_current_core_context();
set_current_core_inactive();
- call_with_stack_pointer(get_smc_core012_stack_address(), save_se_and_power_down_cpu);
+
+ /* Ensure that other cores are already asleep. */
+ if (!(APBDEV_PMC_PWRGATE_STATUS_0 & 0xE00)) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_200) {
+ call_with_stack_pointer(get_smc_core012_stack_address(), save_se_and_power_down_cpu);
+ } else {
+ save_se_and_power_down_cpu();
+ }
+ }
generic_panic();
}
diff --git a/exosphere/src/sc7.h b/exosphere/src/sc7.h
new file mode 100644
index 000000000..c5612da92
--- /dev/null
+++ b/exosphere/src/sc7.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_SC7_H
+#define EXOSPHERE_SC7_H
+
+#include
+
+/* Exosphere Deep Sleep Entry implementation. */
+
+#define LP0_TZRAM_SAVE_SIZE 0xE000
+
+uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argument);
+
+#endif
\ No newline at end of file
diff --git a/exosphere/src/se.c b/exosphere/src/se.c
index fe92958c6..80cc350ec 100644
--- a/exosphere/src/se.c
+++ b/exosphere/src/se.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "utils.h"
@@ -20,9 +36,8 @@ static unsigned int g_se_exp_sizes[KEYSLOT_RSA_MAX];
static bool g_se_generated_vector = false;
static uint8_t g_se_stored_test_vector[0x10];
-
/* Initialize a SE linked list. */
-void ll_init(se_ll_t *ll, void *buffer, size_t size) {
+void ll_init(volatile se_ll_t *ll, void *buffer, size_t size) {
ll->num_entries = 0; /* 1 Entry. */
if (buffer != NULL) {
@@ -46,7 +61,7 @@ void set_security_engine_callback(unsigned int (*callback)(void)) {
/* Fires on Security Engine operation completion. */
void se_operation_completed(void) {
- SECURITY_ENGINE->INT_ENABLE_REG = 0;
+ se_get_regs()->INT_ENABLE_REG = 0;
if (g_se_callback != NULL) {
g_se_callback();
g_se_callback = NULL;
@@ -54,13 +69,14 @@ void se_operation_completed(void) {
}
void se_check_error_status_reg(void) {
- if (SECURITY_ENGINE->ERR_STATUS_REG) {
+ if (se_get_regs()->ERR_STATUS_REG) {
generic_panic();
}
}
void se_check_for_error(void) {
- if (SECURITY_ENGINE->INT_STATUS_REG & 0x10000 || SECURITY_ENGINE->FLAGS_REG & 3 || SECURITY_ENGINE->ERR_STATUS_REG) {
+ volatile tegra_se_t *se = se_get_regs();
+ if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) {
generic_panic();
}
}
@@ -70,12 +86,11 @@ void se_trigger_interrupt(void) {
}
void se_verify_flags_cleared(void) {
- if (SECURITY_ENGINE->FLAGS_REG & 3) {
+ if (se_get_regs()->FLAGS_REG & 3) {
generic_panic();
}
}
-
void se_generate_test_vector(void *vector) {
/* TODO: Implement real test vector generation. */
memset(vector, 0, 0x10);
@@ -106,23 +121,27 @@ void se_generate_stored_vector(void) {
/* Set the flags for an AES keyslot. */
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
/* Misc flags. */
if (flags & ~0x80) {
- SECURITY_ENGINE->AES_KEYSLOT_FLAGS[keyslot] = ~flags;
+ se->AES_KEYSLOT_FLAGS[keyslot] = ~flags;
}
/* Disable keyslot reads. */
if (flags & 0x80) {
- SECURITY_ENGINE->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
+ se->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
}
}
/* Set the flags for an RSA keyslot. */
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_RSA_MAX) {
generic_panic();
}
@@ -130,28 +149,32 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
/* Misc flags. */
if (flags & ~0x80) {
/* TODO: Why are flags assigned this way? */
- SECURITY_ENGINE->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
+ se->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
}
/* Disable keyslot reads. */
if (flags & 0x80) {
- SECURITY_ENGINE->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
+ se->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
}
}
void clear_aes_keyslot(unsigned int keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
/* Zero out the whole keyslot and IV. */
for (unsigned int i = 0; i < 0x10; i++) {
- SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
- SECURITY_ENGINE->AES_KEYTABLE_DATA = 0;
+ se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
+ se->AES_KEYTABLE_DATA = 0;
}
}
void clear_rsa_keyslot(unsigned int keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_RSA_MAX) {
generic_panic();
}
@@ -159,40 +182,44 @@ void clear_rsa_keyslot(unsigned int keyslot) {
/* Zero out the whole keyslot. */
for (unsigned int i = 0; i < 0x40; i++) {
/* Select Keyslot Modulus[i] */
- SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
- SECURITY_ENGINE->RSA_KEYTABLE_DATA = 0;
+ se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
+ se->RSA_KEYTABLE_DATA = 0;
}
for (unsigned int i = 0; i < 0x40; i++) {
/* Select Keyslot Expontent[i] */
- SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
- SECURITY_ENGINE->RSA_KEYTABLE_DATA = 0;
+ se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
+ se->RSA_KEYTABLE_DATA = 0;
}
}
void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) {
generic_panic();
}
for (size_t i = 0; i < (key_size >> 2); i++) {
- SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
- SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(key, 4 * i);
+ se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
+ se->AES_KEYTABLE_DATA = read32le(key, 4 * i);
}
}
void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) {
generic_panic();
}
for (size_t i = 0; i < (modulus_size >> 2); i++) {
- SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i;
- SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4);
+ se->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i;
+ se->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4);
}
for (size_t i = 0; i < (exp_size >> 2); i++) {
- SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
- SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4);
+ se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
+ se->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4);
}
g_se_modulus_sizes[keyslot] = modulus_size;
@@ -200,48 +227,56 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_
}
void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) {
generic_panic();
}
for (size_t i = 0; i < (iv_size >> 2); i++) {
- SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
- SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(iv, 4 * i);
+ se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
+ se->AES_KEYTABLE_DATA = read32le(iv, 4 * i);
}
}
void clear_aes_keyslot_iv(unsigned int keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
for (size_t i = 0; i < (0x10 >> 2); i++) {
- SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
- SECURITY_ENGINE->AES_KEYTABLE_DATA = 0;
+ se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
+ se->AES_KEYTABLE_DATA = 0;
}
}
void set_se_ctr(const void *ctr) {
for (unsigned int i = 0; i < 4; i++) {
- SECURITY_ENGINE->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4);
+ se_get_regs()->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4);
}
}
void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSIZE_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) {
generic_panic();
}
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB);
- SECURITY_ENGINE->CRYPTO_REG = keyslot_src << 24;
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
- SECURITY_ENGINE->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8;
+ se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB);
+ se->CRYPTO_REG = keyslot_src << 24;
+ se->BLOCK_COUNT_REG = 0;
+ se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8;
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);
}
void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, unsigned int crypt_config, bool encrypt, unsigned int (*callback)(void)) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
@@ -252,34 +287,34 @@ void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr,
/* Setup Config register. */
if (encrypt) {
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
+ se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
} else {
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
+ se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
}
/* Setup Crypto register. */
- SECURITY_ENGINE->CRYPTO_REG = crypt_config | (keyslot << 24) | (encrypt << 8);
+ se->CRYPTO_REG = crypt_config | (keyslot << 24) | (encrypt << 8);
/* Mark this encryption as insecure -- this makes the SE not a secure busmaster. */
- SECURITY_ENGINE->CRYPTO_REG |= 0x80000000;
+ se->CRYPTO_REG |= 0x80000000;
/* Appropriate number of blocks. */
- SECURITY_ENGINE->BLOCK_COUNT_REG = (size >> 4) - 1;
+ se->BLOCK_COUNT_REG = (size >> 4) - 1;
/* Set the callback, for after the async operation. */
set_security_engine_callback(callback);
/* Enable SE Interrupt firing for async op. */
- SECURITY_ENGINE->INT_ENABLE_REG = 0x10;
+ se->INT_ENABLE_REG = 0x10;
/* Setup Input/Output lists */
- SECURITY_ENGINE->IN_LL_ADDR_REG = in_ll_paddr;
- SECURITY_ENGINE->OUT_LL_ADDR_REG = out_ll_paddr;
+ se->IN_LL_ADDR_REG = in_ll_paddr;
+ se->OUT_LL_ADDR_REG = out_ll_paddr;
/* Set registers for operation. */
- SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG;
- SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG;
- SECURITY_ENGINE->OPERATION_REG = 1;
+ se->ERR_STATUS_REG = se->ERR_STATUS_REG;
+ se->INT_STATUS_REG = se->INT_STATUS_REG;
+ se->OPERATION_REG = 1;
/* Ensure writes go through. */
__dsb_ish();
@@ -287,7 +322,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)) {
/* Unknown what this write does, but official code writes it for CTR mode. */
- SECURITY_ENGINE->_0x80C = 1;
+ se_get_regs()->SPARE_0 = 1;
set_se_ctr(ctr);
se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x81E, true, callback);
}
@@ -302,8 +337,8 @@ void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, ui
se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x66, false, callback);
}
-
void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*callback)(void)) {
+ volatile tegra_se_t *se = se_get_regs();
uint8_t stack_buf[KEYSIZE_RSA_MAX];
if (keyslot >= KEYSLOT_RSA_MAX || size > KEYSIZE_RSA_MAX) {
@@ -315,24 +350,24 @@ void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*cal
stack_buf[i] = *((uint8_t *)buf + size - i - 1);
}
-
- SECURITY_ENGINE->CONFIG_REG = (ALG_RSA | DST_RSAREG);
- SECURITY_ENGINE->RSA_CONFIG = keyslot << 24;
- SECURITY_ENGINE->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
- SECURITY_ENGINE->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
+ se->CONFIG_REG = (ALG_RSA | DST_RSAREG);
+ se->RSA_CONFIG = keyslot << 24;
+ se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
+ se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
set_security_engine_callback(callback);
/* Enable SE Interrupt firing for async op. */
- SECURITY_ENGINE->INT_ENABLE_REG = 0x10;
+ se->INT_ENABLE_REG = 0x10;
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
trigger_se_rsa_op(stack_buf, size);
- while (!(SECURITY_ENGINE->INT_STATUS_REG & 2)) { /* Wait a while */ }
+ while (!(se->INT_STATUS_REG & 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) {
+ volatile tegra_se_t *se = se_get_regs();
uint8_t stack_buf[KEYSIZE_RSA_MAX];
if (keyslot >= KEYSLOT_RSA_MAX || src_size > KEYSIZE_RSA_MAX || dst_size > KEYSIZE_RSA_MAX) {
@@ -344,11 +379,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);
}
- SECURITY_ENGINE->CONFIG_REG = (ALG_RSA | DST_RSAREG);
- SECURITY_ENGINE->RSA_CONFIG = keyslot << 24;
- SECURITY_ENGINE->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
- SECURITY_ENGINE->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
-
+ se->CONFIG_REG = (ALG_RSA | DST_RSAREG);
+ se->RSA_CONFIG = keyslot << 24;
+ se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
+ se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size);
@@ -366,7 +400,7 @@ void se_get_exp_mod_output(void *buf, size_t size) {
/* Copy endian swapped output. */
while (num_dwords) {
- *p_out = read32be(SECURITY_ENGINE->RSA_OUTPUT, offset);
+ *p_out = read32be(se_get_regs()->RSA_OUTPUT, offset);
offset += 4;
p_out--;
num_dwords--;
@@ -431,22 +465,25 @@ bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const v
void trigger_se_rsa_op(void *buf, size_t size) {
+ volatile tegra_se_t *se = se_get_regs();
se_ll_t in_ll;
+
ll_init(&in_ll, (void *)buf, size);
/* Set the input LL. */
- SECURITY_ENGINE->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll);
+ se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll);
/* Set registers for operation. */
- SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG;
- SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG;
- SECURITY_ENGINE->OPERATION_REG = 1;
+ se->ERR_STATUS_REG = se->ERR_STATUS_REG;
+ se->INT_STATUS_REG = se->INT_STATUS_REG;
+ se->OPERATION_REG = 1;
/* Ensure writes go through. */
__dsb_ish();
}
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size) {
+ volatile tegra_se_t *se = se_get_regs();
se_ll_t in_ll;
se_ll_t out_ll;
@@ -456,20 +493,19 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v
__dsb_sy();
/* Set the LLs. */
- SECURITY_ENGINE->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll);
- SECURITY_ENGINE->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll);
+ se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll);
+ se->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll);
/* Set registers for operation. */
- SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG;
- SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG;
- SECURITY_ENGINE->OPERATION_REG = op;
+ se->ERR_STATUS_REG = se->ERR_STATUS_REG;
+ se->INT_STATUS_REG = se->INT_STATUS_REG;
+ se->OPERATION_REG = op;
- while (!(SECURITY_ENGINE->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
+ while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
se_check_for_error();
}
-
/* Secure AES Functionality. */
void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, size_t src_size) {
uint8_t block[0x10] = {0};
@@ -485,7 +521,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src,
flush_dcache_range(block, block + sizeof(block));
/* Trigger AES operation. */
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se_get_regs()->BLOCK_COUNT_REG = 0;
trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
/* Copy output data into dst. */
@@ -496,6 +532,8 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src,
}
void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) {
generic_panic();
}
@@ -510,15 +548,15 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo
unsigned int num_blocks = src_size >> 4;
/* Unknown what this write does, but official code writes it for CTR mode. */
- SECURITY_ENGINE->_0x80C = 1;
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
- SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x91E;
+ se->SPARE_0 = 1;
+ se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
+ se->CRYPTO_REG = (keyslot << 24) | 0x91E;
set_se_ctr(ctr);
/* Handle any aligned blocks. */
size_t aligned_size = (size_t)num_blocks << 4;
if (aligned_size) {
- SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1;
+ se->BLOCK_COUNT_REG = num_blocks - 1;
trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size);
}
@@ -537,13 +575,15 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo
}
void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
generic_panic();
}
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
- SECURITY_ENGINE->CRYPTO_REG = keyslot << 24 | 0x100;
+ se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
+ se->CRYPTO_REG = keyslot << 24 | 0x100;
flush_dcache_range((uint8_t *)src, (uint8_t *)src + 0x10);
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + 0x10);
@@ -560,12 +600,14 @@ void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_si
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
generic_panic();
}
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
- SECURITY_ENGINE->CRYPTO_REG = keyslot << 24;
+ se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
+ se->CRYPTO_REG = keyslot << 24;
flush_dcache_range((uint8_t *)src, (uint8_t *)src + 0x10);
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
flush_dcache_range((uint8_t *)dst, (uint8_t *)dst + 0x10);
@@ -584,6 +626,8 @@ void shift_left_xor_rb(uint8_t *key) {
}
void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
@@ -600,17 +644,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
shift_left_xor_rb(derived_key);
}
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
- SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | (0x145);
+ se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
+ se->CRYPTO_REG = (keyslot << 24) | (0x145);
clear_aes_keyslot_iv(keyslot);
-
unsigned int num_blocks = (data_size + 0xF) >> 4;
/* Handle aligned blocks. */
if (num_blocks > 1) {
- SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 2;
+ se->BLOCK_COUNT_REG = num_blocks - 2;
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
- SECURITY_ENGINE->CRYPTO_REG |= 0x80;
+ se->CRYPTO_REG |= 0x80;
}
/* Create final block. */
@@ -627,13 +670,13 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
}
/* Perform last operation. */
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->BLOCK_COUNT_REG = 0;
flush_dcache_range(last_block, last_block + sizeof(last_block));
trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
/* Copy output CMAC. */
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
- ((uint32_t *)cmac)[i] = read32le(SECURITY_ENGINE->HASH_RESULT_REG, i << 2);
+ ((uint32_t *)cmac)[i] = read32le(se->HASH_RESULT_REG, i << 2);
}
}
@@ -645,42 +688,48 @@ void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size,
}
void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) {
generic_panic();
}
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16);
- SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x144;
+ se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16);
+ se->CRYPTO_REG = (keyslot << 24) | 0x144;
set_aes_keyslot_iv(keyslot, iv, 0x10);
- SECURITY_ENGINE->BLOCK_COUNT_REG = (src_size >> 4) - 1;
+ se->BLOCK_COUNT_REG = (src_size >> 4) - 1;
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
}
/* SHA256 Implementation. */
void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
/* Setup config for SHA256, size = BITS(src_size) */
- SECURITY_ENGINE->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
- SECURITY_ENGINE->SHA_CONFIG_REG = 1;
- SECURITY_ENGINE->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3);
- SECURITY_ENGINE->_0x208 = 0;
- SECURITY_ENGINE->_0x20C = 0;
- SECURITY_ENGINE->_0x210 = 0;
- SECURITY_ENGINE->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3);
- SECURITY_ENGINE->_0x218 = 0;
- SECURITY_ENGINE->_0x21C = 0;
- SECURITY_ENGINE->_0x220 = 0;
+ se->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
+ se->SHA_CONFIG_REG = 1;
+ se->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3);
+ se->_0x208 = 0;
+ se->_0x20C = 0;
+ se->_0x210 = 0;
+ se->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3);
+ se->_0x218 = 0;
+ se->_0x21C = 0;
+ se->_0x220 = 0;
/* Trigger the operation. */
trigger_se_blocking_op(OP_START, NULL, 0, src, src_size);
/* Copy output hash. */
for (unsigned int i = 0; i < (0x20 >> 2); i++) {
- ((uint32_t *)dst)[i] = read32be(SECURITY_ENGINE->HASH_RESULT_REG, i << 2);
+ ((uint32_t *)dst)[i] = read32be(se->HASH_RESULT_REG, i << 2);
}
}
/* RNG API */
void se_initialize_rng(unsigned int keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
@@ -689,74 +738,80 @@ void se_initialize_rng(unsigned int keyslot) {
/* This will be discarded, when done. */
uint8_t output_buf[0x10];
- SECURITY_ENGINE->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */
- SECURITY_ENGINE->RNG_RESEED_INTERVAL_REG = 70001;
- SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY);
- SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x108;
- SECURITY_ENGINE->RNG_CONFIG_REG = 5;
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */
+ se->RNG_RESEED_INTERVAL_REG = 70001;
+ se->CONFIG_REG = (ALG_RNG | DST_MEMORY);
+ se->CRYPTO_REG = (keyslot << 24) | 0x108;
+ se->RNG_CONFIG_REG = 5;
+ se->BLOCK_COUNT_REG = 0;
trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0);
}
void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
uint32_t num_blocks = size >> 4;
size_t aligned_size = num_blocks << 4;
- SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY);
- SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x108;
- SECURITY_ENGINE->RNG_CONFIG_REG = 4;
+ se->CONFIG_REG = (ALG_RNG | DST_MEMORY);
+ se->CRYPTO_REG = (keyslot << 24) | 0x108;
+ se->RNG_CONFIG_REG = 4;
if (num_blocks >= 1) {
- SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1;
+ se->BLOCK_COUNT_REG = num_blocks - 1;
trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0);
}
if (size > aligned_size) {
se_perform_aes_block_operation(dst + aligned_size, size - aligned_size, NULL, 0);
}
-
}
-
/* SE context save API. */
void se_set_in_context_save_mode(bool is_context_save_mode) {
- uint32_t val = SECURITY_ENGINE->_0x0;
+ volatile tegra_se_t *se = se_get_regs();
+
+ uint32_t val = se->_0x0;
if (is_context_save_mode) {
val |= 0x10000;
} else {
val &= 0xFFFEFFFF;
}
- SECURITY_ENGINE->_0x0 = val;
+ se->_0x0 = val;
/* Perform a useless read from flags reg. */
- (void)(SECURITY_ENGINE->FLAGS_REG);
+ (void)(se->FLAGS_REG);
}
void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (dst_keyslot >= KEYSLOT_AES_MAX || rng_keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
/* Setup Config. */
- SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_KEYTAB);
- SECURITY_ENGINE->CRYPTO_REG = (rng_keyslot << 24) | 0x108;
- SECURITY_ENGINE->RNG_CONFIG_REG = 4;
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->CONFIG_REG = (ALG_RNG | DST_KEYTAB);
+ se->CRYPTO_REG = (rng_keyslot << 24) | 0x108;
+ se->RNG_CONFIG_REG = 4;
+ se->BLOCK_COUNT_REG = 0;
/* Generate low part of key. */
- SECURITY_ENGINE->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8);
+ se->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8);
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
/* Generate high part of key. */
- SECURITY_ENGINE->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8) | 1;
+ se->CRYPTO_KEYTABLE_DST_REG = (dst_keyslot << 8) | 1;
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
}
void se_generate_srk(unsigned int srkgen_keyslot) {
- SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_SRK);
- SECURITY_ENGINE->CRYPTO_REG = (srkgen_keyslot << 24) | 0x108;
- SECURITY_ENGINE->RNG_CONFIG_REG = 6;
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ volatile tegra_se_t *se = se_get_regs();
+
+ se->CONFIG_REG = (ALG_RNG | DST_SRK);
+ se->CRYPTO_REG = (srkgen_keyslot << 24) | 0x108;
+ se->RNG_CONFIG_REG = 6;
+ se->BLOCK_COUNT_REG = 0;
trigger_se_blocking_op(OP_START, NULL, 0, NULL, 0);
}
@@ -780,6 +835,7 @@ void se_encrypt_with_srk(void *dst, size_t dst_size, const void *src, size_t src
}
void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void *dst) {
+ volatile tegra_se_t *se = se_get_regs();
uint8_t _work_buf[0x80];
uint8_t *work_buf = (uint8_t *)(((uintptr_t)_work_buf + 0x7F) & ~0x3F);
@@ -792,39 +848,39 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void
flush_dcache_range(work_buf, work_buf + 0x10);
/* Save random initial block. */
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
- SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM);
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
+ se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM);
+ se->BLOCK_COUNT_REG = 0;
se_encrypt_with_srk(dst, 0x10, work_buf, 0x10);
/* Save Sticky Bits. */
for (unsigned int i = 0; i < 0x2; i++) {
- SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT);
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_STICKY_BITS) | (i << CTX_SAVE_STICKY_BIT_INDEX_SHIFT);
+ se->BLOCK_COUNT_REG = 0;
se_encrypt_with_srk(dst + 0x10 + (i * 0x10), 0x10, NULL, 0);
}
/* Save AES Key Table. */
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
- SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS);
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS);
+ se->BLOCK_COUNT_REG = 0;
se_encrypt_with_srk(dst + 0x30 + (i * 0x20), 0x10, NULL, 0);
- SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_HIGH_BITS);
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_HIGH_BITS);
+ se->BLOCK_COUNT_REG = 0;
se_encrypt_with_srk(dst + 0x40 + (i * 0x20), 0x10, NULL, 0);
}
/* Save AES Original IVs. */
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
- SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV);
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_ORIGINAL_IV);
+ se->BLOCK_COUNT_REG = 0;
se_encrypt_with_srk(dst + 0x230 + (i * 0x10), 0x10, NULL, 0);
}
/* Save AES Updated IVs */
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
- SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV);
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (i << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_UPDATED_IV);
+ se->BLOCK_COUNT_REG = 0;
se_encrypt_with_srk(dst + 0x330 + (i * 0x10), 0x10, NULL, 0);
}
@@ -833,8 +889,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 mod_exp = 0; mod_exp < 2; mod_exp++) {
for (unsigned int sub_block = 0; sub_block < 0x10; sub_block++) {
- SECURITY_ENGINE->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);
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ 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->BLOCK_COUNT_REG = 0;
se_encrypt_with_srk(rsa_ctx_out, 0x10, NULL, 0);
rsa_ctx_out += 0x10;
}
@@ -843,14 +899,14 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void
/* 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};
- SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM);
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM);
+ se->BLOCK_COUNT_REG = 0;
se_encrypt_with_srk(dst + 0x830, 0x10, context_save_known_pattern, 0x10);
/* Save SRK into PMC registers. */
- SECURITY_ENGINE->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_SRK);
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_SRK);
+ se->BLOCK_COUNT_REG = 0;
se_encrypt_with_srk(work_buf, 0, NULL, 0);
- SECURITY_ENGINE->CONFIG_REG = 0;
+ se->CONFIG_REG = 0;
se_encrypt_with_srk(work_buf, 0, NULL, 0);
}
diff --git a/exosphere/src/se.h b/exosphere/src/se.h
index 5fd606a2b..61c8973fa 100644
--- a/exosphere/src/se.h
+++ b/exosphere/src/se.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_SE_H
#define EXOSPHERE_SE_H
@@ -27,6 +43,11 @@
/* This keyslot was added in 5.0.0. */
#define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA
+/* This keyslot was added in 6.00. */
+#define KEYSLOT_SWITCH_6XTSECKEY 0xC
+#define KEYSLOT_SWITCH_6XTSECROOTKEY 0xD
+#define KEYSLOT_SWITCH_6XSBK 0xE
+
#define KEYSLOT_AES_MAX 0x10
#define KEYSLOT_RSA_MAX 0x2
@@ -81,7 +102,7 @@
#define RSA_2048_BYTES 0x100
-typedef struct security_engine {
+typedef struct {
uint32_t _0x0;
uint32_t _0x4;
uint32_t OPERATION_REG;
@@ -141,15 +162,13 @@ typedef struct security_engine {
uint32_t FLAGS_REG;
uint32_t ERR_STATUS_REG;
uint32_t _0x808;
- uint32_t _0x80C;
+ uint32_t SPARE_0;
uint32_t _0x810;
uint32_t _0x814;
uint32_t _0x818;
uint32_t _0x81C;
uint8_t _0x820[0x17E0];
-} security_engine_t;
-
-static_assert(sizeof(security_engine_t) == 0x2000, "Mis-defined Security Engine Registers!");
+} tegra_se_t;
typedef struct {
uint32_t address;
@@ -161,15 +180,10 @@ typedef struct {
se_addr_info_t addr_info; /* This should really be an array...but for our use case it works. */
} se_ll_t;
-
-/* WIP, API subject to change. */
-
-static inline volatile security_engine_t *get_security_engine(void) {
- return (volatile security_engine_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_SE));
+static inline volatile tegra_se_t *se_get_regs(void) {
+ return (volatile tegra_se_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_SE));
}
-#define SECURITY_ENGINE (get_security_engine())
-
/* This function MUST be registered to fire on the appropriate interrupt. */
void se_operation_completed(void);
@@ -193,7 +207,6 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_s
void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size);
void set_se_ctr(const void *ctr);
-
/* Insecure AES API */
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_cbc_encrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void));
diff --git a/exosphere/src/sealedkeys.c b/exosphere/src/sealedkeys.c
index 73a88bcc6..0d6e9ad48 100644
--- a/exosphere/src/sealedkeys.c
+++ b/exosphere/src/sealedkeys.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
@@ -17,11 +33,11 @@ static const uint8_t g_seal_key_sources[CRYPTOUSECASE_MAX_5X][0x10] = {
{0x0E, 0xE0, 0xC4, 0x33, 0x82, 0x66, 0xE8, 0x08, 0x39, 0x13, 0x41, 0x7D, 0x04, 0x64, 0x2B, 0x6D},
{0xE1, 0xA8, 0xAA, 0x6A, 0x2D, 0x9C, 0xDE, 0x43, 0x0C, 0xDE, 0xC6, 0x17, 0xF6, 0xC7, 0xF1, 0xDE},
{0x74, 0x20, 0xF6, 0x46, 0x77, 0xB0, 0x59, 0x2C, 0xE8, 0x1B, 0x58, 0x64, 0x47, 0x41, 0x37, 0xD9},
- {0xAA, 0x19, 0x0F, 0xFA, 0x4C, 0x30, 0x3B, 0x2E, 0xE8, 0x1B, 0x58, 0x64, 0x47, 0x41, 0x37, 0xD9}
+ {0xAA, 0x19, 0x0F, 0xFA, 0x4C, 0x30, 0x3B, 0x2E, 0xE6, 0xD8, 0x9A, 0xCF, 0xE5, 0x3F, 0xB3, 0x4B}
};
bool usecase_is_invalid(unsigned int usecase) {
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
return usecase >= CRYPTOUSECASE_MAX_5X;
} else {
return usecase >= CRYPTOUSECASE_MAX;
diff --git a/exosphere/src/sealedkeys.h b/exosphere/src/sealedkeys.h
index c73f148bd..70f380527 100644
--- a/exosphere/src/sealedkeys.h
+++ b/exosphere/src/sealedkeys.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_SEALED_KEYS_H
#define EXOSPHERE_SEALED_KEYS_H
diff --git a/exosphere/src/smc_ams.c b/exosphere/src/smc_ams.c
new file mode 100644
index 000000000..5c58cbda3
--- /dev/null
+++ b/exosphere/src/smc_ams.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+#include
+#include
+#include
+#include
+
+#include "utils.h"
+#include "smc_ams.h"
+#include "arm.h"
+#include "synchronization.h"
+#include "memory_map.h"
+#include "mmu.h"
+
+static atomic_flag g_ams_userpage_mapped = ATOMIC_FLAG_INIT;
+static atomic_flag g_ams_iram_page_mapped = ATOMIC_FLAG_INIT;
+
+static inline uintptr_t get_ams_user_page_secure_monitor_addr(void) {
+ return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_USER_PAGE);
+}
+
+static inline uintptr_t get_ams_iram_page_secure_monitor_addr(void) {
+ return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE);
+}
+
+#define AMS_USER_PAGE_SECURE_MONITOR_ADDR (get_ams_user_page_secure_monitor_addr())
+#define AMS_IRAM_PAGE_SECURE_MONITOR_ADDR (get_ams_iram_page_secure_monitor_addr())
+
+
+static inline uintptr_t get_page_for_address(void *address) {
+ return ((uintptr_t)(address)) & ~0xFFFULL;
+}
+
+static bool ams_is_user_addr_valid(uintptr_t user_address) {
+ /* Check that the address is in dram. */
+ uintptr_t page_address = get_page_for_address((void *)user_address);
+ return (page_address - 0x80000000ull) < (6ull << 30);
+}
+
+static bool ams_is_iram_addr_valid(uintptr_t iram_address) {
+ /* Check that the address is in iram. */
+ return 0x40000000ULL <= iram_address && iram_address <= 0x4003FFFFULL;
+}
+
+static void ams_map_userpage(uintptr_t user_address) {
+ lock_acquire(&g_ams_userpage_mapped);
+ static const uint64_t userpage_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_NORMAL;
+ uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
+ mmu_map_page(mmu_l3_tbl, AMS_USER_PAGE_SECURE_MONITOR_ADDR, get_page_for_address((void *)user_address), userpage_attributes);
+ tlb_invalidate_page_inner_shareable((void *)AMS_USER_PAGE_SECURE_MONITOR_ADDR);
+}
+
+static void ams_unmap_userpage(void) {
+ uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
+ mmu_unmap_page(mmu_l3_tbl, AMS_USER_PAGE_SECURE_MONITOR_ADDR);
+ tlb_invalidate_page_inner_shareable((void *)AMS_USER_PAGE_SECURE_MONITOR_ADDR);
+ lock_release(&g_ams_userpage_mapped);
+}
+
+void ams_map_irampage(uintptr_t iram_address) {
+ lock_acquire(&g_ams_iram_page_mapped);
+ static const uint64_t irampage_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_DEVICE;
+ uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
+ mmu_map_page(mmu_l3_tbl, AMS_IRAM_PAGE_SECURE_MONITOR_ADDR, get_page_for_address((void *)iram_address), irampage_attributes);
+ tlb_invalidate_page_inner_shareable((void *)AMS_IRAM_PAGE_SECURE_MONITOR_ADDR);
+}
+
+void ams_unmap_irampage(void) {
+ uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
+ mmu_unmap_page(mmu_l3_tbl, AMS_IRAM_PAGE_SECURE_MONITOR_ADDR);
+ tlb_invalidate_page_inner_shareable((void *)AMS_IRAM_PAGE_SECURE_MONITOR_ADDR);
+ lock_release(&g_ams_iram_page_mapped);
+}
+
+uint32_t ams_iram_copy(smc_args_t *args) {
+ /* Implements a DRAM <-> IRAM copy of up to one page. */
+ /* This operation is necessary to implement reboot-to-payload. */
+ /* args->X[1] = DRAM address (translated by kernel), must be 4-byte aligned. */
+ /* args->X[2] = IRAM address, must be 4-byte aligned. */
+ /* args->X[3] = size (must be <= 0x1000 and 4-byte aligned). */
+ /* args->X[4] = 0 for read, 1 for write. */
+
+ const uintptr_t dram_address = (uintptr_t)args->X[1];
+ const uintptr_t iram_address = (uintptr_t)args->X[2];
+ const uintptr_t dram_page_offset = (dram_address & 0xFFFULL);
+ const uintptr_t iram_page_offset = (iram_address & 0xFFFULL);
+ const size_t size = args->X[3];
+ const uint32_t option = (uint32_t)args->X[4];
+
+ /* Validate addresses. */
+ if (!ams_is_user_addr_valid(dram_address) || !ams_is_iram_addr_valid(iram_address)) {
+ return 2;
+ }
+
+ /* Validate size. */
+ if (size > 0x1000 || (size + dram_page_offset) > 0x1000 || (size + iram_page_offset) > 0x1000) {
+ return 2;
+ }
+
+ /* Validate alignment. */
+ if (size % sizeof(uint32_t) || dram_page_offset % sizeof(uint32_t) || iram_page_offset % sizeof(uint32_t)) {
+ return 2;
+ }
+
+ /* Validate argument. */
+ if (option != 0 && option != 1) {
+ return 2;
+ }
+
+ /* Map pages. */
+ ams_map_userpage(dram_address);
+ ams_map_irampage(iram_address);
+
+ /* Set source/destination for copy. */
+ volatile uint32_t *dram_ptr = (volatile uint32_t *)(AMS_USER_PAGE_SECURE_MONITOR_ADDR + dram_page_offset);
+ volatile uint32_t *iram_ptr = (volatile uint32_t *)(AMS_IRAM_PAGE_SECURE_MONITOR_ADDR + iram_page_offset);
+
+ volatile uint32_t *dst;
+ volatile uint32_t *src;
+ const size_t num_dwords = size / sizeof(uint32_t);
+ if (option == 0) {
+ dst = dram_ptr;
+ src = iram_ptr;
+ } else {
+ dst = iram_ptr;
+ src = dram_ptr;
+ }
+
+ /* Actually copy data. */
+ for (size_t i = 0; i < num_dwords; i++) {
+ dst[i] = src[i];
+ }
+
+ /* Flush! */
+ flush_dcache_range((void *)dst, (void *)(dst + num_dwords));
+
+ /* Unmap pages. */
+ ams_unmap_irampage();
+ ams_unmap_userpage();
+
+ return 0;
+}
diff --git a/exosphere/src/smc_ams.h b/exosphere/src/smc_ams.h
new file mode 100644
index 000000000..8b74d3bd5
--- /dev/null
+++ b/exosphere/src/smc_ams.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef EXOSPHERE_SMC_AMS_H
+#define EXOSPHERE_SMC_AMS_H
+
+#include "smc_api.h"
+
+uint32_t ams_iram_copy(smc_args_t *args);
+
+void ams_map_irampage(uintptr_t iram_address);
+void ams_unmap_irampage(void);
+
+#endif
\ No newline at end of file
diff --git a/exosphere/src/smc_api.c b/exosphere/src/smc_api.c
index 23c5cb728..39e0a7d52 100644
--- a/exosphere/src/smc_api.c
+++ b/exosphere/src/smc_api.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
@@ -15,20 +31,24 @@
#include "sealedkeys.h"
#include "smc_api.h"
#include "smc_user.h"
+#include "smc_ams.h"
#include "se.h"
#include "userpage.h"
#include "titlekey.h"
-#include "lp0.h"
+#include "sc7.h"
#include "exocfg.h"
#define SMC_USER_HANDLERS 0x13
#define SMC_PRIV_HANDLERS 0x9
+#define SMC_AMS_HANDLERS 0x2
+
#define DEBUG_LOG_SMCS 0
+#define DEBUG_PANIC_ON_FAILURE 0
/* User SMC prototypes */
-uint32_t smc_set_config(smc_args_t *args);
-uint32_t smc_get_config(smc_args_t *args);
+uint32_t smc_set_config_user(smc_args_t *args);
+uint32_t smc_get_config_user(smc_args_t *args);
uint32_t smc_check_status(smc_args_t *args);
uint32_t smc_get_result(smc_args_t *args);
uint32_t smc_exp_mod(smc_args_t *args);
@@ -54,12 +74,15 @@ uint32_t smc_decrypt_or_import_rsa_key(smc_args_t *args);
uint32_t smc_cpu_suspend(smc_args_t *args);
uint32_t smc_cpu_off(smc_args_t *args);
uint32_t smc_cpu_on(smc_args_t *args);
-/* uint32_t smc_get_config(smc_args_t *args); */
+uint32_t smc_get_config_priv(smc_args_t *args);
uint32_t smc_get_random_bytes_for_priv(smc_args_t *args);
uint32_t smc_panic(smc_args_t *args);
uint32_t smc_configure_carveout(smc_args_t *args);
uint32_t smc_read_write_register(smc_args_t *args);
+/* Atmosphere SMC prototypes */
+uint32_t smc_ams_iram_copy(smc_args_t *args);
+
typedef struct {
uint32_t id;
uint32_t (*handler)(smc_args_t *args);
@@ -72,8 +95,8 @@ typedef struct {
static smc_table_entry_t g_smc_user_table[SMC_USER_HANDLERS] = {
{0, NULL},
- {0xC3000401, smc_set_config},
- {0xC3000002, smc_get_config},
+ {0xC3000401, smc_set_config_user},
+ {0xC3000002, smc_get_config_user},
{0xC3000003, smc_check_status},
{0xC3000404, smc_get_result},
{0xC3000E05, smc_exp_mod},
@@ -97,14 +120,20 @@ static smc_table_entry_t g_smc_priv_table[SMC_PRIV_HANDLERS] = {
{0xC4000001, smc_cpu_suspend},
{0x84000002, smc_cpu_off},
{0xC4000003, smc_cpu_on},
- {0xC3000004, smc_get_config}, /* NOTE: Same function as for USER */
+ {0xC3000004, smc_get_config_priv},
{0xC3000005, smc_get_random_bytes_for_priv},
{0xC3000006, smc_panic},
{0xC3000007, smc_configure_carveout},
{0xC3000008, smc_read_write_register}
};
-static smc_table_t g_smc_tables[2] = {
+/* This is a table used for atmosphere-specific SMCs. */
+static smc_table_entry_t g_smc_ams_table[SMC_AMS_HANDLERS] = {
+ {0, NULL},
+ {0xF0000201, smc_ams_iram_copy},
+};
+
+static smc_table_t g_smc_tables[SMC_HANDLER_COUNT + 1] = {
{ /* SMC_HANDLER_USER */
g_smc_user_table,
SMC_USER_HANDLERS
@@ -112,6 +141,10 @@ static smc_table_t g_smc_tables[2] = {
{ /* SMC_HANDLER_PRIV */
g_smc_priv_table,
SMC_PRIV_HANDLERS
+ },
+ { /* SMC_HANDLER_AMS */
+ g_smc_ams_table,
+ SMC_AMS_HANDLERS
}
};
@@ -121,21 +154,29 @@ static atomic_flag g_is_priv_smc_in_progress = ATOMIC_FLAG_INIT;
/* Global for smc_configure_carveout. */
static bool g_configured_carveouts[2] = {false, false};
+static bool g_has_suspended = false;
+void set_suspend_for_debug(void) {
+ g_has_suspended = true;
+}
+
void set_version_specific_smcs(void) {
switch (exosphere_get_target_firmware()) {
- case EXOSPHERE_TARGET_FIRMWARE_100:
+ case ATMOSPHERE_TARGET_FIRMWARE_100:
/* 1.0.0 doesn't have ConfigureCarveout or ReadWriteRegister. */
g_smc_priv_table[7].handler = NULL;
g_smc_priv_table[8].handler = NULL;
/* 1.0.0 doesn't have UnwrapAesWrappedTitlekey. */
g_smc_user_table[0x12].handler = NULL;
break;
- case EXOSPHERE_TARGET_FIRMWARE_200:
- case EXOSPHERE_TARGET_FIRMWARE_300:
- case EXOSPHERE_TARGET_FIRMWARE_400:
+ case ATMOSPHERE_TARGET_FIRMWARE_200:
+ case ATMOSPHERE_TARGET_FIRMWARE_300:
+ case ATMOSPHERE_TARGET_FIRMWARE_400:
/* Do nothing. */
break;
- case EXOSPHERE_TARGET_FIRMWARE_500:
+ case ATMOSPHERE_TARGET_FIRMWARE_500:
+ case ATMOSPHERE_TARGET_FIRMWARE_600:
+ case ATMOSPHERE_TARGET_FIRMWARE_620:
+ case ATMOSPHERE_TARGET_FIRMWARE_700:
/* No more LoadSecureExpModKey. */
g_smc_user_table[0xE].handler = NULL;
g_smc_user_table[0xC].id = 0xC300D60C;
@@ -204,19 +245,25 @@ void clear_smc_callback(uint64_t key) {
_Atomic uint64_t num_smcs_called = 0;
void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
- unsigned char smc_id;
+ unsigned char smc_id, call_range;
unsigned int result;
unsigned int (*smc_handler)(smc_args_t *args);
-
+
/* Validate top-level handler. */
- if (handler_id != SMC_HANDLER_USER && handler_id != SMC_HANDLER_PRIV) {
+ if (handler_id >= SMC_HANDLER_COUNT) {
generic_panic();
}
- /* Validate core is appropriate for handler. */
- if (handler_id == SMC_HANDLER_USER && get_core_id() != 3) {
- /* USER SMCs must be called via svcCallSecureMonitor on core 3 (where spl runs) */
- generic_panic();
+ /* If user-handler, detect if talking to Atmosphere/validate calling core. */
+ if (handler_id == SMC_HANDLER_USER) {
+ if ((call_range = (unsigned char)((args->X[0] >> 24) & 0x3F)) == SMC_CALL_RANGE_TRUSTED_APP) {
+ /* Nintendo's SMCs are all OEM-specific. */
+ /* Pending a reason not to, we will treat Trusted Application SMCs as intended to talk to Atmosphere. */
+ handler_id = SMC_HANDLER_AMS;
+ } else if (get_core_id() != 3) {
+ /* USER SMCs must be called via svcCallSecureMonitor on core 3 (where spl runs) */
+ generic_panic();
+ }
}
/* Validate sub-handler index */
@@ -255,7 +302,8 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
}
#endif
- if (args->X[0] && (!is_aes_kek || args->X[3] <= EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG))
+#if DEBUG_PANIC_ON_FAILURE
+ if (args->X[0] && (!is_aes_kek || args->X[3] <= ATMOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG))
{
MAKE_REG32(get_iram_address_for_debug() + 0x4FF0) = handler_id;
MAKE_REG32(get_iram_address_for_debug() + 0x4FF4) = smc_id;
@@ -263,6 +311,9 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
*(volatile smc_args_t *)(get_iram_address_for_debug() + 0x4F00) = *args;
panic(PANIC_REBOOT);
}
+#else
+ (void)(is_aes_kek);
+#endif
(void)result; /* FIXME: result unused */
}
@@ -301,15 +352,15 @@ uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *),
return result;
}
-uint32_t smc_set_config(smc_args_t *args) {
+uint32_t smc_set_config_user(smc_args_t *args) {
/* Actual value presumed in X3 on hardware. */
- return configitem_set((ConfigItem)args->X[1], args->X[3]);
+ return configitem_set(false, (ConfigItem)args->X[1], args->X[3]);
}
-uint32_t smc_get_config(smc_args_t *args) {
+uint32_t smc_get_config_user(smc_args_t *args) {
uint64_t out_item = 0;
uint32_t result;
- result = configitem_get((ConfigItem)args->X[1], &out_item);
+ result = configitem_get(false, (ConfigItem)args->X[1], &out_item);
args->X[1] = out_item;
return result;
}
@@ -506,6 +557,14 @@ uint32_t smc_cpu_suspend(smc_args_t *args) {
return smc_wrapper_sync(args, cpu_suspend_wrapper);
}
+uint32_t smc_get_config_priv(smc_args_t *args) {
+ uint64_t out_item = 0;
+ uint32_t result;
+ result = configitem_get(true, (ConfigItem)args->X[1], &out_item);
+ args->X[1] = out_item;
+ return result;
+}
+
uint32_t smc_get_random_bytes_for_priv(smc_args_t *args) {
/* This is an interesting SMC. */
/* The kernel must NEVER be unable to get random bytes, if it needs them */
@@ -558,7 +617,7 @@ uint32_t smc_read_write_register(smc_args_t *args) {
} else {
return 2;
}
- } else if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400 && MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) <= address &&
+ } else if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400 && MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) <= address &&
address < MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) + MMIO_GET_DEVICE_SIZE(MMIO_DEVID_MC)) {
/* Memory Controller RW supported only on 4.0.0+ */
const uint8_t mc_whitelist[0x68] = {
@@ -631,8 +690,10 @@ uint32_t smc_configure_carveout(smc_args_t *args) {
}
/* Configuration is one-shot, and cannot be done multiple times. */
- if (g_configured_carveouts[carveout_id]) {
- return 2;
+ if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_300) {
+ if (g_configured_carveouts[carveout_id]) {
+ return 2;
+ }
}
configure_kernel_carveout(carveout_id + 4, address, size);
@@ -645,3 +706,7 @@ uint32_t smc_panic(smc_args_t *args) {
uint32_t color = ((args->X[1] & 0xF) << 8) | ((args->X[1] & 0xF0)) | ((args->X[1] & 0xF00) >> 8);
panic((color << 20) | 0x40);
}
+
+uint32_t smc_ams_iram_copy(smc_args_t *args) {
+ return smc_wrapper_sync(args, ams_iram_copy);
+}
diff --git a/exosphere/src/smc_api.h b/exosphere/src/smc_api.h
index 3d2a46a79..5f95444fc 100644
--- a/exosphere/src/smc_api.h
+++ b/exosphere/src/smc_api.h
@@ -1,10 +1,37 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_SMC_API_H
#define EXOSPHERE_SMC_API_H
#include
-#define SMC_HANDLER_USER 0
-#define SMC_HANDLER_PRIV 1
+#define SMC_HANDLER_USER 0
+#define SMC_HANDLER_PRIV 1
+#define SMC_HANDLER_COUNT 2
+
+#define SMC_HANDLER_AMS (SMC_HANDLER_COUNT)
+
+#define SMC_CALL_RANGE_ARM_ARCH 0
+#define SMC_CALL_RANGE_CPU 1
+#define SMC_CALL_RANGE_SIP 2
+#define SMC_CALL_RANGE_OEM 3
+#define SMC_CALL_RANGE_STANDARD 4
+
+#define SMC_CALL_RANGE_TRUSTED_APP 0x30
typedef struct {
uint64_t X[8];
@@ -22,6 +49,9 @@ uintptr_t get_exception_entry_stack_address(unsigned int core_id);
void set_version_specific_smcs(void);
+
+void set_suspend_for_debug(void);
+
void call_smc_handler(unsigned int handler_id, smc_args_t *args);
#endif
diff --git a/exosphere/src/smc_user.c b/exosphere/src/smc_user.c
index 7cc8103de..13a7ed367 100644
--- a/exosphere/src/smc_user.c
+++ b/exosphere/src/smc_user.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include
@@ -24,6 +40,22 @@ static uint8_t g_imported_exponents[4][0x100];
static uint8_t g_rsausecase_to_cryptousecase[5] = {1, 2, 3, 5, 6};
+static bool is_user_keyslot_valid(unsigned int keyslot) {
+ switch (exosphere_get_target_firmware()) {
+ case ATMOSPHERE_TARGET_FIRMWARE_100:
+ case ATMOSPHERE_TARGET_FIRMWARE_200:
+ case ATMOSPHERE_TARGET_FIRMWARE_300:
+ case ATMOSPHERE_TARGET_FIRMWARE_400:
+ case ATMOSPHERE_TARGET_FIRMWARE_500:
+ return keyslot <= 3;
+ case ATMOSPHERE_TARGET_FIRMWARE_600:
+ case ATMOSPHERE_TARGET_FIRMWARE_620:
+ case ATMOSPHERE_TARGET_FIRMWARE_700:
+ default:
+ return keyslot <= 5;
+ }
+}
+
void set_exp_mod_done(bool done) {
g_exp_mod_done = done;
}
@@ -126,7 +158,7 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
uint8_t mask_id = (uint8_t)((packed_options >> 1) & 3);
/* Switches the output based on how it will be used. */
- uint8_t usecase = (uint8_t)((packed_options >> 5) & (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500 ? 7 : 3));
+ uint8_t usecase = (uint8_t)((packed_options >> 5) & (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500 ? 7 : 3));
/* Switched the output based on whether it should be console unique. */
bool is_personalized = (int)(packed_options & 1);
@@ -134,9 +166,9 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
bool is_recovery_boot = configitem_is_recovery_boot();
/* 5.0.0+ Bounds checking. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
if (is_personalized) {
- if (master_key_rev > MASTERKEY_REVISION_500_CURRENT || ((1 << (master_key_rev + 1)) & 0x33) == 0) {
+ if (master_key_rev >= MASTERKEY_REVISION_MAX || (MASTERKEY_REVISION_300 <= master_key_rev && master_key_rev < MASTERKEY_REVISION_400_410)) {
return 2;
}
if (mask_id > 3 || usecase >= CRYPTOUSECASE_MAX_5X) {
@@ -163,11 +195,15 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
/* Masks 0, 3 are allowed all the time. */
- const uint8_t kek_seeds[4][0x10] = {
+ const uint8_t kek_seeds[7][0x10] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xA2, 0xAB, 0xBF, 0x9C, 0x92, 0x2F, 0xBB, 0xE3, 0x78, 0x79, 0x9B, 0xC0, 0xCC, 0xEA, 0xA5, 0x74},
{0x57, 0xE2, 0xD9, 0x45, 0xE4, 0x92, 0xF4, 0xFD, 0xC3, 0xF9, 0x86, 0x38, 0x89, 0x78, 0x9F, 0x3C},
- {0xE5, 0x4D, 0x9A, 0x02, 0xF0, 0x4F, 0x5F, 0xA8, 0xAD, 0x76, 0x0A, 0xF6, 0x32, 0x95, 0x59, 0xBB}
+ {0xE5, 0x4D, 0x9A, 0x02, 0xF0, 0x4F, 0x5F, 0xA8, 0xAD, 0x76, 0x0A, 0xF6, 0x32, 0x95, 0x59, 0xBB},
+ /* 5.0.0+ KEK seeds. */
+ {0x59, 0xD9, 0x31, 0xF4, 0xA7, 0x97, 0xB8, 0x14, 0x40, 0xD6, 0xA2, 0x60, 0x2B, 0xED, 0x15, 0x31},
+ {0xFD, 0x6A, 0x25, 0xE5, 0xD8, 0x38, 0x7F, 0x91, 0x49, 0xDA, 0xF8, 0x59, 0xA8, 0x28, 0xE6, 0x75},
+ {0x89, 0x96, 0x43, 0x9A, 0x7C, 0xD5, 0x59, 0x55, 0x24, 0xD5, 0x24, 0x18, 0xAB, 0x6C, 0x04, 0x61}
};
const uint8_t kek_masks[4][0x10] = {
{0x4D, 0x87, 0x09, 0x86, 0xC4, 0x5D, 0x20, 0x72, 0x2F, 0xBA, 0x10, 0x53, 0xDA, 0x92, 0xE8, 0xA9},
@@ -184,9 +220,9 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
unsigned int keyslot;
if (is_personalized) {
/* Behavior changed in 4.0.0, and in 5.0.0. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
keyslot = devkey_get_keyslot(master_key_rev);
- } else if (exosphere_get_target_firmware() == EXOSPHERE_TARGET_FIRMWARE_400) {
+ } else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_400) {
if (master_key_rev >= 1) {
keyslot = KEYSLOT_SWITCH_DEVICEKEY; /* New device key, 4.x. */
} else {
@@ -218,7 +254,7 @@ uint32_t user_load_aes_key(smc_args_t *args) {
uint64_t wrapped_key[2];
uint32_t keyslot = (uint32_t)args->X[1];
- if (keyslot > 3) {
+ if (!is_user_keyslot_valid(keyslot)) {
return 2;
}
@@ -258,6 +294,10 @@ uint32_t crypt_aes_done_handler(void) {
uint32_t user_crypt_aes(smc_args_t *args) {
uint32_t keyslot = args->X[1] & 3;
uint32_t mode = (args->X[1] >> 4) & 3;
+
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
+ keyslot = args->X[1] & 7;
+ }
uint64_t iv_ctr[2];
iv_ctr[0] = args->X[2];
@@ -267,11 +307,11 @@ uint32_t user_crypt_aes(smc_args_t *args) {
uint32_t out_ll_paddr = (uint32_t)(args->X[5]);
size_t size = args->X[6];
- if (size & 0xF) {
+ if (!is_user_keyslot_valid(keyslot) || size & 0xF) {
return 2;
}
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
/* Disallow dma lists outside of safe range. */
if (in_ll_paddr - 0x80000000 >= 0x3FF7F5) {
return 2;
@@ -319,7 +359,7 @@ uint32_t user_generate_specific_aes_key(smc_args_t *args) {
if (master_key_rev > 0) {
master_key_rev -= 1;
}
- if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400) {
master_key_rev = 0;
}
@@ -335,9 +375,9 @@ uint32_t user_generate_specific_aes_key(smc_args_t *args) {
unsigned int keyslot;
/* Behavior changed in 5.0.0. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
keyslot = devkey_get_keyslot(master_key_rev);
- } else if (exosphere_get_target_firmware() == EXOSPHERE_TARGET_FIRMWARE_400) {
+ } else if (exosphere_get_target_firmware() == ATMOSPHERE_TARGET_FIRMWARE_400) {
if (master_key_rev >= 1) {
keyslot = KEYSLOT_SWITCH_DEVICEKEY; /* New device key, 4.x. */
} else {
@@ -386,7 +426,7 @@ uint32_t user_compute_cmac(smc_args_t *args) {
upage_ref_t page_ref;
/* Validate keyslot and size. */
- if (keyslot > 3 || args->X[3] > 0x400) {
+ if (!is_user_keyslot_valid(keyslot) || args->X[3] > 0x400) {
return 2;
}
@@ -416,7 +456,7 @@ uint32_t user_load_rsa_oaep_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function no longer exists in 5.x+. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
generic_panic();
}
@@ -465,7 +505,7 @@ uint32_t user_decrypt_rsa_private_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function no longer exists in 5.x+. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
generic_panic();
}
@@ -523,7 +563,7 @@ uint32_t user_load_secure_exp_mod_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function no longer exists in 5.x+. */
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
generic_panic();
}
@@ -579,7 +619,7 @@ uint32_t user_secure_exp_mod(smc_args_t *args) {
void *user_modulus = (void *)args->X[2];
unsigned int exponent_id = 1;
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_500) {
switch (args->X[3]) {
case 0:
exponent_id = 1;
@@ -622,13 +662,22 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
void *user_wrapped_key = (void *)args->X[1];
void *user_modulus = (void *)args->X[2];
- unsigned int master_key_rev = (unsigned int)args->X[7];
+ unsigned int option = (unsigned int)args->X[7];
+ unsigned int master_key_rev;
+ unsigned int titlekey_type;
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_600) {
+ master_key_rev = option & 0x3F;
+ titlekey_type = (option >> 6) & 1;
+ } else {
+ master_key_rev = option;
+ titlekey_type = 0;
+ }
if(master_key_rev > 0) {
master_key_rev -= 1;
}
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_300) {
if (master_key_rev >= MASTERKEY_REVISION_MAX) {
return 2;
}
@@ -653,6 +702,7 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
tkey_set_expected_label_hash(&args->X[3]);
tkey_set_master_key_rev(master_key_rev);
+ tkey_set_type(titlekey_type);
/* Hardcode RSA keyslot 0. */
set_rsa_keyslot(0, modulus, 0x100, g_imported_exponents[0], 0x100);
@@ -666,7 +716,7 @@ uint32_t user_load_titlekey(smc_args_t *args) {
uint64_t sealed_titlekey[2];
uint32_t keyslot = (uint32_t)args->X[1];
- if (keyslot > 3) {
+ if (!is_user_keyslot_valid(keyslot)) {
return 2;
}
@@ -692,7 +742,7 @@ uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args) {
if (master_key_rev > 0) {
master_key_rev -= 1;
}
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_300) {
if (master_key_rev >= MASTERKEY_REVISION_MAX) {
return 2;
}
@@ -701,6 +751,7 @@ uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args) {
}
tkey_set_master_key_rev(master_key_rev);
+ tkey_set_type(0);
tkey_aes_unwrap(titlekey, 0x10, aes_wrapped_titlekey, 0x10);
seal_titlekey(sealed_titlekey, 0x10, titlekey, 0x10);
@@ -787,7 +838,7 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
upage_ref_t page_ref;
/* This function only exists in 5.x+. */
- if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_500) {
+ if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_500) {
generic_panic();
}
diff --git a/exosphere/src/smc_user.h b/exosphere/src/smc_user.h
index a99add637..ca0adbd62 100644
--- a/exosphere/src/smc_user.h
+++ b/exosphere/src/smc_user.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_SMC_USER_H
#define EXOSPHERE_SMC_USER_H
diff --git a/exosphere/src/start.s b/exosphere/src/start.s
index 7730bda95..8c89dbb70 100644
--- a/exosphere/src/start.s
+++ b/exosphere/src/start.s
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
/* For some reason GAS doesn't know about it, even with .cpu cortex-a57 */
#define cpuactlr_el1 s3_1_c15_c2_0
#define cpuectlr_el1 s3_1_c15_c2_1
@@ -101,8 +117,11 @@ __start_cold:
br x16
_post_cold_crt0_reloc:
-
+ /* Setup stack for coldboot crt0. */
msr spsel, #0
+ bl get_coldboot_crt0_temp_stack_address
+ mov sp, x0
+ mov fp, #0
bl get_coldboot_crt0_stack_address
mov sp, x0
mov fp, #0
@@ -128,6 +147,7 @@ _post_cold_crt0_reloc:
ldr x1, =0x80010000
/* Set size in coldboot relocation list. */
str x21, [x0, #0x8]
+
bl coldboot_init
ldr x16, =__jump_to_main_cold
@@ -219,8 +239,8 @@ __jump_to_main_warm:
bl __set_exception_entry_stack_pointer
mov w0, #0 /* use core0,1,2 stack bottom + 0x800 (VA of warmboot crt0 sp) temporarily */
- bl get_exception_entry_stack_address
- add sp, x0, #0x800
+ bl get_warmboot_main_stack_address
+ mov sp, x0
bl warmboot_main
.section .text.__set_exception_entry_stack, "ax", %progbits
@@ -244,12 +264,14 @@ __set_exception_entry_stack_pointer:
.type __jump_to_lower_el, %function
__jump_to_lower_el:
/* x0: arg (context ID), x1: entrypoint, w2: spsr */
+ mov x19, x0
mov w2, w2
msr elr_el3, x1
msr spsr_el3, x2
bl __set_exception_entry_stack_pointer
+ mov x0, x19
isb
eret
diff --git a/exosphere/src/synchronization.h b/exosphere/src/synchronization.h
index 328186e35..10a6f21c7 100644
--- a/exosphere/src/synchronization.h
+++ b/exosphere/src/synchronization.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_SYNCHRONIZATION_H
#define EXOSPHERE_SYNCHRONIZATION_H
diff --git a/exosphere/src/sysctr0.h b/exosphere/src/sysctr0.h
index 9c887c48c..fae0c1446 100644
--- a/exosphere/src/sysctr0.h
+++ b/exosphere/src/sysctr0.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_SYSCTR0_H
#define EXOSPHERE_SYSCTR0_H
@@ -9,9 +25,25 @@
#define SYSCTR0_BASE (MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_SYSCTR0))
-
#define MAKE_SYSCTR0_REG(n) MAKE_REG32(SYSCTR0_BASE + n)
-
+#define SYSCTR0_CNTCR_0 MAKE_SYSCTR0_REG(0x00)
+#define SYSCTR0_CNTSR_0 MAKE_SYSCTR0_REG(0x04)
+#define SYSCTR0_CNTCV0_0 MAKE_SYSCTR0_REG(0x08)
+#define SYSCTR0_CNTCV1_0 MAKE_SYSCTR0_REG(0x0C)
+#define SYSCTR0_CNTFID0_0 MAKE_SYSCTR0_REG(0x20)
+#define SYSCTR0_CNTFID1_0 MAKE_SYSCTR0_REG(0x24)
+#define SYSCTR0_COUNTERID4_0 MAKE_SYSCTR0_REG(0xFD0)
+#define SYSCTR0_COUNTERID5_0 MAKE_SYSCTR0_REG(0xFD4)
+#define SYSCTR0_COUNTERID6_0 MAKE_SYSCTR0_REG(0xFD8)
+#define SYSCTR0_COUNTERID7_0 MAKE_SYSCTR0_REG(0xFDC)
+#define SYSCTR0_COUNTERID0_0 MAKE_SYSCTR0_REG(0xFE0)
+#define SYSCTR0_COUNTERID1_0 MAKE_SYSCTR0_REG(0xFE4)
+#define SYSCTR0_COUNTERID2_0 MAKE_SYSCTR0_REG(0xFE8)
+#define SYSCTR0_COUNTERID3_0 MAKE_SYSCTR0_REG(0xFEC)
+#define SYSCTR0_COUNTERID8_0 MAKE_SYSCTR0_REG(0xFF0)
+#define SYSCTR0_COUNTERID9_0 MAKE_SYSCTR0_REG(0xFF4)
+#define SYSCTR0_COUNTERID10_0 MAKE_SYSCTR0_REG(0xFF8)
+#define SYSCTR0_COUNTERID11_0 MAKE_SYSCTR0_REG(0xFFC)
#endif
diff --git a/exosphere/src/sysreg.h b/exosphere/src/sysreg.h
index 7fc362004..f8e0f7298 100644
--- a/exosphere/src/sysreg.h
+++ b/exosphere/src/sysreg.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_SYSREG_H
#define EXOSPHERE_SYSREG_H
diff --git a/exosphere/src/timers.c b/exosphere/src/timers.c
index cf16fef5f..cffc7e57b 100644
--- a/exosphere/src/timers.c
+++ b/exosphere/src/timers.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
diff --git a/exosphere/src/timers.h b/exosphere/src/timers.h
index 8c48fe6a2..0cc88c050 100644
--- a/exosphere/src/timers.h
+++ b/exosphere/src/timers.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_TIMERS_H
#define EXOSPHERE_TIMERS_H
@@ -11,10 +27,11 @@ static inline uintptr_t get_timers_base(void) {
}
#define TIMERS_BASE (get_timers_base())
-
#define MAKE_TIMERS_REG(n) MAKE_REG32(TIMERS_BASE + n)
-#define TIMERUS_CNTR_1US_0 MAKE_REG32(TIMERS_BASE + 0x10)
+#define TIMERUS_CNTR_1US_0 MAKE_TIMERS_REG(0x10)
+#define SHARED_INTR_STATUS_0 MAKE_TIMERS_REG(0x1A0)
+#define SHARED_TIMER_SECURE_CFG_0 MAKE_TIMERS_REG(0x1A4)
typedef struct {
uint32_t CONFIG;
@@ -25,7 +42,7 @@ typedef struct {
#define GET_WDT(n) ((volatile watchdog_timers_t *)(TIMERS_BASE + 0x100 + 0x20 * n))
#define WDT_REBOOT_PATTERN 0xC45A
-#define GET_WDT_REBOOT_CFG_REG(n) MAKE_REG32(TIMERS_BASE + 0x60 + 0x8*n)
+#define GET_WDT_REBOOT_CFG_REG(n) MAKE_REG32(TIMERS_BASE + 0x60 + 0x8 * n)
void wait(uint32_t microseconds);
diff --git a/exosphere/src/titlekey.c b/exosphere/src/titlekey.c
index 4c46ed226..3e0e5907a 100644
--- a/exosphere/src/titlekey.c
+++ b/exosphere/src/titlekey.c
@@ -1,8 +1,25 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include "utils.h"
#include "arm.h"
+#include "exocfg.h"
#include "titlekey.h"
#include "masterkey.h"
@@ -10,6 +27,7 @@
static uint64_t g_tkey_expected_label_hash[4];
static unsigned int g_tkey_master_key_rev = MASTERKEY_REVISION_MAX;
+static unsigned int g_tkey_type = 0;
/* Set the expected db prefix. */
void tkey_set_expected_label_hash(uint64_t *label_hash) {
@@ -25,6 +43,17 @@ void tkey_set_master_key_rev(unsigned int master_key_rev) {
g_tkey_master_key_rev = master_key_rev;
}
+static void tkey_validate_type(unsigned int type) {
+ if (type > TITLEKEY_TYPE_MAX || (type > 0 && exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_600)) {
+ generic_panic();
+ }
+}
+
+void tkey_set_type(unsigned int type) {
+ tkey_validate_type(type);
+ g_tkey_type = type;
+}
+
/* Reference for MGF1 can be found here: https://en.wikipedia.org/wiki/Mask_generation_function#MGF1 */
void calculate_mgf1_and_xor(void *masked, size_t masked_size, const void *seed, size_t seed_size) {
uint8_t cur_hash[0x20];
@@ -136,18 +165,19 @@ size_t tkey_rsa_oaep_unwrap(void *dst, size_t dst_size, void *src, size_t src_si
return wrapped_titlekey_size;
}
+static const uint8_t titlekek_sources[TITLEKEY_TYPE_MAX+1][0x10] = {
+ {0x1E, 0xDC, 0x7B, 0x3B, 0x60, 0xE6, 0xB4, 0xD8, 0x78, 0xB8, 0x17, 0x15, 0x98, 0x5E, 0x62, 0x9B},
+ {0x3B, 0x78, 0xF2, 0x61, 0x0F, 0x9D, 0x5A, 0xE2, 0x7B, 0x4E, 0x45, 0xAF, 0xCB, 0x0B, 0x67, 0x4D}
+};
+
void tkey_aes_unwrap(void *dst, size_t dst_size, const void *src, size_t src_size) {
if (g_tkey_master_key_rev >= MASTERKEY_REVISION_MAX || dst_size != 0x10 || src_size != 0x10) {
generic_panic();
}
-
- const uint8_t titlekek_source[0x10] = {
- 0x1E, 0xDC, 0x7B, 0x3B, 0x60, 0xE6, 0xB4, 0xD8, 0x78, 0xB8, 0x17, 0x15, 0x98, 0x5E, 0x62, 0x9B
- };
-
+
/* Generate the appropriate titlekek into keyslot 9. */
unsigned int master_keyslot = mkey_get_keyslot(g_tkey_master_key_rev);
- decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, master_keyslot, titlekek_source, 0x10);
+ decrypt_data_into_keyslot(KEYSLOT_SWITCH_TEMPKEY, master_keyslot, titlekek_sources[g_tkey_type], 0x10);
/* Unwrap the titlekey using the titlekek. */
se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_TEMPKEY, dst, 0x10, src, 0x10);
diff --git a/exosphere/src/titlekey.h b/exosphere/src/titlekey.h
index a74949b8b..8b4593911 100644
--- a/exosphere/src/titlekey.h
+++ b/exosphere/src/titlekey.h
@@ -1,10 +1,29 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_TITLEKEY_H
#define EXOSPHERE_TITLEKEY_H
#include
+#define TITLEKEY_TYPE_MAX 0x1
+
void tkey_set_expected_label_hash(uint64_t *label_hash);
void tkey_set_master_key_rev(unsigned int master_key_rev);
+void tkey_set_type(unsigned int type);
size_t tkey_rsa_oaep_unwrap(void *dst, size_t dst_size, void *src, size_t src_size);
diff --git a/exosphere/src/uart.c b/exosphere/src/uart.c
index ee1379f92..ce5c6c418 100644
--- a/exosphere/src/uart.c
+++ b/exosphere/src/uart.c
@@ -1,9 +1,24 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include "timers.h"
#include "uart.h"
#include "misc.h"
-/* Adapted from https://github.com/nwert/hekate/blob/master/hwinit/uart.c */
-
void uart_select(UartDevice dev) {
unsigned int id = (unsigned int)dev;
PINMUX_AUX_UARTn_TX_0(id) = 0; /* UART */
diff --git a/exosphere/src/uart.h b/exosphere/src/uart.h
index e39e56948..7a46e74c8 100644
--- a/exosphere/src/uart.h
+++ b/exosphere/src/uart.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_UART_H
#define EXOSPHERE_UART_H
@@ -5,7 +22,6 @@
#include "memory_map.h"
/* Exosphere driver for the Tegra X1 UARTs. */
-/* Mostly copied from https://github.com/nwert/hekate/blob/master/hwinit/uart.h and https://github.com/nwert/hekate/blob/master/hwinit/uart.c */
static inline uintptr_t get_uart_base(void) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_UART);
diff --git a/exosphere/src/userpage.c b/exosphere/src/userpage.c
index 01ee0afe2..d026df530 100644
--- a/exosphere/src/userpage.c
+++ b/exosphere/src/userpage.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "utils.h"
diff --git a/exosphere/src/userpage.h b/exosphere/src/userpage.h
index f14e0cd0a..7f708b0cc 100644
--- a/exosphere/src/userpage.h
+++ b/exosphere/src/userpage.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_USERPAGE_H
#define EXOSPHERE_USERPAGE_H
diff --git a/exosphere/src/utils.c b/exosphere/src/utils.c
index 2f60fbfe1..a01243e8a 100644
--- a/exosphere/src/utils.c
+++ b/exosphere/src/utils.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include "utils.h"
@@ -14,14 +30,15 @@ __attribute__ ((noreturn)) void panic(uint32_t code) {
APBDEV_PMC_SCRATCH200_0 = code;
}
- /* Uncomment for Debugging.
+ /* // Uncomment for Debugging.
uint64_t temp_reg;
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM)) = APBDEV_PMC_SCRATCH200_0;
SAVE_SYSREG64(ESR_EL3, 0x10);
SAVE_SYSREG64(ELR_EL3, 0x18);
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) + 0x400ull) = 0x10; */
+ MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10;
+ */
/* TODO: Custom Panic Driver, which displays to screen without rebooting. */
/* For now, just use NX BOOTLOADER's panic. */
@@ -32,7 +49,7 @@ __attribute__ ((noreturn)) void panic(uint32_t code) {
}
__attribute__ ((noreturn)) void generic_panic(void) {
- /* Uncomment for Debugging.
+ /* //Uncomment for Debugging.
uint64_t temp_reg;
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);
diff --git a/exosphere/src/utils.h b/exosphere/src/utils.h
index 1567c3fc5..22dd55e43 100644
--- a/exosphere/src/utils.h
+++ b/exosphere/src/utils.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef EXOSPHERE_UTILS_H
#define EXOSPHERE_UTILS_H
diff --git a/exosphere/src/version.h b/exosphere/src/version.h
deleted file mode 100644
index a22c9027f..000000000
--- a/exosphere/src/version.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef EXOSPHERE_VERSION_H
-#define EXOSPHERE_VERSION_H
-
-#define EXOSPHERE_RELEASE_VERSION_MAJOR 0
-#define EXOSPHERE_RELEASE_VERSION_MINOR 1
-
-#endif
\ No newline at end of file
diff --git a/exosphere/src/warmboot_init.c b/exosphere/src/warmboot_init.c
index 1dd7d1445..2422b03ba 100644
--- a/exosphere/src/warmboot_init.c
+++ b/exosphere/src/warmboot_init.c
@@ -1,13 +1,33 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include "utils.h"
#include "memory_map.h"
#include "mc.h"
#include "arm.h"
#include "synchronization.h"
#include "exocfg.h"
+#include "pmc.h"
#undef MC_BASE
#define MC_BASE (MMIO_GET_DEVICE_PA(MMIO_DEVID_MC))
+#define WARMBOOT_GET_TZRAM_SEGMENT_PA(x) ((g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_500) \
+ ? TZRAM_GET_SEGMENT_PA(x) : TZRAM_GET_SEGMENT_5X_PA(x))
+
/* start.s */
void __set_memory_registers(uintptr_t ttbr0, uintptr_t vbar, uint64_t cpuectlr, uint32_t scr,
uint32_t tcr, uint32_t cptr, uint64_t mair, uint32_t sctlr);
@@ -15,16 +35,16 @@ void __set_memory_registers(uintptr_t ttbr0, uintptr_t vbar, uint64_t cpuectlr,
unsigned int g_exosphere_target_firmware_for_init = 0;
uintptr_t get_warmboot_crt0_stack_address(void) {
- return TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE012_STACK) + 0x800;
+ return WARMBOOT_GET_TZRAM_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE012_STACK) + 0x800;
}
uintptr_t get_warmboot_crt0_stack_address_critsec_enter(void) {
unsigned int core_id = get_core_id();
- if (core_id) {
- return TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x1000;
+ if (core_id == 3) {
+ return WARMBOOT_GET_TZRAM_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x1000;
} else {
- return TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x80 * (core_id + 1);
+ return WARMBOOT_GET_TZRAM_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x80 * (core_id + 1);
}
}
@@ -33,7 +53,7 @@ void warmboot_crt0_critical_section_enter(volatile critical_section_t *critical_
}
void init_dma_controllers(unsigned int target_firmware) {
- if (target_firmware >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_400) {
/* Set some unknown registers in HOST1X. */
MAKE_REG32(0x500038F8) &= 0xFFFFFFFE;
MAKE_REG32(0x50003300) = 0;
@@ -89,9 +109,8 @@ void init_dma_controllers(unsigned int target_firmware) {
}
}
-void set_memory_registers_enable_mmu(void) {
+void _set_memory_registers_enable_mmu(const uintptr_t ttbr0) {
static const uintptr_t vbar = TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800;
- static const uintptr_t ttbr0 = TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64;
/*
- Disable table walk descriptor access prefetch.
@@ -142,12 +161,22 @@ void set_memory_registers_enable_mmu(void) {
__set_memory_registers(ttbr0, vbar, cpuectlr, scr, tcr, cptr, mair, sctlr);
}
+void set_memory_registers_enable_mmu_1x_ttbr0(void) {
+ static const uintptr_t ttbr0 = TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64;
+ _set_memory_registers_enable_mmu(ttbr0);
+}
+
+void set_memory_registers_enable_mmu_5x_ttbr0(void) {
+ static const uintptr_t ttbr0 = TZRAM_GET_SEGMENT_5X_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64;
+ _set_memory_registers_enable_mmu(ttbr0);
+}
+
#if 0 /* Since we decided not to identity-unmap TZRAM */
static void identity_remap_tzram(void) {
/* See also: configure_ttbls (in coldboot_init.c). */
- uintptr_t *mmu_l1_tbl = (uintptr_t *)(TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
- uintptr_t *mmu_l2_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE);
- uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
+ uintptr_t *mmu_l1_tbl = (uintptr_t *)(WARMBOOT_GET_TZRAM_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
+ uintptr_t *mmu_l2_tbl = (uintptr_t *)WARMBOOT_GET_TZRAM_SEGMENT_PA(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE);
+ uintptr_t *mmu_l3_tbl = (uintptr_t *)WARMBOOT_GET_TZRAM_SEGMENT_PA(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
mmu_map_table(1, mmu_l1_tbl, 0x40000000, mmu_l2_tbl, 0);
mmu_map_table(2, mmu_l2_tbl, 0x7C000000, mmu_l3_tbl, 0);
@@ -168,13 +197,17 @@ void warmboot_init(void) {
*/
flush_dcache_all();
invalidate_icache_all();
-
+
/* On warmboot (not cpu_on) only */
- if (MC_SECURITY_CFG3_0 == 0) {
+ if (VIRT_MC_SECURITY_CFG3 == 0) {
init_dma_controllers(g_exosphere_target_firmware_for_init);
}
-
+
/*identity_remap_tzram();*/
/* Nintendo pointlessly fully invalidate the TLB & invalidate the data cache on the modified ranges here */
- set_memory_registers_enable_mmu();
+ if (g_exosphere_target_firmware_for_init < ATMOSPHERE_TARGET_FIRMWARE_500) {
+ set_memory_registers_enable_mmu_1x_ttbr0();
+ } else {
+ set_memory_registers_enable_mmu_5x_ttbr0();
+ }
}
diff --git a/exosphere/src/warmboot_main.c b/exosphere/src/warmboot_main.c
index 01e127df6..b782a61e9 100644
--- a/exosphere/src/warmboot_main.c
+++ b/exosphere/src/warmboot_main.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include "utils.h"
#include "mmu.h"
#include "memory_map.h"
@@ -14,8 +30,15 @@
#include "car.h"
#include "i2c.h"
#include "misc.h"
+#include "uart.h"
#include "interrupt.h"
+#include "pmc.h"
+
+uintptr_t get_warmboot_main_stack_address(void) {
+ return TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x780;
+}
+
void __attribute__((noreturn)) warmboot_main(void) {
/*
This function and its callers are reached in either of the following events, under normal conditions:
@@ -32,9 +55,17 @@ void __attribute__((noreturn)) warmboot_main(void) {
identity_unmap_iram_cd_tzram();
/* On warmboot (not cpu_on) only */
- if (MC_SECURITY_CFG3_0 == 0) {
+ if (VIRT_MC_SECURITY_CFG3 == 0) {
+ /* N only does this on dev units, but we will do it unconditionally. */
+ {
+ uart_select(UART_A);
+ clkrst_reboot(CARDEVICE_UARTA);
+ uart_init(UART_A, 115200);
+ }
+
if (!configitem_is_retail()) {
- /* TODO: uart_log("OHAYO"); */
+ uart_send(UART_A, "OHAYO", 6);
+ uart_wait_idle(UART_A, UART_VENDOR_STATE_TX_IDLE);
}
/* Sanity check the Security Engine. */
@@ -48,12 +79,12 @@ void __attribute__((noreturn)) warmboot_main(void) {
/* Make PMC (2.x+), MC (4.x+) registers secure-only */
secure_additional_devices();
- if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400 || configitem_get_hardware_type() == 0) {
+ if (exosphere_get_target_firmware() < ATMOSPHERE_TARGET_FIRMWARE_400 || configitem_get_hardware_type() == 0) {
/* Enable input to I2C1 */
PINMUX_AUX_GEN1_I2C_SCL_0 = 0x40;
PINMUX_AUX_GEN1_I2C_SDA_0 = 0x40;
- clkrst_enable(CARDEVICE_I2C1);
+ clkrst_reboot(CARDEVICE_I2C1);
i2c_init(0);
i2c_clear_ti_charger_bit_7();
clkrst_disable(CARDEVICE_I2C1);
@@ -61,7 +92,7 @@ void __attribute__((noreturn)) warmboot_main(void) {
clear_user_smc_in_progress();
- if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
+ if (exosphere_get_target_firmware() >= ATMOSPHERE_TARGET_FIRMWARE_400) {
setup_4x_mmio();
}
}
diff --git a/fusee/fusee-primary/Makefile b/fusee/fusee-primary/Makefile
index 975160cb0..107b32f55 100644
--- a/fusee/fusee-primary/Makefile
+++ b/fusee/fusee-primary/Makefile
@@ -7,8 +7,17 @@ $(error "Please set DEVKITARM in your environment. export DEVKITARM=dev
endif
TOPDIR ?= $(CURDIR)
+
+AMS := $(TOPDIR)/../../
include $(DEVKITARM)/base_rules
+AMSBRANCH := $(shell git symbolic-ref --short HEAD)
+AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
+
+ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
+ AMSREV := $(AMSREV)-dirty
+endif
+
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
@@ -18,15 +27,15 @@ include $(DEVKITARM)/base_rules
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
BUILD := build
-SOURCES := src src/sdmmc src/hwinit src/lib src/lib/fatfs src/display
+SOURCES := src src/sdmmc src/lib src/lib/fatfs src/display
DATA := data
-INCLUDES := include
+INCLUDES := include ../../common/include
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
-DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC
+DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
CFLAGS := \
-g \
@@ -67,14 +76,15 @@ export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
- $(foreach dir,$(DATA),$(CURDIR)/$(dir))
+ $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
+ $(AMS)/exosphere/rebootstub
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
-BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
+BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) rebootstub.bin
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
@@ -101,10 +111,13 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
-.PHONY: $(BUILD) clean all
+.PHONY: $(BUILD) clean all check_rebootstub
#---------------------------------------------------------------------------------
-all: $(BUILD)
+all: check_rebootstub $(BUILD)
+
+check_rebootstub:
+ @$(MAKE) -C $(AMS)/exosphere/rebootstub all
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@@ -113,6 +126,7 @@ $(BUILD):
#---------------------------------------------------------------------------------
clean:
@echo clean ...
+ @$(MAKE) -C $(AMS)/exosphere/rebootstub clean
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
@@ -143,7 +157,7 @@ $(OFILES_SRC) : $(HFILES_BIN)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
-%.bin.o : %.bin
+%.bin.o %_bin.h: %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
diff --git a/fusee/fusee-primary/src/apb_misc.h b/fusee/fusee-primary/src/apb_misc.h
index 114b7496a..b2e8b1dff 100644
--- a/fusee/fusee-primary/src/apb_misc.h
+++ b/fusee/fusee-primary/src/apb_misc.h
@@ -1,6 +1,33 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_APB_MISC_H
#define FUSEE_APB_MISC_H
+#include
+
+#define APB_MISC_BASE 0x70000000
+#define APB_PADCTL_BASE 0x70000810
+#define MAKE_APB_MISC_REG(n) MAKE_REG32(APB_MISC_BASE + n)
+#define MAKE_APB_PADCTL_REG(n) MAKE_REG32(APB_PADCTL_BASE + n)
+
+#define APB_MISC_PP_PINMUX_GLOBAL_0 MAKE_APB_MISC_REG(0x40)
+#define APB_MISC_GP_WIFI_EN_CFGPADCTRL_0 MAKE_APB_MISC_REG(0xB64)
+#define APB_MISC_GP_WIFI_RST_CFGPADCTRL_0 MAKE_APB_MISC_REG(0xB68)
+
#define SDMMC1_PAD_CAL_DRVUP_SHIFT (20)
#define SDMMC1_PAD_CAL_DRVDN_SHIFT (12)
#define SDMMC1_PAD_CAL_DRVUP_MASK (0x7Fu << SDMMC1_PAD_CAL_DRVUP_SHIFT)
@@ -48,7 +75,7 @@ typedef struct {
static inline volatile tegra_padctl_t *padctl_get_regs(void)
{
- return (volatile tegra_padctl_t *)0x70000810;
+ return (volatile tegra_padctl_t *)APB_PADCTL_BASE;
}
#endif
diff --git a/fusee/fusee-primary/src/btn.c b/fusee/fusee-primary/src/btn.c
new file mode 100644
index 000000000..f845c350e
--- /dev/null
+++ b/fusee/fusee-primary/src/btn.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "btn.h"
+#include "i2c.h"
+#include "gpio.h"
+#include "timers.h"
+
+uint32_t btn_read()
+{
+ uint32_t res = 0;
+
+ if (!gpio_read(GPIO_BUTTON_VOL_DOWN))
+ res |= BTN_VOL_DOWN;
+
+ if (!gpio_read(GPIO_BUTTON_VOL_UP))
+ res |= BTN_VOL_UP;
+
+ uint32_t val = 0;
+ if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, 0x15, &val, 1))
+ {
+ if (val & 0x4)
+ res |= BTN_POWER;
+ }
+
+ return res;
+}
+
+uint32_t btn_wait()
+{
+ uint32_t res = 0, btn = btn_read();
+ int pwr = 0;
+
+ if (btn & BTN_POWER)
+ {
+ pwr = 1;
+ btn &= ~BTN_POWER;
+ }
+
+ do
+ {
+ res = btn_read();
+
+ if (!(res & BTN_POWER) && pwr)
+ pwr = 0;
+ else if (pwr)
+ res &= ~BTN_POWER;
+ } while (btn == res);
+
+ return res;
+}
+
+uint32_t btn_wait_timeout(uint32_t time_ms, uint32_t mask)
+{
+ uint32_t timeout = get_time_ms() + time_ms;
+ uint32_t res = btn_read() & mask;
+
+ do
+ {
+ if (!(res & mask))
+ res = btn_read() & mask;
+ } while (get_time_ms() < timeout);
+
+ return res;
+}
\ No newline at end of file
diff --git a/fusee/fusee-primary/src/btn.h b/fusee/fusee-primary/src/btn.h
new file mode 100644
index 000000000..04f569b94
--- /dev/null
+++ b/fusee/fusee-primary/src/btn.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_BTN_H_
+#define FUSEE_BTN_H_
+
+#define BTN_POWER 0x1
+#define BTN_VOL_DOWN 0x2
+#define BTN_VOL_UP 0x4
+
+uint32_t btn_read();
+uint32_t btn_wait();
+uint32_t btn_wait_timeout(uint32_t time_ms, uint32_t mask);
+
+#endif
\ No newline at end of file
diff --git a/fusee/fusee-primary/src/car.c b/fusee/fusee-primary/src/car.c
new file mode 100644
index 000000000..935dea922
--- /dev/null
+++ b/fusee/fusee-primary/src/car.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "car.h"
+#include "timers.h"
+#include "utils.h"
+
+static inline uint32_t get_clk_source_reg(CarDevice dev) {
+ switch (dev) {
+ case CARDEVICE_UARTA: return 0x178;
+ case CARDEVICE_UARTB: return 0x17C;
+ case CARDEVICE_UARTC: return 0x1A0;
+ case CARDEVICE_I2C1: return 0x124;
+ case CARDEVICE_I2C5: return 0x128;
+ case CARDEVICE_UNK: return 0;
+ case CARDEVICE_SE: return 0x42C;
+ case CARDEVICE_HOST1X: return 0x180;
+ case CARDEVICE_TSEC: return 0x1F4;
+ case CARDEVICE_SOR_SAFE: return 0;
+ case CARDEVICE_SOR0: return 0;
+ case CARDEVICE_SOR1: return 0x410;
+ case CARDEVICE_KFUSE: return 0;
+ case CARDEVICE_CL_DVFS: return 0;
+ case CARDEVICE_CORESIGHT: return 0x1D4;
+ case CARDEVICE_ACTMON: return 0x3E8;
+ case CARDEVICE_BPMP: return 0;
+ default: generic_panic();
+ }
+}
+
+static inline uint32_t get_clk_source_val(CarDevice dev) {
+ switch (dev) {
+ case CARDEVICE_UARTA: return 0;
+ case CARDEVICE_UARTB: return 0;
+ case CARDEVICE_UARTC: return 0;
+ case CARDEVICE_I2C1: return 6;
+ case CARDEVICE_I2C5: return 6;
+ case CARDEVICE_UNK: return 0;
+ case CARDEVICE_SE: return 0;
+ case CARDEVICE_HOST1X: return 4;
+ case CARDEVICE_TSEC: return 0;
+ case CARDEVICE_SOR_SAFE: return 0;
+ case CARDEVICE_SOR0: return 0;
+ case CARDEVICE_SOR1: return 0;
+ case CARDEVICE_KFUSE: return 0;
+ case CARDEVICE_CL_DVFS: return 0;
+ case CARDEVICE_CORESIGHT: return 0;
+ case CARDEVICE_ACTMON: return 6;
+ case CARDEVICE_BPMP: return 0;
+ default: generic_panic();
+ }
+}
+
+static inline uint32_t get_clk_source_div(CarDevice dev) {
+ switch (dev) {
+ case CARDEVICE_UARTA: return 0;
+ case CARDEVICE_UARTB: return 0;
+ case CARDEVICE_UARTC: return 0;
+ case CARDEVICE_I2C1: return 0;
+ case CARDEVICE_I2C5: return 0;
+ case CARDEVICE_UNK: return 0;
+ case CARDEVICE_SE: return 0;
+ case CARDEVICE_HOST1X: return 3;
+ case CARDEVICE_TSEC: return 2;
+ case CARDEVICE_SOR_SAFE: return 0;
+ case CARDEVICE_SOR0: return 0;
+ case CARDEVICE_SOR1: return 2;
+ case CARDEVICE_KFUSE: return 0;
+ case CARDEVICE_CL_DVFS: return 0;
+ case CARDEVICE_CORESIGHT: return 4;
+ case CARDEVICE_ACTMON: return 0;
+ case CARDEVICE_BPMP: return 0;
+ default: generic_panic();
+ }
+}
+
+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};
+
+void clk_enable(CarDevice dev) {
+ uint32_t clk_source_reg;
+ if ((clk_source_reg = get_clk_source_reg(dev))) {
+ MAKE_CAR_REG(clk_source_reg) = (get_clk_source_val(dev) << 29) | get_clk_source_div(dev);
+ }
+ MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
+}
+
+void clk_disable(CarDevice dev) {
+ MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
+}
+
+void rst_enable(CarDevice dev) {
+ MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
+}
+
+void rst_disable(CarDevice dev) {
+ MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
+}
+
+void clkrst_enable(CarDevice dev) {
+ clk_enable(dev);
+ rst_disable(dev);
+}
+
+void clkrst_disable(CarDevice dev) {
+ rst_enable(dev);
+ clk_disable(dev);
+}
+
+void clkrst_reboot(CarDevice dev) {
+ clkrst_disable(dev);
+ if (dev == CARDEVICE_KFUSE) {
+ /* Workaround for KFUSE clock. */
+ clk_enable(dev);
+ udelay(100);
+ rst_disable(dev);
+ udelay(200);
+ } else {
+ clkrst_enable(dev);
+ }
+}
+
+void clkrst_enable_fuse_regs(bool enable) {
+ volatile tegra_car_t *car = car_get_regs();
+ car->misc_clk_enb = ((car->misc_clk_enb & 0xEFFFFFFF) | ((enable & 1) << 28));
+}
diff --git a/fusee/fusee-primary/src/car.h b/fusee/fusee-primary/src/car.h
index 8cc0fb139..4135a54ef 100644
--- a/fusee/fusee-primary/src/car.h
+++ b/fusee/fusee-primary/src/car.h
@@ -1,121 +1,218 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_CAR_H
#define FUSEE_CAR_H
-#define CLK_SOURCE_SDMMC1 20
-#define CLK_SOURCE_SDMMC2 21
-#define CLK_SOURCE_SDMMC3 47
-#define CLK_SOURCE_SDMMC4 25
-#define CLK_SOURCE_SDMMC_LEGACY 0
+#include
+#include
+
+#define CAR_BASE 0x60006000
+#define MAKE_CAR_REG(n) MAKE_REG32(CAR_BASE + n)
#define CLK_L_SDMMC1 (1 << 14)
#define CLK_L_SDMMC2 (1 << 9)
#define CLK_U_SDMMC3 (1 << 5)
#define CLK_L_SDMMC4 (1 << 15)
-#define TEGRA_CLK_PLLS 6 /* Number of normal PLLs */
-#define TEGRA_CLK_SIMPLE_PLLS 3 /* Number of simple PLLs */
-#define TEGRA_CLK_SOURCES 64 /* Number of ppl clock sources L/H/U */
-#define TEGRA_CLK_SOURCES_VW 32 /* Number of ppl clock sources V/W */
-#define TEGRA_CLK_SOURCES_X 32 /* Number of ppl clock sources X */
-#define TEGRA_CLK_SOURCES_Y 18 /* Number of ppl clock sources Y */
-
#define CLK_SOURCE_MASK (0b111 << 29)
#define CLK_SOURCE_FIRST (0b000 << 29)
#define CLK_DIVIDER_MASK (0xff << 0)
#define CLK_DIVIDER_UNITY (0x00 << 0)
-#define CAR_CONTROL_SDMMC1 (1 << 14)
-#define CAR_CONTROL_SDMMC4 (1 << 15)
-#define CAR_CONTROL_SDMMC_LEGACY (1 << 1)
+#define NUM_CAR_BANKS 7
-/* PLL registers - there are several PLLs in the clock controller */
-typedef struct {
- uint32_t pll_base; /* the control register */
-
- /* pll_out[0] is output A control, pll_out[1] is output B control */
- uint32_t pll_out[2];
- uint32_t pll_misc; /* other misc things */
-} clk_pll_t;
-
-/* PLL registers - there are several PLLs in the clock controller */
-typedef struct {
- uint32_t pll_base; /* the control register */
- uint32_t pll_misc; /* other misc things */
-} clk_pll_simple_t;
-
-typedef struct {
- uint32_t pllm_base; /* the control register */
- uint32_t pllm_out; /* output control */
- uint32_t pllm_misc1; /* misc1 */
- uint32_t pllm_misc2; /* misc2 */
-} clk_pllm_t;
+/* Clock and reset devices. */
+typedef enum {
+ CARDEVICE_UARTA = ((0 << 5) | 0x6),
+ CARDEVICE_UARTB = ((0 << 5) | 0x7),
+ CARDEVICE_UARTC = ((1 << 5) | 0x17),
+ CARDEVICE_I2C1 = ((0 << 5) | 0xC),
+ CARDEVICE_I2C5 = ((1 << 5) | 0xF),
+ CARDEVICE_UNK = ((3 << 5) | 0x1E),
+ CARDEVICE_SE = ((3 << 5) | 0x1F),
+ CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
+ CARDEVICE_TSEC = ((2 << 5) | 0x13),
+ CARDEVICE_SOR_SAFE = ((6 << 5) | 0x1E),
+ CARDEVICE_SOR0 = ((5 << 5) | 0x16),
+ CARDEVICE_SOR1 = ((5 << 5) | 0x17),
+ CARDEVICE_KFUSE = ((1 << 5) | 0x8),
+ CARDEVICE_CL_DVFS = ((4 << 5) | 0x1B),
+ CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
+ CARDEVICE_ACTMON = ((3 << 5) | 0x17),
+ CARDEVICE_BPMP = ((0 << 5) | 0x1)
+} CarDevice;
/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
typedef struct {
- uint32_t rst_src; /* _RST_SOURCE_0,0x00 */
+ uint32_t rst_src; /* _RST_SOURCE_0, 0x00 */
+ /* _RST_DEVICES_L/H/U_0 0x4-0xc */
uint32_t rst_dev_l;
uint32_t rst_dev_h;
uint32_t rst_dev_u;
+ /* _CLK_OUT_ENB_L/H/U_0 0x10-0x18 */
uint32_t clk_out_enb_l;
uint32_t clk_out_enb_h;
uint32_t clk_out_enb_u;
- uint32_t reserved0; /* reserved_0, 0x1C */
- uint32_t cclk_brst_pol; /* _CCLK_BURST_POLICY_0, 0x20 */
- uint32_t super_cclk_div; /* _SUPER_CCLK_DIVIDER_0,0x24 */
- uint32_t sclk_brst_pol; /* _SCLK_BURST_POLICY_0, 0x28 */
- uint32_t super_sclk_div; /* _SUPER_SCLK_DIVIDER_0,0x2C */
- uint32_t clk_sys_rate; /* _CLK_SYSTEM_RATE_0, 0x30 */
- uint32_t prog_dly_clk; /* _PROG_DLY_CLK_0, 0x34 */
- uint32_t aud_sync_clk_rate; /* _AUDIO_SYNC_CLK_RATE_0,0x38 */
- uint32_t reserved1; /* reserved_1, 0x3C */
- uint32_t cop_clk_skip_plcy; /* _COP_CLK_SKIP_POLICY_0,0x40 */
- uint32_t clk_mask_arm; /* _CLK_MASK_ARM_0, 0x44 */
- uint32_t misc_clk_enb; /* _MISC_CLK_ENB_0, 0x48 */
- uint32_t clk_cpu_cmplx; /* _CLK_CPU_CMPLX_0, 0x4C */
- uint32_t osc_ctrl; /* _OSC_CTRL_0, 0x50 */
- uint32_t pll_lfsr; /* _PLL_LFSR_0, 0x54 */
- uint32_t osc_freq_det; /* _OSC_FREQ_DET_0, 0x58 */
- uint32_t osc_freq_det_stat; /* _OSC_FREQ_DET_STATUS_0,0x5C */
- uint32_t reserved2[8]; /* reserved_2[8], 0x60-7C */
+ uint32_t _0x1C;
+ uint32_t cclk_brst_pol; /* _CCLK_BURST_POLICY_0, 0x20 */
+ uint32_t super_cclk_div; /* _SUPER_CCLK_DIVIDER_0, 0x24 */
+ uint32_t sclk_brst_pol; /* _SCLK_BURST_POLICY_0, 0x28 */
+ uint32_t super_sclk_div; /* _SUPER_SCLK_DIVIDER_0, 0x2c */
+ uint32_t clk_sys_rate; /* _CLK_SYSTEM_RATE_0, 0x30 */
+ uint32_t prog_dly_clk; /* _PROG_DLY_CLK_0, 0x34 */
+ uint32_t aud_sync_clk_rate; /* _AUDIO_SYNC_CLK_RATE_0, 0x38 */
+ uint32_t _0x3C;
+ uint32_t cop_clk_skip_plcy; /* _COP_CLK_SKIP_POLICY_0, 0x40 */
+ uint32_t clk_mask_arm; /* _CLK_MASK_ARM_0, 0x44 */
+ uint32_t misc_clk_enb; /* _MISC_CLK_ENB_0, 0x48 */
+ uint32_t clk_cpu_cmplx; /* _CLK_CPU_CMPLX_0, 0x4c */
+ uint32_t osc_ctrl; /* _OSC_CTRL_0, 0x50 */
+ uint32_t pll_lfsr; /* _PLL_LFSR_0, 0x54 */
+ uint32_t osc_freq_det; /* _OSC_FREQ_DET_0, 0x58 */
+ uint32_t osc_freq_det_stat; /* _OSC_FREQ_DET_STATUS_0, 0x5c */
+ uint32_t _0x60[2];
+ uint32_t plle_ss_cntl; /* _PLLE_SS_CNTL_0, 0x68 */
+ uint32_t plle_misc1; /* _PLLE_MISC1_0, 0x6c */
+ uint32_t _0x70[4];
- clk_pll_t pll[TEGRA_CLK_PLLS]; /* PLLs from 0x80 to 0xdc */
+ /* PLLC 0x80-0x8c */
+ uint32_t pllc_base;
+ uint32_t pllc_out;
+ uint32_t pllc_misc0;
+ uint32_t pllc_misc1;
+
+ /* PLLM 0x90-0x9c */
+ uint32_t pllm_base;
+ uint32_t pllm_out;
+ uint32_t pllm_misc1;
+ uint32_t pllm_misc2;
+
+ /* PLLP 0xa0-0xac */
+ uint32_t pllp_base;
+ uint32_t pllp_outa;
+ uint32_t pllp_outb;
+ uint32_t pllp_misc;
+
+ /* PLLA 0xb0-0xbc */
+ uint32_t plla_base;
+ uint32_t plla_out;
+ uint32_t plla_misc0;
+ uint32_t plla_misc1;
+
+ /* PLLU 0xc0-0xcc */
+ uint32_t pllu_base;
+ uint32_t pllu_out;
+ uint32_t pllu_misc1;
+ uint32_t pllu_misc2;
+
+ /* PLLD 0xd0-0xdc */
+ uint32_t plld_base;
+ uint32_t plld_out;
+ uint32_t plld_misc1;
+ uint32_t plld_misc2;
- /* PLLs from 0xe0 to 0xf4 */
- clk_pll_simple_t pll_simple[TEGRA_CLK_SIMPLE_PLLS];
+ /* PLLX 0xe0-0xe4 */
+ uint32_t pllx_base;
+ uint32_t pllx_misc;
+
+ /* PLLE 0xe8-0xf4 */
+ uint32_t plle_base;
+ uint32_t plle_misc;
+ uint32_t plle_ss_cntl1;
+ uint32_t plle_ss_cntl2;
+
+ uint32_t lvl2_clk_gate_ovra; /* _LVL2_CLK_GATE_OVRA_0, 0xf8 */
+ uint32_t lvl2_clk_gate_ovrb; /* _LVL2_CLK_GATE_OVRB_0, 0xfc */
- uint32_t reserved10; /* _reserved_10, 0xF8 */
- uint32_t reserved11; /* _reserved_11, 0xFC */
+ uint32_t clk_source_i2s2; /* _CLK_SOURCE_I2S2_0, 0x100 */
+ uint32_t clk_source_i2s3; /* _CLK_SOURCE_I2S3_0, 0x104 */
+ uint32_t clk_source_spdif_out; /* _CLK_SOURCE_SPDIF_OUT_0, 0x108 */
+ uint32_t clk_source_spdif_in; /* _CLK_SOURCE_SPDIF_IN_0, 0x10c */
+ uint32_t clk_source_pwm; /* _CLK_SOURCE_PWM_0, 0x110 */
+ uint32_t _0x114;
+ uint32_t clk_source_spi2; /* _CLK_SOURCE_SPI2_0, 0x118 */
+ uint32_t clk_source_spi3; /* _CLK_SOURCE_SPI3_0, 0x11c */
+ uint32_t _0x120;
+ uint32_t clk_source_i2c1; /* _CLK_SOURCE_I2C1_0, 0x124 */
+ uint32_t clk_source_i2c5; /* _CLK_SOURCE_I2C5_0, 0x128 */
+ uint32_t _0x12c[2];
+ uint32_t clk_source_spi1; /* _CLK_SOURCE_SPI1_0, 0x134 */
+ uint32_t clk_source_disp1; /* _CLK_SOURCE_DISP1_0, 0x138 */
+ uint32_t clk_source_disp2; /* _CLK_SOURCE_DISP2_0, 0x13c */
+ uint32_t _0x140;
+ uint32_t clk_source_isp; /* _CLK_SOURCE_ISP_0, 0x144 */
+ uint32_t clk_source_vi; /* _CLK_SOURCE_VI_0, 0x148 */
+ uint32_t _0x14c;
+ uint32_t clk_source_sdmmc1; /* _CLK_SOURCE_SDMMC1_0, 0x150 */
+ uint32_t clk_source_sdmmc2; /* _CLK_SOURCE_SDMMC2_0, 0x154 */
+ uint32_t _0x158[3];
+ uint32_t clk_source_sdmmc4; /* _CLK_SOURCE_SDMMC4_0, 0x164 */
+ uint32_t _0x168[4];
+ uint32_t clk_source_uarta; /* _CLK_SOURCE_UARTA_0, 0x178 */
+ uint32_t clk_source_uartb; /* _CLK_SOURCE_UARTB_0, 0x17c */
+ uint32_t clk_source_host1x; /* _CLK_SOURCE_HOST1X_0, 0x180 */
+ uint32_t _0x184[5];
+ uint32_t clk_source_i2c2; /* _CLK_SOURCE_I2C2_0, 0x198 */
+ uint32_t clk_source_emc; /* _CLK_SOURCE_EMC_0, 0x19c */
+ uint32_t clk_source_uartc; /* _CLK_SOURCE_UARTC_0, 0x1a0 */
+ uint32_t _0x1a4;
+ uint32_t clk_source_vi_sensor; /* _CLK_SOURCE_VI_SENSOR_0, 0x1a8 */
+ uint32_t _0x1ac[2];
+ uint32_t clk_source_spi4; /* _CLK_SOURCE_SPI4_0, 0x1b4 */
+ uint32_t clk_source_i2c3; /* _CLK_SOURCE_I2C3_0, 0x1b8 */
+ uint32_t clk_source_sdmmc3; /* _CLK_SOURCE_SDMMC3_0, 0x1bc */
+ uint32_t clk_source_uartd; /* _CLK_SOURCE_UARTD_0, 0x1c0 */
+ uint32_t _0x1c4[2];
+ uint32_t clk_source_owr; /* _CLK_SOURCE_OWR_0, 0x1cc */
+ uint32_t _0x1d0;
+ uint32_t clk_source_csite; /* _CLK_SOURCE_CSITE_0, 0x1d4 */
+ uint32_t clk_source_i2s1; /* _CLK_SOURCE_I2S1_0, 0x1d8 */
+ uint32_t clk_source_dtv; /* _CLK_SOURCE_DTV_0, 0x1dc */
+ uint32_t _0x1e0[5];
+ uint32_t clk_source_tsec; /* _CLK_SOURCE_TSEC_0, 0x1f4 */
+ uint32_t _0x1f8;
+
+ uint32_t clk_spare2; /* _CLK_SPARE2_0, 0x1fc */
+ uint32_t _0x200[32];
- uint32_t clk_src[TEGRA_CLK_SOURCES]; /*_I2S1_0... 0x100-1fc */
+ uint32_t clk_out_enb_x; /* _CLK_OUT_ENB_X_0, 0x280 */
+ uint32_t clk_enb_x_set; /* _CLK_ENB_X_SET_0, 0x284 */
+ uint32_t clk_enb_x_clr; /* _CLK_ENB_X_CLR_0, 0x288 */
- uint32_t reserved20[32]; /* _reserved_20, 0x200-27c */
+ uint32_t rst_devices_x; /* _RST_DEVICES_X_0, 0x28c */
+ uint32_t rst_dev_x_set; /* _RST_DEV_X_SET_0, 0x290 */
+ uint32_t rst_dev_x_clr; /* _RST_DEV_X_CLR_0, 0x294 */
- uint32_t clk_out_enb_x; /* _CLK_OUT_ENB_X_0, 0x280 */
- uint32_t clk_enb_x_set; /* _CLK_ENB_X_SET_0, 0x284 */
- uint32_t clk_enb_x_clr; /* _CLK_ENB_X_CLR_0, 0x288 */
+ uint32_t clk_out_enb_y; /* _CLK_OUT_ENB_Y_0, 0x298 */
+ uint32_t clk_enb_y_set; /* _CLK_ENB_Y_SET_0, 0x29c */
+ uint32_t clk_enb_y_clr; /* _CLK_ENB_Y_CLR_0, 0x2a0 */
- uint32_t rst_devices_x; /* _RST_DEVICES_X_0, 0x28c */
- uint32_t rst_dev_x_set; /* _RST_DEV_X_SET_0, 0x290 */
- uint32_t rst_dev_x_clr; /* _RST_DEV_X_CLR_0, 0x294 */
+ uint32_t rst_devices_y; /* _RST_DEVICES_Y_0, 0x2a4 */
+ uint32_t rst_dev_y_set; /* _RST_DEV_Y_SET_0, 0x2a8 */
+ uint32_t rst_dev_y_clr; /* _RST_DEV_Y_CLR_0, 0x2ac */
- uint32_t clk_out_enb_y; /* _CLK_OUT_ENB_Y_0, 0x298 */
- uint32_t clk_enb_y_set; /* _CLK_ENB_Y_SET_0, 0x29c */
- uint32_t clk_enb_y_clr; /* _CLK_ENB_Y_CLR_0, 0x2a0 */
+ uint32_t _0x2b0[17];
+ uint32_t dfll_base; /* _DFLL_BASE_0, 0x2f4 */
+ uint32_t _0x2f8[2];
- uint32_t rst_devices_y; /* _RST_DEVICES_Y_0, 0x2a4 */
- uint32_t rst_dev_y_set; /* _RST_DEV_Y_SET_0, 0x2a8 */
- uint32_t rst_dev_y_clr; /* _RST_DEV_Y_CLR_0, 0x2ac */
-
- uint32_t reserved21[17]; /* _reserved_21, 0x2b0-2f0 */
-
- uint32_t dfll_base; /* _DFLL_BASE_0, 0x2f4 */
-
- uint32_t reserved22[2]; /* _reserved_22, 0x2f8-2fc */
-
- /* _RST_DEV_L/H/U_SET_0 0x300 ~ 0x314 */
+ /* _RST_DEV_L/H/U_SET_0 0x300-0x314 */
uint32_t rst_dev_l_set;
uint32_t rst_dev_l_clr;
uint32_t rst_dev_h_set;
@@ -123,9 +220,9 @@ typedef struct {
uint32_t rst_dev_u_set;
uint32_t rst_dev_u_clr;
- uint32_t reserved30[2]; /* _reserved_30, 0x318, 0x31c */
+ uint32_t _0x318[2];
- /* _CLK_ENB_L/H/U_CLR_0 0x320 ~ 0x334 */
+ /* _CLK_ENB_L/H/U_CLR_0 0x320-0x334 */
uint32_t clk_enb_l_set;
uint32_t clk_enb_l_clr;
uint32_t clk_enb_h_set;
@@ -133,136 +230,276 @@ typedef struct {
uint32_t clk_enb_u_set;
uint32_t clk_enb_u_clr;
- uint32_t reserved31[2]; /* _reserved_31, 0x338, 0x33c */
-
- uint32_t cpu_cmplx_set; /* _RST_CPU_CMPLX_SET_0, 0x340 */
- uint32_t cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR_0, 0x344 */
+ uint32_t _0x338;
+ uint32_t ccplex_pg_sm_ovrd; /* _CCPLEX_PG_SM_OVRD_0, 0x33c */
+ uint32_t rst_cpu_cmplx_set; /* _RST_CPU_CMPLX_SET_0, 0x340 */
+ uint32_t rst_cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR_0, 0x344 */
/* Additional (T30) registers */
- uint32_t clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET_0, 0x348 */
- uint32_t clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET_0, 0x34c */
+ uint32_t clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET_0, 0x348 */
+ uint32_t clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET_0, 0x34c */
- uint32_t reserved32[2]; /* _reserved_32, 0x350,0x354 */
+ uint32_t _0x350[2];
+ uint32_t rst_dev_v; /* _RST_DEVICES_V_0, 0x358 */
+ uint32_t rst_dev_w; /* _RST_DEVICES_W_0, 0x35c */
+ uint32_t clk_out_enb_v; /* _CLK_OUT_ENB_V_0, 0x360 */
+ uint32_t clk_out_enb_w; /* _CLK_OUT_ENB_W_0, 0x364 */
+ uint32_t cclkg_brst_pol; /* _CCLKG_BURST_POLICY_0, 0x368 */
+ uint32_t super_cclkg_div; /* _SUPER_CCLKG_DIVIDER_0, 0x36c */
+ uint32_t cclklp_brst_pol; /* _CCLKLP_BURST_POLICY_0, 0x370 */
+ uint32_t super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER_0, 0x374 */
+ uint32_t clk_cpug_cmplx; /* _CLK_CPUG_CMPLX_0, 0x378 */
+ uint32_t clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX_0, 0x37c */
+ uint32_t cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL_0, 0x380 */
+ uint32_t cpu_softrst_ctrl1; /* _CPU_SOFTRST_CTRL1_0, 0x384 */
+ uint32_t cpu_softrst_ctrl2; /* _CPU_SOFTRST_CTRL2_0, 0x388 */
+ uint32_t _0x38c[5];
+ uint32_t lvl2_clk_gate_ovrc; /* _LVL2_CLK_GATE_OVRC, 0x3a0 */
+ uint32_t lvl2_clk_gate_ovrd; /* _LVL2_CLK_GATE_OVRD, 0x3a4 */
+ uint32_t _0x3a8[2];
+
+ uint32_t _0x3b0;
+ uint32_t clk_source_mselect; /* _CLK_SOURCE_MSELECT_0, 0x3b4 */
+ uint32_t clk_source_tsensor; /* _CLK_SOURCE_TSENSOR_0, 0x3b8 */
+ uint32_t clk_source_i2s4; /* _CLK_SOURCE_I2S4_0, 0x3bc */
+ uint32_t clk_source_i2s5; /* _CLK_SOURCE_I2S5_0, 0x3c0 */
+ uint32_t clk_source_i2c4; /* _CLK_SOURCE_I2C4_0, 0x3c4 */
+ uint32_t _0x3c8[2];
+ uint32_t clk_source_ahub; /* _CLK_SOURCE_AHUB_0, 0x3d0 */
+ uint32_t _0x3d4[4];
+ uint32_t clk_source_hda2codec_2x; /* _CLK_SOURCE_HDA2CODEC_2X_0, 0x3e4 */
+ uint32_t clk_source_actmon; /* _CLK_SOURCE_ACTMON_0, 0x3e8 */
+ uint32_t clk_source_extperiph1; /* _CLK_SOURCE_EXTPERIPH1_0, 0x3ec */
+ uint32_t clk_source_extperiph2; /* _CLK_SOURCE_EXTPERIPH2_0, 0x3f0 */
+ uint32_t clk_source_extperiph3; /* _CLK_SOURCE_EXTPERIPH3_0, 0x3f4 */
+ uint32_t _0x3f8;
+ uint32_t clk_source_i2c_slow; /* _CLK_SOURCE_I2C_SLOW_0, 0x3fc */
+ uint32_t clk_source_sys; /* _CLK_SOURCE_SYS_0, 0x400 */
+ uint32_t clk_source_ispb; /* _CLK_SOURCE_ISPB_0, 0x404 */
+ uint32_t _0x408[2];
+ uint32_t clk_source_sor1; /* _CLK_SOURCE_SOR1_0, 0x410 */
+ uint32_t clk_source_sor0; /* _CLK_SOURCE_SOR0_0, 0x414 */
+ uint32_t _0x418[2];
+ uint32_t clk_source_sata_oob; /* _CLK_SOURCE_SATA_OOB_0, 0x420 */
+ uint32_t clk_source_sata; /* _CLK_SOURCE_SATA_0, 0x424 */
+ uint32_t clk_source_hda; /* _CLK_SOURCE_HDA_0, 0x428 */
+ uint32_t _0x42c;
- uint32_t rst_dev_v; /* _RST_DEVICES_V/W_0 */
- uint32_t rst_dev_w; /* _RST_DEVICES_V/W_0 */
-
- uint32_t clk_out_enb_v; /* _CLK_OUT_ENB_V/W_0 */
- uint32_t clk_out_enb_w; /* _CLK_OUT_ENB_V/W_0 */
- uint32_t cclkg_brst_pol; /* _CCLKG_BURST_POLICY_0, 0x368 */
- uint32_t super_cclkg_div; /* _SUPER_CCLKG_DIVIDER_0, 0x36C */
- uint32_t cclklp_brst_pol; /* _CCLKLP_BURST_POLICY_0, 0x370 */
- uint32_t super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER_0, 0x374 */
- uint32_t clk_cpug_cmplx; /* _CLK_CPUG_CMPLX_0, 0x378 */
- uint32_t clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX_0, 0x37C */
- uint32_t cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL_0, 0x380 */
- uint32_t cpu_softrst_ctrl1; /* _CPU_SOFTRST_CTRL1_0, 0x384 */
- uint32_t cpu_softrst_ctrl2; /* _CPU_SOFTRST_CTRL2_0, 0x388 */
- uint32_t reserved33[9]; /* _reserved_33, 0x38c-3ac */
- uint32_t clk_src_v; /* 0x3B0-0x42C */
- uint32_t clk_src_w; /* 0x3B0-0x42C */
-
- /* _RST_DEV_V/W_SET_0 0x430 ~ 0x43c */
+ /* _RST_DEV_V/W_SET_0 0x430-0x43c */
uint32_t rst_dev_v_set;
uint32_t rst_dev_v_clr;
uint32_t rst_dev_w_set;
uint32_t rst_dev_w_clr;
- /* _CLK_ENB_V/W_CLR_0 0x440 ~ 0x44c */
- uint32_t rst_clk_v_set;
- uint32_t rst_clk_v_clr;
- uint32_t rst_clk_w_set;
- uint32_t rst_clk_w_clr;
+ /* _CLK_ENB_V/W_CLR_0 0x440-0x44c */
+ uint32_t clk_enb_v_set;
+ uint32_t clk_enb_v_clr;
+ uint32_t clk_enb_w_set;
+ uint32_t clk_enb_w_clr;
/* Additional (T114+) registers */
- uint32_t rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET_0, 0x450 */
- uint32_t rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR_0, 0x454 */
- uint32_t rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET_0, 0x458 */
- uint32_t rst_cpulp_cmplx_clr; /* _RST_CPULP_CMPLX_CLR_0, 0x45C */
- uint32_t clk_cpug_cmplx_set; /* _CLK_CPUG_CMPLX_SET_0, 0x460 */
- uint32_t clk_cpug_cmplx_clr; /* _CLK_CPUG_CMPLX_CLR_0, 0x464 */
- uint32_t clk_cpulp_cmplx_set; /* _CLK_CPULP_CMPLX_SET_0, 0x468 */
- uint32_t clk_cpulp_cmplx_clr; /* _CLK_CPULP_CMPLX_CLR_0, 0x46C */
- uint32_t cpu_cmplx_status; /* _CPU_CMPLX_STATUS_0, 0x470 */
- uint32_t reserved40[1]; /* _reserved_40, 0x474 */
- uint32_t intstatus; /* __INTSTATUS_0, 0x478 */
- uint32_t intmask; /* __INTMASK_0, 0x47C */
- uint32_t utmip_pll_cfg0; /* _UTMIP_PLL_CFG0_0, 0x480 */
- uint32_t utmip_pll_cfg1; /* _UTMIP_PLL_CFG1_0, 0x484 */
- uint32_t utmip_pll_cfg2; /* _UTMIP_PLL_CFG2_0, 0x488 */
+ uint32_t rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET_0, 0x450 */
+ uint32_t rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR_0, 0x454 */
+ uint32_t rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET_0, 0x458 */
+ uint32_t rst_cpulp_cmplx_clr; /* _RST_CPULP_CMPLX_CLR_0, 0x45c */
+ uint32_t clk_cpug_cmplx_set; /* _CLK_CPUG_CMPLX_SET_0, 0x460 */
+ uint32_t clk_cpug_cmplx_clr; /* _CLK_CPUG_CMPLX_CLR_0, 0x464 */
+ uint32_t clk_cpulp_cmplx_set; /* _CLK_CPULP_CMPLX_SET_0, 0x468 */
+ uint32_t clk_cpulp_cmplx_clr; /* _CLK_CPULP_CMPLX_CLR_0, 0x46c */
+ uint32_t cpu_cmplx_status; /* _CPU_CMPLX_STATUS_0, 0x470 */
+ uint32_t _0x474;
+ uint32_t intstatus; /* _INTSTATUS_0, 0x478 */
+ uint32_t intmask; /* _INTMASK_0, 0x47c */
+ uint32_t utmip_pll_cfg0; /* _UTMIP_PLL_CFG0_0, 0x480 */
+ uint32_t utmip_pll_cfg1; /* _UTMIP_PLL_CFG1_0, 0x484 */
+ uint32_t utmip_pll_cfg2; /* _UTMIP_PLL_CFG2_0, 0x488 */
- uint32_t plle_aux; /* _PLLE_AUX_0, 0x48C */
- uint32_t sata_pll_cfg0; /* _SATA_PLL_CFG0_0, 0x490 */
- uint32_t sata_pll_cfg1; /* _SATA_PLL_CFG1_0, 0x494 */
- uint32_t pcie_pll_cfg0; /* _PCIE_PLL_CFG0_0, 0x498 */
+ uint32_t plle_aux; /* _PLLE_AUX_0, 0x48c */
+ uint32_t sata_pll_cfg0; /* _SATA_PLL_CFG0_0, 0x490 */
+ uint32_t sata_pll_cfg1; /* _SATA_PLL_CFG1_0, 0x494 */
+ uint32_t pcie_pll_cfg0; /* _PCIE_PLL_CFG0_0, 0x498 */
- uint32_t prog_audio_dly_clk; /* _PROG_AUDIO_DLY_CLK_0, 0x49C */
- uint32_t audio_sync_clk_i2s0; /* _AUDIO_SYNC_CLK_I2S0_0, 0x4A0 */
- uint32_t audio_sync_clk_i2s1; /* _AUDIO_SYNC_CLK_I2S1_0, 0x4A4 */
- uint32_t audio_sync_clk_i2s2; /* _AUDIO_SYNC_CLK_I2S2_0, 0x4A8 */
- uint32_t audio_sync_clk_i2s3; /* _AUDIO_SYNC_CLK_I2S3_0, 0x4AC */
- uint32_t audio_sync_clk_i2s4; /* _AUDIO_SYNC_CLK_I2S4_0, 0x4B0 */
- uint32_t audio_sync_clk_spdif; /* _AUDIO_SYNC_CLK_SPDIF_0, 0x4B4 */
+ uint32_t prog_audio_dly_clk; /* _PROG_AUDIO_DLY_CLK_0, 0x49c */
+ uint32_t audio_sync_clk_i2s0; /* _AUDIO_SYNC_CLK_I2S0_0, 0x4a0 */
+ uint32_t audio_sync_clk_i2s1; /* _AUDIO_SYNC_CLK_I2S1_0, 0x4a4 */
+ uint32_t audio_sync_clk_i2s2; /* _AUDIO_SYNC_CLK_I2S2_0, 0x4a8 */
+ uint32_t audio_sync_clk_i2s3; /* _AUDIO_SYNC_CLK_I2S3_0, 0x4ac */
+ uint32_t audio_sync_clk_i2s4; /* _AUDIO_SYNC_CLK_I2S4_0, 0x4b0 */
+ uint32_t audio_sync_clk_spdif; /* _AUDIO_SYNC_CLK_SPDIF_0, 0x4b4 */
- uint32_t plld2_base; /* _PLLD2_BASE_0, 0x4B8 */
- uint32_t plld2_misc; /* _PLLD2_MISC_0, 0x4BC */
- uint32_t utmip_pll_cfg3; /* _UTMIP_PLL_CFG3_0, 0x4C0 */
- uint32_t pllrefe_base; /* _PLLREFE_BASE_0, 0x4C4 */
- uint32_t pllrefe_misc; /* _PLLREFE_MISC_0, 0x4C8 */
- uint32_t crs_reserved_50[7]; /* _reserved_50, 0x4CC-0x4E4 */
- uint32_t pllc2_base; /* _PLLC2_BASE_0, 0x4E8 */
- uint32_t pllc2_misc0; /* _PLLC2_MISC_0_0, 0x4EC */
- uint32_t pllc2_misc1; /* _PLLC2_MISC_1_0, 0x4F0 */
- uint32_t pllc2_misc2; /* _PLLC2_MISC_2_0, 0x4F4 */
- uint32_t pllc2_misc3; /* _PLLC2_MISC_3_0, 0x4F8 */
- uint32_t pllc3_base; /* _PLLC3_BASE_0, 0x4FC */
+ uint32_t plld2_base; /* _PLLD2_BASE_0, 0x4b8 */
+ uint32_t plld2_misc; /* _PLLD2_MISC_0, 0x4bc */
+ uint32_t utmip_pll_cfg3; /* _UTMIP_PLL_CFG3_0, 0x4c0 */
+ uint32_t pllrefe_base; /* _PLLREFE_BASE_0, 0x4c4 */
+ uint32_t pllrefe_misc; /* _PLLREFE_MISC_0, 0x4c8 */
+ uint32_t pllrefe_out; /* _PLLREFE_OUT_0, 0x4cc */
+ uint32_t cpu_finetrim_byp; /* _CPU_FINETRIM_BYP_0, 0x4d0 */
+ uint32_t cpu_finetrim_select; /* _CPU_FINETRIM_SELECT_0, 0x4d4 */
+ uint32_t cpu_finetrim_dr; /* _CPU_FINETRIM_DR_0, 0x4d8 */
+ uint32_t cpu_finetrim_df; /* _CPU_FINETRIM_DF_0, 0x4dc */
+ uint32_t cpu_finetrim_f; /* _CPU_FINETRIM_F_0, 0x4e0 */
+ uint32_t cpu_finetrim_r; /* _CPU_FINETRIM_R_0, 0x4e4 */
+ uint32_t pllc2_base; /* _PLLC2_BASE_0, 0x4e8 */
+ uint32_t pllc2_misc0; /* _PLLC2_MISC_0_0, 0x4ec */
+ uint32_t pllc2_misc1; /* _PLLC2_MISC_1_0, 0x4f0 */
+ uint32_t pllc2_misc2; /* _PLLC2_MISC_2_0, 0x4f4 */
+ uint32_t pllc2_misc3; /* _PLLC2_MISC_3_0, 0x4f8 */
+ uint32_t pllc3_base; /* _PLLC3_BASE_0, 0x4fc */
uint32_t pllc3_misc0; /* _PLLC3_MISC_0_0, 0x500 */
uint32_t pllc3_misc1; /* _PLLC3_MISC_1_0, 0x504 */
uint32_t pllc3_misc2; /* _PLLC3_MISC_2_0, 0x508 */
- uint32_t pllc3_misc3; /* _PLLC3_MISC_3_0, 0x50C */
+ uint32_t pllc3_misc3; /* _PLLC3_MISC_3_0, 0x50c */
uint32_t pllx_misc1; /* _PLLX_MISC_1_0, 0x510 */
uint32_t pllx_misc2; /* _PLLX_MISC_2_0, 0x514 */
uint32_t pllx_misc3; /* _PLLX_MISC_3_0, 0x518 */
- uint32_t xusbio_pll_cfg0; /* _XUSBIO_PLL_CFG0_0, 0x51C */
+ uint32_t xusbio_pll_cfg0; /* _XUSBIO_PLL_CFG0_0, 0x51c */
uint32_t xusbio_pll_cfg1; /* _XUSBIO_PLL_CFG0_1, 0x520 */
uint32_t plle_aux1; /* _PLLE_AUX1_0, 0x524 */
uint32_t pllp_reshift; /* _PLLP_RESHIFT_0, 0x528 */
- uint32_t utmipll_hw_pwrdn_cfg0; /* _UTMIPLL_HW_PWRDN_CFG0_0, 0x52C */
+ uint32_t utmipll_hw_pwrdn_cfg0; /* _UTMIPLL_HW_PWRDN_CFG0_0, 0x52c */
uint32_t pllu_hw_pwrdn_cfg0; /* _PLLU_HW_PWRDN_CFG0_0, 0x530 */
uint32_t xusb_pll_cfg0; /* _XUSB_PLL_CFG0_0, 0x534 */
- uint32_t reserved51[1]; /* _reserved_51, 0x538 */
- uint32_t clk_cpu_misc; /* _CLK_CPU_MISC_0, 0x53C */
+ uint32_t _0x538;
+ uint32_t clk_cpu_misc; /* _CLK_CPU_MISC_0, 0x53c */
uint32_t clk_cpug_misc; /* _CLK_CPUG_MISC_0, 0x540 */
uint32_t clk_cpulp_misc; /* _CLK_CPULP_MISC_0, 0x544 */
uint32_t pllx_hw_ctrl_cfg; /* _PLLX_HW_CTRL_CFG_0, 0x548 */
- uint32_t pllx_sw_ramp_cfg; /* _PLLX_SW_RAMP_CFG_0, 0x54C */
+ uint32_t pllx_sw_ramp_cfg; /* _PLLX_SW_RAMP_CFG_0, 0x54c */
uint32_t pllx_hw_ctrl_status; /* _PLLX_HW_CTRL_STATUS_0, 0x550 */
- uint32_t reserved52[1]; /* _reserved_52, 0x554 */
+ uint32_t lvl2_clk_gate_ovre; /* _LVL2_CLK_GATE_OVRE, 0x554 */
uint32_t super_gr3d_clk_div; /* _SUPER_GR3D_CLK_DIVIDER_0, 0x558 */
- uint32_t spare_reg0; /* _SPARE_REG0_0, 0x55C */
- uint32_t _rsv32[4]; /* 0x560-0x56c */
- uint32_t plld2_ss_cfg; /* _PLLD2_SS_CFG 0x570 */
- uint32_t _rsv32_1[7]; /* 0x574-58c */
- clk_pll_simple_t plldp; /* _PLLDP_BASE, 0x590 _PLLDP_MISC */
- uint32_t plldp_ss_cfg; /* _PLLDP_SS_CFG, 0x598 */
-
- /* Tegra124+ - skip to 0x600 here for new CLK_SOURCE_ regs */
- uint32_t _rsrv32_2[25]; /* _0x59C - 0x5FC */
- uint32_t clk_src_x[TEGRA_CLK_SOURCES_X]; /* XUSB, etc, 0x600-0x67C */
-
- /* Tegra210 - skip to 0x694 here for new CLK_SOURCE_ regs */
- uint32_t reserved61[5]; /* _reserved_61, 0x680 - 0x690 */
+ uint32_t spare_reg0; /* _SPARE_REG0_0, 0x55c */
+ uint32_t audio_sync_clk_dmic1; /* _AUDIO_SYNC_CLK_DMIC1_0, 0x560 */
+ uint32_t audio_sync_clk_dmic2; /* _AUDIO_SYNC_CLK_DMIC2_0, 0x564 */
- /*
- * NOTE: PLLA1 regs are in the middle of this Y region. Break this in
- * two later if PLLA1 is needed, but for now this is cleaner.
- */
- uint32_t clk_src_y[TEGRA_CLK_SOURCES_Y]; /* SPARE1, etc, 0x694-0x6D8 */
+ uint32_t _0x568[2];
+ uint32_t plld2_ss_cfg; /* _PLLD2_SS_CFG, 0x570 */
+ uint32_t plld2_ss_ctrl1; /* _PLLD2_SS_CTRL1_0, 0x574 */
+ uint32_t plld2_ss_ctrl2; /* _PLLD2_SS_CTRL2_0, 0x578 */
+ uint32_t _0x57c[5];
+
+ uint32_t plldp_base; /* _PLLDP_BASE, 0x590*/
+ uint32_t plldp_misc; /* _PLLDP_MISC, 0x594 */
+ uint32_t plldp_ss_cfg; /* _PLLDP_SS_CFG, 0x598 */
+ uint32_t plldp_ss_ctrl1; /* _PLLDP_SS_CTRL1_0, 0x59c */
+ uint32_t plldp_ss_ctrl2; /* _PLLDP_SS_CTRL2_0, 0x5a0 */
+ uint32_t pllc4_base; /* _PLLC4_BASE_0, 0x5a4 */
+ uint32_t pllc4_misc; /* _PLLC4_MISC_0, 0x5a8 */
+ uint32_t _0x5ac[6];
+ uint32_t clk_spare0; /* _CLK_SPARE0_0, 0x5c4 */
+ uint32_t clk_spare1; /* _CLK_SPARE1_0, 0x5c8 */
+ uint32_t gpu_isob_ctrl; /* _GPU_ISOB_CTRL_0, 0x5cc */
+ uint32_t pllc_misc2; /* _PLLC_MISC_2_0, 0x5d0 */
+ uint32_t pllc_misc3; /* _PLLC_MISC_3_0, 0x5d4 */
+ uint32_t plla_misc2; /* _PLLA_MISC2_0, 0x5d8 */
+ uint32_t _0x5dc[2];
+ uint32_t pllc4_out; /* _PLLC4_OUT_0, 0x5e4 */
+ uint32_t pllmb_base; /* _PLLMB_BASE_0, 0x5e8 */
+ uint32_t pllmb_misc1; /* _PLLMB_MISC1_0, 0x5ec */
+ uint32_t pllx_misc4; /* _PLLX_MISC_4_0, 0x5f0 */
+ uint32_t pllx_misc5; /* _PLLX_MISC_5_0, 0x5f4 */
+ uint32_t _0x5f8[2];
+
+ uint32_t clk_source_xusb_core_host; /* _CLK_SOURCE_XUSB_CORE_HOST_0, 0x600 */
+ uint32_t clk_source_xusb_falcon; /* _CLK_SOURCE_XUSB_FALCON_0, 0x604 */
+ uint32_t clk_source_xusb_fs; /* _CLK_SOURCE_XUSB_FS_0, 0x608 */
+ uint32_t clk_source_xusb_core_dev; /* _CLK_SOURCE_XUSB_CORE_DEV_0, 0x60c */
+ uint32_t clk_source_xusb_ss; /* _CLK_SOURCE_XUSB_SS_0, 0x610 */
+ uint32_t clk_source_cilab; /* _CLK_SOURCE_CILAB_0, 0x614 */
+ uint32_t clk_source_cilcd; /* _CLK_SOURCE_CILCD_0, 0x618 */
+ uint32_t clk_source_cilef; /* _CLK_SOURCE_CILEF_0, 0x61c */
+ uint32_t clk_source_dsia_lp; /* _CLK_SOURCE_DSIA_LP_0, 0x620 */
+ uint32_t clk_source_dsib_lp; /* _CLK_SOURCE_DSIB_LP_0, 0x624 */
+ uint32_t clk_source_entropy; /* _CLK_SOURCE_ENTROPY_0, 0x628 */
+ uint32_t clk_source_dvfs_ref; /* _CLK_SOURCE_DVFS_REF_0, 0x62c */
+ uint32_t clk_source_dvfs_soc; /* _CLK_SOURCE_DVFS_SOC_0, 0x630 */
+ uint32_t _0x634[3];
+ uint32_t clk_source_emc_latency; /* _CLK_SOURCE_EMC_LATENCY_0, 0x640 */
+ uint32_t clk_source_soc_therm; /* _CLK_SOURCE_SOC_THERM_0, 0x644 */
+ uint32_t _0x648;
+ uint32_t clk_source_dmic1; /* _CLK_SOURCE_DMIC1_0, 0x64c */
+ uint32_t clk_source_dmic2; /* _CLK_SOURCE_DMIC2_0, 0x650 */
+ uint32_t _0x654;
+ uint32_t clk_source_vi_sensor2; /* _CLK_SOURCE_VI_SENSOR2_0, 0x658 */
+ uint32_t clk_source_i2c6; /* _CLK_SOURCE_I2C6_0, 0x65c */
+ uint32_t clk_source_mipibif; /* _CLK_SOURCE_MIPIBIF_0, 0x660 */
+ uint32_t clk_source_emc_dll; /* _CLK_SOURCE_EMC_DLL_0, 0x664 */
+ uint32_t _0x668;
+ uint32_t clk_source_uart_fst_mipi_cal; /* _CLK_SOURCE_UART_FST_MIPI_CAL_0, 0x66c */
+ uint32_t _0x670[2];
+ uint32_t clk_source_vic; /* _CLK_SOURCE_VIC_0, 0x678 */
+
+ uint32_t pllp_outc; /* _PLLP_OUTC_0, 0x67c */
+ uint32_t pllp_misc1; /* _PLLP_MISC1_0, 0x680 */
+ uint32_t _0x684[2];
+ uint32_t emc_div_clk_shaper_ctrl; /* _EMC_DIV_CLK_SHAPER_CTRL_0, 0x68c */
+ uint32_t emc_pllc_shaper_ctrl; /* _EMC_PLLC_SHAPER_CTRL_0, 0x690 */
+
+ uint32_t clk_source_sdmmc_legacy_tm; /* _CLK_SOURCE_SDMMC_LEGACY_TM_0, 0x694 */
+ uint32_t clk_source_nvdec; /* _CLK_SOURCE_NVDEC_0, 0x698 */
+ uint32_t clk_source_nvjpg; /* _CLK_SOURCE_NVJPG_0, 0x69c */
+ uint32_t clk_source_nvenc; /* _CLK_SOURCE_NVENC_0, 0x6a0 */
+
+ uint32_t plla1_base; /* _PLLA1_BASE_0, 0x6a4 */
+ uint32_t plla1_misc0; /* _PLLA1_MISC_0_0, 0x6a8 */
+ uint32_t plla1_misc1; /* _PLLA1_MISC_1_0, 0x6ac */
+ uint32_t plla1_misc2; /* _PLLA1_MISC_2_0, 0x6b0 */
+ uint32_t plla1_misc3; /* _PLLA1_MISC_3_0, 0x6b4 */
+ uint32_t audio_sync_clk_dmic3; /* _AUDIO_SYNC_CLK_DMIC3_0, 0x6b8 */
+
+ uint32_t clk_source_dmic3; /* _CLK_SOURCE_DMIC3_0, 0x6bc */
+ uint32_t clk_source_ape; /* _CLK_SOURCE_APE_0, 0x6c0 */
+ uint32_t clk_source_qspi; /* _CLK_SOURCE_QSPI_0, 0x6c4 */
+ uint32_t clk_source_vi_i2c; /* _CLK_SOURCE_VI_I2C_0, 0x6c8 */
+ uint32_t clk_source_usb2_hsic_trk; /* _CLK_SOURCE_USB2_HSIC_TRK_0, 0x6cc */
+ uint32_t clk_source_pex_sata_usb_rx_byp; /* _CLK_SOURCE_PEX_SATA_USB_RX_BYP_0, 0x6d0 */
+ uint32_t clk_source_maud; /* _CLK_SOURCE_MAUD_0, 0x6d4 */
+ uint32_t clk_source_tsecb; /* _CLK_SOURCE_TSECB_0, 0x6d8 */
+
+ uint32_t clk_cpug_misc1; /* _CLK_CPUG_MISC1_0, 0x6dc */
+ uint32_t aclk_burst_policy; /* _ACLK_BURST_POLICY_0, 0x6e0 */
+ uint32_t super_aclk_divider; /* _SUPER_ACLK_DIVIDER_0, 0x6e4 */
+
+ uint32_t nvenc_super_clk_divider; /* _NVENC_SUPER_CLK_DIVIDER_0, 0x6e8 */
+ uint32_t vi_super_clk_divider; /* _VI_SUPER_CLK_DIVIDER_0, 0x6ec */
+ uint32_t vic_super_clk_divider; /* _VIC_SUPER_CLK_DIVIDER_0, 0x6f0 */
+ uint32_t nvdec_super_clk_divider; /* _NVDEC_SUPER_CLK_DIVIDER_0, 0x6f4 */
+ uint32_t isp_super_clk_divider; /* _ISP_SUPER_CLK_DIVIDER_0, 0x6f8 */
+ uint32_t ispb_super_clk_divider; /* _ISPB_SUPER_CLK_DIVIDER_0, 0x6fc */
+ uint32_t nvjpg_super_clk_divider; /* _NVJPG_SUPER_CLK_DIVIDER_0, 0x700 */
+ uint32_t se_super_clk_divider; /* _SE_SUPER_CLK_DIVIDER_0, 0x704 */
+ uint32_t tsec_super_clk_divider; /* _TSEC_SUPER_CLK_DIVIDER_0, 0x708 */
+ uint32_t tsecb_super_clk_divider; /* _TSECB_SUPER_CLK_DIVIDER_0, 0x70c */
+
+ uint32_t clk_source_uartape; /* _CLK_SOURCE_UARTAPE_0, 0x710 */
+ uint32_t clk_cpug_misc2; /* _CLK_CPUG_MISC2_0, 0x714 */
+ uint32_t clk_source_dbgapb; /* _CLK_SOURCE_DBGAPB_0, 0x718 */
+ uint32_t clk_ccplex_cc4_ret_clk_enb; /* _CLK_CCPLEX_CC4_RET_CLK_ENB_0, 0x71c */
+ uint32_t actmon_cpu_clk; /* _ACTMON_CPU_CLK_0, 0x720 */
+ uint32_t clk_source_emc_safe; /* _CLK_SOURCE_EMC_SAFE_0, 0x724 */
+ uint32_t sdmmc2_pllc4_out0_shaper_ctrl; /* _SDMMC2_PLLC4_OUT0_SHAPER_CTRL_0, 0x728 */
+ uint32_t sdmmc2_pllc4_out1_shaper_ctrl; /* _SDMMC2_PLLC4_OUT1_SHAPER_CTRL_0, 0x72c */
+ uint32_t sdmmc2_pllc4_out2_shaper_ctrl; /* _SDMMC2_PLLC4_OUT2_SHAPER_CTRL_0, 0x730 */
+ uint32_t sdmmc2_div_clk_shaper_ctrl; /* _SDMMC2_DIV_CLK_SHAPER_CTRL_0, 0x734 */
+ uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
+ uint32_t sdmmc4_pllc4_out1_shaper_ctrl; /* _SDMMC4_PLLC4_OUT1_SHAPER_CTRL_0, 0x73c */
+ uint32_t sdmmc4_pllc4_out2_shaper_ctrl; /* _SDMMC4_PLLC4_OUT2_SHAPER_CTRL_0, 0x740 */
+ uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
} tegra_car_t;
-static inline volatile tegra_car_t *car_get_regs(void)
-{
- return (volatile tegra_car_t *)0x60006000;
+static inline volatile tegra_car_t *car_get_regs(void) {
+ return (volatile tegra_car_t *)CAR_BASE;
}
+void clk_enable(CarDevice dev);
+void clk_disable(CarDevice dev);
+void rst_enable(CarDevice dev);
+void rst_disable(CarDevice dev);
+
+void clkrst_enable(CarDevice dev);
+void clkrst_disable(CarDevice dev);
+void clkrst_reboot(CarDevice dev);
+
+void clkrst_enable_fuse_regs(bool enable);
+
#endif
diff --git a/fusee/fusee-primary/src/chainloader.c b/fusee/fusee-primary/src/chainloader.c
index 6890ff4ff..bc222604a 100644
--- a/fusee/fusee-primary/src/chainloader.c
+++ b/fusee/fusee-primary/src/chainloader.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include "chainloader.h"
int g_chainloader_argc = 0;
@@ -17,7 +33,7 @@ static void *xmemmove(void *dst, const void *src, size_t len)
for (size_t i = 0; i < len; i++) {
dst8[i] = src8[i];
}
- } else if (src8 > dst8) {
+ } else if (dst8 > src8) {
for (size_t i = len; len > 0; len--)
dst8[i - 1] = src8[i - 1];
}
diff --git a/fusee/fusee-primary/src/chainloader.h b/fusee/fusee-primary/src/chainloader.h
index 43fe602a2..0081530c3 100644
--- a/fusee/fusee-primary/src/chainloader.h
+++ b/fusee/fusee-primary/src/chainloader.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_CHAINLOADER_H
#define FUSEE_CHAINLOADER_H
diff --git a/fusee/fusee-primary/src/di.c b/fusee/fusee-primary/src/di.c
new file mode 100644
index 000000000..b6f8116c9
--- /dev/null
+++ b/fusee/fusee-primary/src/di.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "di.h"
+#include "timers.h"
+#include "i2c.h"
+#include "pmc.h"
+#include "max77620.h"
+#include "gpio.h"
+#include "pinmux.h"
+#include "car.h"
+
+#include "di.inl"
+
+static uint32_t _display_ver = 0;
+
+static void exec_cfg(uint32_t *base, const cfg_op_t *ops, uint32_t num_ops)
+{
+ for (uint32_t i = 0; i < num_ops; i++)
+ base[ops[i].off] = ops[i].val;
+}
+
+static void _display_dsi_wait(uint32_t timeout, uint32_t off, uint32_t mask)
+{
+ uint32_t end = get_time_us() + timeout;
+ while ((get_time_us() < end) && (MAKE_DSI_REG(off) & mask)) {
+ /* Wait. */
+ }
+ udelay(5);
+}
+
+void display_init()
+{
+ volatile tegra_car_t *car = car_get_regs();
+ volatile tegra_pmc_t *pmc = pmc_get_regs();
+ volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
+
+ /* Power on. */
+ uint8_t val = 0xD0;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1);
+ val = 0x09;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_GPIO7, &val, 1);
+
+ /* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */
+ car->rst_dev_h_clr = 0x1010000;
+ car->clk_enb_h_set = 0x1010000;
+ car->rst_dev_l_clr = 0x18000000;
+ car->clk_enb_l_set = 0x18000000;
+ car->clk_enb_x_set = 0x20000;
+ car->clk_source_uart_fst_mipi_cal = 0xA;
+ car->clk_enb_w_set = 0x80000;
+ car->clk_source_dsia_lp = 0xA;
+
+ /* DPD idle. */
+ pmc->io_dpd_req = 0x40000000;
+ pmc->io_dpd2_req = 0x40000000;
+
+ /* Configure pins. */
+ pinmux->nfc_en &= ~PINMUX_TRISTATE;
+ pinmux->nfc_int &= ~PINMUX_TRISTATE;
+ pinmux->lcd_bl_pwm &= ~PINMUX_TRISTATE;
+ pinmux->lcd_bl_en &= ~PINMUX_TRISTATE;
+ pinmux->lcd_rst &= ~PINMUX_TRISTATE;
+
+ /* Configure Backlight +-5V GPIOs. */
+ gpio_configure_mode(GPIO_LCD_BL_P5V, GPIO_MODE_GPIO);
+ gpio_configure_mode(GPIO_LCD_BL_N5V, GPIO_MODE_GPIO);
+ gpio_configure_direction(GPIO_LCD_BL_P5V, GPIO_DIRECTION_OUTPUT);
+ gpio_configure_direction(GPIO_LCD_BL_N5V, GPIO_DIRECTION_OUTPUT);
+
+ /* Enable Backlight +5V. */
+ gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_HIGH);
+
+ udelay(10000);
+
+ /* Enable Backlight -5V. */
+ gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_HIGH);
+
+ udelay(10000);
+
+ /* Configure Backlight PWM, EN and RST GPIOs. */
+ gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_GPIO);
+ gpio_configure_mode(GPIO_LCD_BL_EN, GPIO_MODE_GPIO);
+ gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO);
+ gpio_configure_direction(GPIO_LCD_BL_PWM, GPIO_DIRECTION_OUTPUT);
+ gpio_configure_direction(GPIO_LCD_BL_EN, GPIO_DIRECTION_OUTPUT);
+ gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT);
+
+ /* Enable Backlight EN. */
+ gpio_write(GPIO_LCD_BL_EN, GPIO_LEVEL_HIGH);
+
+ /* Configure display interface and display. */
+ MAKE_MIPI_CAL_REG(0x60) = 0;
+
+ exec_cfg((uint32_t *)CAR_BASE, _display_config_1, 4);
+ exec_cfg((uint32_t *)DI_BASE, _display_config_2, 94);
+ exec_cfg((uint32_t *)DSI_BASE, _display_config_3, 60);
+
+ udelay(10000);
+
+ /* Enable Backlight RST. */
+ gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH);
+
+ udelay(60000);
+
+ MAKE_DSI_REG(DSI_BTA_TIMING) = 0x50204;
+ MAKE_DSI_REG(DSI_WR_DATA) = 0x337;
+ MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
+ _display_dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO));
+
+ MAKE_DSI_REG(DSI_WR_DATA) = 0x406;
+ MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
+ _display_dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO));
+
+ MAKE_DSI_REG(DSI_HOST_CONTROL) = (DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC);
+ _display_dsi_wait(150000, DSI_HOST_CONTROL, DSI_HOST_CONTROL_IMM_BTA);
+
+ udelay(5000);
+
+ _display_ver = MAKE_DSI_REG(DSI_RD_DATA);
+
+ if (_display_ver == 0x10)
+ exec_cfg((uint32_t *)DSI_BASE, _display_config_4, 43);
+
+ MAKE_DSI_REG(DSI_WR_DATA) = 0x1105;
+ MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
+
+ udelay(180000);
+
+ MAKE_DSI_REG(DSI_WR_DATA) = 0x2905;
+ MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
+
+ udelay(20000);
+
+ exec_cfg((uint32_t *)DSI_BASE, _display_config_5, 21);
+ exec_cfg((uint32_t *)CAR_BASE, _display_config_6, 3);
+
+ MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4;
+ exec_cfg((uint32_t *)DSI_BASE, _display_config_7, 10);
+
+ udelay(10000);
+
+ exec_cfg((uint32_t *)MIPI_CAL_BASE, _display_config_8, 6);
+ exec_cfg((uint32_t *)DSI_BASE, _display_config_9, 4);
+ exec_cfg((uint32_t *)MIPI_CAL_BASE, _display_config_10, 16);
+
+ udelay(10000);
+
+ exec_cfg((uint32_t *)DI_BASE, _display_config_11, 113);
+}
+
+void display_backlight(bool enable)
+{
+ /* Enable Backlight PWM. */
+ gpio_write(GPIO_LCD_BL_PWM, enable ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
+}
+
+void display_end()
+{
+ volatile tegra_car_t *car = car_get_regs();
+ volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
+
+ /* Disable Backlight. */
+ display_backlight(false);
+
+ MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 1;
+ MAKE_DSI_REG(DSI_WR_DATA) = 0x2805;
+
+ MAKE_DI_REG(DC_CMD_STATE_ACCESS) = (READ_MUX | WRITE_MUX);
+ MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 0;
+
+ exec_cfg((uint32_t *)DI_BASE, _display_config_12, 17);
+ exec_cfg((uint32_t *)DSI_BASE, _display_config_13, 16);
+
+ udelay(10000);
+
+ if (_display_ver == 0x10)
+ exec_cfg((uint32_t *)DSI_BASE, _display_config_14, 22);
+
+ MAKE_DSI_REG(DSI_WR_DATA) = 0x1005;
+ MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
+
+ udelay(50000);
+
+ /* Disable Backlight RST. */
+ gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW);
+
+ udelay(10000);
+
+ /* Disable Backlight -5V. */
+ gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_LOW);
+
+ udelay(10000);
+
+ /* Disable Backlight +5V. */
+ gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_LOW);
+
+ udelay(10000);
+
+ /* Disable clocks. */
+ car->rst_dev_h_set = 0x1010000;
+ car->clk_enb_h_clr = 0x1010000;
+ car->rst_dev_l_set = 0x18000000;
+ car->clk_enb_l_clr = 0x18000000;
+
+ MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF));
+ MAKE_DSI_REG(DSI_POWER_CONTROL) = 0;
+
+ /* Backlight PWM. */
+ gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO);
+
+ pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE);
+ pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1);
+}
+
+void display_color_screen(uint32_t color)
+{
+ exec_cfg((uint32_t *)DI_BASE, cfg_display_one_color, 8);
+
+ /* Configure display to show single color. */
+ MAKE_DI_REG(DC_WIN_AD_WIN_OPTIONS) = 0;
+ MAKE_DI_REG(DC_WIN_BD_WIN_OPTIONS) = 0;
+ MAKE_DI_REG(DC_WIN_CD_WIN_OPTIONS) = 0;
+ MAKE_DI_REG(DC_DISP_BLEND_BACKGROUND_COLOR) = color;
+ MAKE_DI_REG(DC_CMD_STATE_CONTROL) = ((MAKE_DI_REG(DC_CMD_STATE_CONTROL) & 0xFFFFFFFE) | GENERAL_ACT_REQ);
+
+ udelay(35000);
+
+ display_backlight(true);
+}
+
+uint32_t *display_init_framebuffer(void *address)
+{
+ static cfg_op_t conf[sizeof(cfg_display_framebuffer)/sizeof(cfg_op_t)] = {0};
+ if (conf[0].val == 0) {
+ for (uint32_t i = 0; i < sizeof(cfg_display_framebuffer)/sizeof(cfg_op_t); i++) {
+ conf[i] = cfg_display_framebuffer[i];
+ }
+ }
+
+ uint32_t *lfb_addr = (uint32_t *)address;
+ conf[19].val = (uint32_t)address;
+
+ /* This configures the framebuffer @ address with a resolution of 1280x720 (line stride 768). */
+ exec_cfg((uint32_t *)DI_BASE, conf, 32);
+
+ udelay(35000);
+
+ return lfb_addr;
+}
diff --git a/fusee/fusee-primary/src/di.h b/fusee/fusee-primary/src/di.h
new file mode 100644
index 000000000..4aa4f944d
--- /dev/null
+++ b/fusee/fusee-primary/src/di.h
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_DI_H_
+#define FUSEE_DI_H_
+
+#include
+#include
+
+#define HOST1X_BASE 0x50000000
+#define DI_BASE 0x54200000
+#define DSI_BASE 0x54300000
+#define VIC_BASE 0x54340000
+#define MIPI_CAL_BASE 0x700E3000
+#define MAKE_HOST1X_REG(n) MAKE_REG32(HOST1X_BASE + n)
+#define MAKE_DI_REG(n) MAKE_REG32(DI_BASE + n * 4)
+#define MAKE_DSI_REG(n) MAKE_REG32(DSI_BASE + n * 4)
+#define MAKE_MIPI_CAL_REG(n) MAKE_REG32(MIPI_CAL_BASE + n)
+#define MAKE_VIC_REG(n) MAKE_REG32(VIC_BASE + n)
+
+/* Display registers. */
+#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
+
+#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
+#define SYNCPT_CNTRL_NO_STALL (1 << 8)
+#define SYNCPT_CNTRL_SOFT_RESET (1 << 0)
+
+#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
+#define SYNCPT_VSYNC_ENABLE (1 << 8)
+
+#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
+
+#define DC_CMD_DISPLAY_COMMAND 0x32
+#define DISP_CTRL_MODE_STOP (0 << 5)
+#define DISP_CTRL_MODE_C_DISPLAY (1 << 5)
+#define DISP_CTRL_MODE_NC_DISPLAY (2 << 5)
+#define DISP_CTRL_MODE_MASK (3 << 5)
+
+#define DC_CMD_DISPLAY_POWER_CONTROL 0x36
+#define PW0_ENABLE (1 << 0)
+#define PW1_ENABLE (1 << 2)
+#define PW2_ENABLE (1 << 4)
+#define PW3_ENABLE (1 << 6)
+#define PW4_ENABLE (1 << 8)
+#define PM0_ENABLE (1 << 16)
+#define PM1_ENABLE (1 << 18)
+
+#define DC_CMD_INT_MASK 0x38
+#define DC_CMD_INT_ENABLE 0x39
+
+#define DC_CMD_STATE_ACCESS 0x40
+#define READ_MUX (1 << 0)
+#define WRITE_MUX (1 << 2)
+
+#define DC_CMD_STATE_CONTROL 0x41
+#define GENERAL_ACT_REQ (1 << 0)
+#define WIN_A_ACT_REQ (1 << 1)
+#define WIN_B_ACT_REQ (1 << 2)
+#define WIN_C_ACT_REQ (1 << 3)
+#define CURSOR_ACT_REQ (1 << 7)
+#define GENERAL_UPDATE (1 << 8)
+#define WIN_A_UPDATE (1 << 9)
+#define WIN_B_UPDATE (1 << 10)
+#define WIN_C_UPDATE (1 << 11)
+#define CURSOR_UPDATE (1 << 15)
+#define NC_HOST_TRIG (1 << 24)
+
+#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
+#define WINDOW_A_SELECT (1 << 4)
+#define WINDOW_B_SELECT (1 << 5)
+#define WINDOW_C_SELECT (1 << 6)
+
+#define DC_CMD_REG_ACT_CONTROL 0x043
+
+#define DC_COM_CRC_CONTROL 0x300
+#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
+#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
+
+#define DC_COM_DSC_TOP_CTL 0x33E
+
+#define DC_DISP_DISP_WIN_OPTIONS 0x402
+#define HDMI_ENABLE (1 << 30)
+#define DSI_ENABLE (1 << 29)
+#define SOR1_TIMING_CYA (1 << 27)
+#define SOR1_ENABLE (1 << 26)
+#define SOR_ENABLE (1 << 25)
+#define CURSOR_ENABLE (1 << 16)
+
+#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
+#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
+#define DC_DISP_DISP_TIMING_OPTIONS 0x405
+#define DC_DISP_REF_TO_SYNC 0x406
+#define DC_DISP_SYNC_WIDTH 0x407
+#define DC_DISP_BACK_PORCH 0x408
+#define DC_DISP_ACTIVE 0x409
+#define DC_DISP_FRONT_PORCH 0x40A
+
+#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
+#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
+#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
+#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
+#define PIXEL_CLK_DIVIDER_PCD3 (3 << 8)
+#define PIXEL_CLK_DIVIDER_PCD4 (4 << 8)
+#define PIXEL_CLK_DIVIDER_PCD6 (5 << 8)
+#define PIXEL_CLK_DIVIDER_PCD8 (6 << 8)
+#define PIXEL_CLK_DIVIDER_PCD9 (7 << 8)
+#define PIXEL_CLK_DIVIDER_PCD12 (8 << 8)
+#define PIXEL_CLK_DIVIDER_PCD16 (9 << 8)
+#define PIXEL_CLK_DIVIDER_PCD18 (10 << 8)
+#define PIXEL_CLK_DIVIDER_PCD24 (11 << 8)
+#define PIXEL_CLK_DIVIDER_PCD13 (12 << 8)
+#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
+
+#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F
+#define DISP_DATA_FORMAT_DF1P1C (0 << 0)
+#define DISP_DATA_FORMAT_DF1P2C24B (1 << 0)
+#define DISP_DATA_FORMAT_DF1P2C18B (2 << 0)
+#define DISP_DATA_FORMAT_DF1P2C16B (3 << 0)
+#define DISP_DATA_FORMAT_DF2S (4 << 0)
+#define DISP_DATA_FORMAT_DF3S (5 << 0)
+#define DISP_DATA_FORMAT_DFSPI (6 << 0)
+#define DISP_DATA_FORMAT_DF1P3C24B (7 << 0)
+#define DISP_DATA_FORMAT_DF1P3C18B (8 << 0)
+#define DISP_ALIGNMENT_MSB (0 << 8)
+#define DISP_ALIGNMENT_LSB (1 << 8)
+#define DISP_ORDER_RED_BLUE (0 << 9)
+#define DISP_ORDER_BLUE_RED (1 << 9)
+
+#define DC_DISP_DISP_COLOR_CONTROL 0x430
+#define DITHER_CONTROL_MASK (3 << 8)
+#define DITHER_CONTROL_DISABLE (0 << 8)
+#define DITHER_CONTROL_ORDERED (2 << 8)
+#define DITHER_CONTROL_ERRDIFF (3 << 8)
+#define BASE_COLOR_SIZE_MASK (0xf << 0)
+#define BASE_COLOR_SIZE_666 (0 << 0)
+#define BASE_COLOR_SIZE_111 (1 << 0)
+#define BASE_COLOR_SIZE_222 (2 << 0)
+#define BASE_COLOR_SIZE_333 (3 << 0)
+#define BASE_COLOR_SIZE_444 (4 << 0)
+#define BASE_COLOR_SIZE_555 (5 << 0)
+#define BASE_COLOR_SIZE_565 (6 << 0)
+#define BASE_COLOR_SIZE_332 (7 << 0)
+#define BASE_COLOR_SIZE_888 (8 << 0)
+
+#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
+#define SC1_H_QUALIFIER_NONE (1 << 16)
+#define SC0_H_QUALIFIER_NONE (1 << 0)
+
+#define DC_DISP_DATA_ENABLE_OPTIONS 0x432
+#define DE_SELECT_ACTIVE_BLANK (0 << 0)
+#define DE_SELECT_ACTIVE (1 << 0)
+#define DE_SELECT_ACTIVE_IS (2 << 0)
+#define DE_CONTROL_ONECLK (0 << 2)
+#define DE_CONTROL_NORMAL (1 << 2)
+#define DE_CONTROL_EARLY_EXT (2 << 2)
+#define DE_CONTROL_EARLY (3 << 2)
+#define DE_CONTROL_ACTIVE_BLANK (4 << 2)
+
+#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480
+#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
+
+#define DC_WIN_CSC_YOF 0x611
+#define DC_WIN_CSC_KYRGB 0x612
+#define DC_WIN_CSC_KUR 0x613
+#define DC_WIN_CSC_KVR 0x614
+#define DC_WIN_CSC_KUG 0x615
+#define DC_WIN_CSC_KVG 0x616
+#define DC_WIN_CSC_KUB 0x617
+#define DC_WIN_CSC_KVB 0x618
+#define DC_WIN_AD_WIN_OPTIONS 0xB80
+#define DC_WIN_BD_WIN_OPTIONS 0xD80
+#define DC_WIN_CD_WIN_OPTIONS 0xF80
+
+/* The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER). */
+#define DC_WIN_WIN_OPTIONS 0x700
+#define H_DIRECTION (1 << 0)
+#define V_DIRECTION (1 << 2)
+#define COLOR_EXPAND (1 << 6)
+#define CSC_ENABLE (1 << 18)
+#define WIN_ENABLE (1 << 30)
+
+#define DC_WIN_COLOR_DEPTH 0x703
+#define WIN_COLOR_DEPTH_P1 0x0
+#define WIN_COLOR_DEPTH_P2 0x1
+#define WIN_COLOR_DEPTH_P4 0x2
+#define WIN_COLOR_DEPTH_P8 0x3
+#define WIN_COLOR_DEPTH_B4G4R4A4 0x4
+#define WIN_COLOR_DEPTH_B5G5R5A 0x5
+#define WIN_COLOR_DEPTH_B5G6R5 0x6
+#define WIN_COLOR_DEPTH_AB5G5R5 0x7
+#define WIN_COLOR_DEPTH_B8G8R8A8 0xC
+#define WIN_COLOR_DEPTH_R8G8B8A8 0xD
+#define WIN_COLOR_DEPTH_B6x2G6x2R6x2A8 0xE
+#define WIN_COLOR_DEPTH_R6x2G6x2B6x2A8 0xF
+#define WIN_COLOR_DEPTH_YCbCr422 0x10
+#define WIN_COLOR_DEPTH_YUV422 0x11
+#define WIN_COLOR_DEPTH_YCbCr420P 0x12
+#define WIN_COLOR_DEPTH_YUV420P 0x13
+#define WIN_COLOR_DEPTH_YCbCr422P 0x14
+#define WIN_COLOR_DEPTH_YUV422P 0x15
+#define WIN_COLOR_DEPTH_YCbCr422R 0x16
+#define WIN_COLOR_DEPTH_YUV422R 0x17
+#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
+#define WIN_COLOR_DEPTH_YUV422RA 0x19
+
+#define DC_WIN_BUFFER_CONTROL 0x702
+#define DC_WIN_POSITION 0x704
+
+#define DC_WIN_SIZE 0x705
+#define H_SIZE(x) (((x) & 0x1fff) << 0)
+#define V_SIZE(x) (((x) & 0x1fff) << 16)
+
+#define DC_WIN_PRESCALED_SIZE 0x706
+#define H_PRESCALED_SIZE(x) (((x) & 0x7fff) << 0)
+#define V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)
+
+#define DC_WIN_H_INITIAL_DDA 0x707
+#define DC_WIN_V_INITIAL_DDA 0x708
+
+#define DC_WIN_DDA_INC 0x709
+#define H_DDA_INC(x) (((x) & 0xffff) << 0)
+#define V_DDA_INC(x) (((x) & 0xffff) << 16)
+
+#define DC_WIN_LINE_STRIDE 0x70A
+#define DC_WIN_DV_CONTROL 0x70E
+
+/* The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). */
+#define DC_WINBUF_START_ADDR 0x800
+#define DC_WINBUF_ADDR_H_OFFSET 0x806
+#define DC_WINBUF_ADDR_V_OFFSET 0x808
+#define DC_WINBUF_SURFACE_KIND 0x80B
+
+/* Display serial interface registers. */
+#define DSI_RD_DATA 0x9
+#define DSI_WR_DATA 0xA
+
+#define DSI_POWER_CONTROL 0xB
+#define DSI_POWER_CONTROL_ENABLE 1
+
+#define DSI_INT_ENABLE 0xC
+#define DSI_INT_STATUS 0xD
+#define DSI_INT_MASK 0xE
+
+#define DSI_HOST_CONTROL 0xF
+#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21)
+#define DSI_HOST_CONTROL_CRC_RESET (1 << 20)
+#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
+#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
+#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
+#define DSI_HOST_CONTROL_RAW (1 << 6)
+#define DSI_HOST_CONTROL_HS (1 << 5)
+#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4)
+#define DSI_HOST_CONTROL_IMM_BTA (1 << 3)
+#define DSI_HOST_CONTROL_PKT_BTA (1 << 2)
+#define DSI_HOST_CONTROL_CS (1 << 1)
+#define DSI_HOST_CONTROL_ECC (1 << 0)
+
+#define DSI_CONTROL 0x10
+#define DSI_CONTROL_HS_CLK_CTRL (1 << 20)
+#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
+#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
+#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
+#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
+#define DSI_CONTROL_DCS_ENABLE (1 << 3)
+#define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2)
+#define DSI_CONTROL_VIDEO_ENABLE (1 << 1)
+#define DSI_CONTROL_HOST_ENABLE (1 << 0)
+
+#define DSI_SOL_DELAY 0x11
+#define DSI_MAX_THRESHOLD 0x12
+
+#define DSI_TRIGGER 0x13
+#define DSI_TRIGGER_HOST (1 << 1)
+#define DSI_TRIGGER_VIDEO (1 << 0)
+
+#define DSI_TX_CRC 0x14
+#define DSI_STATUS 0x15
+#define DSI_INIT_SEQ_CONTROL 0x1A
+#define DSI_INIT_SEQ_DATA_0 0x1B
+#define DSI_INIT_SEQ_DATA_1 0x1C
+#define DSI_INIT_SEQ_DATA_2 0x1D
+#define DSI_INIT_SEQ_DATA_3 0x1E
+#define DSI_PKT_SEQ_0_LO 0x23
+#define DSI_PKT_SEQ_0_HI 0x24
+#define DSI_PKT_SEQ_1_LO 0x25
+#define DSI_PKT_SEQ_1_HI 0x26
+#define DSI_PKT_SEQ_2_LO 0x27
+#define DSI_PKT_SEQ_2_HI 0x28
+#define DSI_PKT_SEQ_3_LO 0x29
+#define DSI_PKT_SEQ_3_HI 0x2A
+#define DSI_PKT_SEQ_4_LO 0x2B
+#define DSI_PKT_SEQ_4_HI 0x2C
+#define DSI_PKT_SEQ_5_LO 0x2D
+#define DSI_PKT_SEQ_5_HI 0x2E
+#define DSI_DCS_CMDS 0x33
+#define DSI_PKT_LEN_0_1 0x34
+#define DSI_PKT_LEN_2_3 0x35
+#define DSI_PKT_LEN_4_5 0x36
+#define DSI_PKT_LEN_6_7 0x37
+#define DSI_PHY_TIMING_0 0x3C
+#define DSI_PHY_TIMING_1 0x3D
+#define DSI_PHY_TIMING_2 0x3E
+#define DSI_BTA_TIMING 0x3F
+
+#define DSI_TIMEOUT_0 0x44
+#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
+#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
+
+#define DSI_TIMEOUT_1 0x45
+#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
+#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
+
+#define DSI_TO_TALLY 0x46
+
+#define DSI_PAD_CONTROL_0 0x4B
+#define DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24)
+#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
+#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
+#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
+
+#define DSI_PAD_CONTROL_CD 0x4c
+#define DSI_VIDEO_MODE_CONTROL 0x4E
+
+#define DSI_PAD_CONTROL_1 0x4F
+#define DSI_PAD_CONTROL_2 0x50
+
+#define DSI_PAD_CONTROL_3 0x51
+#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
+#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
+#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
+#define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0)
+
+#define DSI_PAD_CONTROL_4 0x52
+
+typedef struct _cfg_op_t
+{
+ uint32_t off;
+ uint32_t val;
+} cfg_op_t;
+
+void display_init();
+void display_end();
+
+/* Show one single color on the display. */
+void display_color_screen(uint32_t color);
+
+/* Switches screen backlight ON/OFF. */
+void display_backlight(bool enable);
+
+/* Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
+uint32_t *display_init_framebuffer(void *address);
+
+#endif
diff --git a/fusee/fusee-primary/src/di.inl b/fusee/fusee-primary/src/di.inl
new file mode 100644
index 000000000..e438ca5cb
--- /dev/null
+++ b/fusee/fusee-primary/src/di.inl
@@ -0,0 +1,563 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (C) 2018 CTCaer
+ *
+ * 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 .
+ */
+
+//Clock config.
+static const cfg_op_t _display_config_1[4] = {
+ {0x4E, 0x40000000}, //CLK_RST_CONTROLLER_CLK_SOURCE_DISP1
+ {0x34, 0x4830A001}, //CLK_RST_CONTROLLER_PLLD_BASE
+ {0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
+ {0x37, 0x2D0AAA} //CLK_RST_CONTROLLER_PLLD_MISC
+};
+
+//Display A config.
+static const cfg_op_t _display_config_2[94] = {
+ {DC_CMD_STATE_ACCESS, 0},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
+ {DC_CMD_REG_ACT_CONTROL, 0x54},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_DISP_DC_MCCIF_FIFOCTRL, 0},
+ {DC_DISP_DISP_MEM_HIGH_PRIORITY, 0},
+ {DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0},
+ {DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE},
+ {DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL},
+ {DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | 0x9}, // 9: SYNCPT
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
+ {DC_CMD_STATE_ACCESS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_DV_CONTROL, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ /* Setup default YUV colorspace conversion coefficients */
+ {DC_WIN_CSC_YOF, 0xF0},
+ {DC_WIN_CSC_KYRGB, 0x12A},
+ {DC_WIN_CSC_KUR, 0},
+ {DC_WIN_CSC_KVR, 0x198},
+ {DC_WIN_CSC_KUG, 0x39B},
+ {DC_WIN_CSC_KVG, 0x32F},
+ {DC_WIN_CSC_KUB, 0x204},
+ {DC_WIN_CSC_KVB, 0},
+ /* End of color coefficients */
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_DV_CONTROL, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ /* Setup default YUV colorspace conversion coefficients */
+ {DC_WIN_CSC_YOF, 0xF0},
+ {DC_WIN_CSC_KYRGB, 0x12A},
+ {DC_WIN_CSC_KUR, 0},
+ {DC_WIN_CSC_KVR, 0x198},
+ {DC_WIN_CSC_KUG, 0x39B},
+ {DC_WIN_CSC_KVG, 0x32F},
+ {DC_WIN_CSC_KUB, 0x204},
+ {DC_WIN_CSC_KVB, 0},
+ /* End of color coefficients */
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_DV_CONTROL, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ /* Setup default YUV colorspace conversion coefficients */
+ {DC_WIN_CSC_YOF, 0xF0},
+ {DC_WIN_CSC_KYRGB, 0x12A},
+ {DC_WIN_CSC_KUR, 0},
+ {DC_WIN_CSC_KVR, 0x198},
+ {DC_WIN_CSC_KUG, 0x39B},
+ {DC_WIN_CSC_KVG, 0x32F},
+ {DC_WIN_CSC_KUB, 0x204},
+ {DC_WIN_CSC_KVB, 0},
+ /* End of color coefficients */
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
+ {DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
+ {DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
+ {DC_COM_PIN_OUTPUT_POLARITY(3), 0},
+ {0x4E4, 0},
+ {DC_COM_CRC_CONTROL, 0},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {0x716, 0x10000FF},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {0x716, 0x10000FF},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {0x716, 0x10000FF},
+ {DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_COMMAND, 0},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}
+};
+
+//DSI Init config.
+static const cfg_op_t _display_config_3[60] = {
+ {DSI_WR_DATA, 0},
+ {DSI_INT_ENABLE, 0},
+ {DSI_INT_STATUS, 0},
+ {DSI_INT_MASK, 0},
+ {DSI_INIT_SEQ_DATA_0, 0},
+ {DSI_INIT_SEQ_DATA_1, 0},
+ {DSI_INIT_SEQ_DATA_2, 0},
+ {DSI_INIT_SEQ_DATA_3, 0},
+ {DSI_DCS_CMDS, 0},
+ {DSI_PKT_SEQ_0_LO, 0},
+ {DSI_PKT_SEQ_1_LO, 0},
+ {DSI_PKT_SEQ_2_LO, 0},
+ {DSI_PKT_SEQ_3_LO, 0},
+ {DSI_PKT_SEQ_4_LO, 0},
+ {DSI_PKT_SEQ_5_LO, 0},
+ {DSI_PKT_SEQ_0_HI, 0},
+ {DSI_PKT_SEQ_1_HI, 0},
+ {DSI_PKT_SEQ_2_HI, 0},
+ {DSI_PKT_SEQ_3_HI, 0},
+ {DSI_PKT_SEQ_4_HI, 0},
+ {DSI_PKT_SEQ_5_HI, 0},
+ {DSI_CONTROL, 0},
+ {DSI_PAD_CONTROL_CD, 0},
+ {DSI_SOL_DELAY, 0x18},
+ {DSI_MAX_THRESHOLD, 0x1E0},
+ {DSI_TRIGGER, 0},
+ {DSI_INIT_SEQ_CONTROL, 0},
+ {DSI_PKT_LEN_0_1, 0},
+ {DSI_PKT_LEN_2_3, 0},
+ {DSI_PKT_LEN_4_5, 0},
+ {DSI_PKT_LEN_6_7, 0},
+ {DSI_PAD_CONTROL_1, 0},
+ {DSI_PHY_TIMING_0, 0x6070601},
+ {DSI_PHY_TIMING_1, 0x40A0E05},
+ {DSI_PHY_TIMING_2, 0x30109},
+ {DSI_BTA_TIMING, 0x190A14},
+ {DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
+ {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
+ {DSI_TO_TALLY, 0},
+ {DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Enable
+ {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
+ {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
+ {DSI_POWER_CONTROL, 0},
+ {DSI_POWER_CONTROL, 0},
+ {DSI_PAD_CONTROL_1, 0},
+ {DSI_PHY_TIMING_0, 0x6070601},
+ {DSI_PHY_TIMING_1, 0x40A0E05},
+ {DSI_PHY_TIMING_2, 0x30118},
+ {DSI_BTA_TIMING, 0x190A14},
+ {DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)},
+ {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)},
+ {DSI_TO_TALLY, 0},
+ {DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
+ {DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
+ {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
+ {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
+ {DSI_MAX_THRESHOLD, 0x40},
+ {DSI_TRIGGER, 0},
+ {DSI_TX_CRC, 0},
+ {DSI_INIT_SEQ_CONTROL, 0}
+};
+
+//DSI config (if ver == 0x10).
+static const cfg_op_t _display_config_4[43] = {
+ {DSI_WR_DATA, 0x439},
+ {DSI_WR_DATA, 0x9483FFB9},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0xBD15},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0x1939},
+ {DSI_WR_DATA, 0xAAAAAAD8},
+ {DSI_WR_DATA, 0xAAAAAAEB},
+ {DSI_WR_DATA, 0xAAEBAAAA},
+ {DSI_WR_DATA, 0xAAAAAAAA},
+ {DSI_WR_DATA, 0xAAAAAAEB},
+ {DSI_WR_DATA, 0xAAEBAAAA},
+ {DSI_WR_DATA, 0xAA},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0x1BD15},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0x2739},
+ {DSI_WR_DATA, 0xFFFFFFD8},
+ {DSI_WR_DATA, 0xFFFFFFFF},
+ {DSI_WR_DATA, 0xFFFFFFFF},
+ {DSI_WR_DATA, 0xFFFFFFFF},
+ {DSI_WR_DATA, 0xFFFFFFFF},
+ {DSI_WR_DATA, 0xFFFFFFFF},
+ {DSI_WR_DATA, 0xFFFFFFFF},
+ {DSI_WR_DATA, 0xFFFFFFFF},
+ {DSI_WR_DATA, 0xFFFFFFFF},
+ {DSI_WR_DATA, 0xFFFFFF},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0x2BD15},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0xF39},
+ {DSI_WR_DATA, 0xFFFFFFD8},
+ {DSI_WR_DATA, 0xFFFFFFFF},
+ {DSI_WR_DATA, 0xFFFFFFFF},
+ {DSI_WR_DATA, 0xFFFFFF},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0xBD15},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0x6D915},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0x439},
+ {DSI_WR_DATA, 0xB9},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST}
+};
+
+//DSI config.
+static const cfg_op_t _display_config_5[21] = {
+ {DSI_PAD_CONTROL_1, 0},
+ {DSI_PHY_TIMING_0, 0x6070601},
+ {DSI_PHY_TIMING_1, 0x40A0E05},
+ {DSI_PHY_TIMING_2, 0x30172},
+ {DSI_BTA_TIMING, 0x190A14},
+ {DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)},
+ {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)},
+ {DSI_TO_TALLY, 0},
+ {DSI_PKT_SEQ_0_LO, 0x40000208},
+ {DSI_PKT_SEQ_2_LO, 0x40000308},
+ {DSI_PKT_SEQ_4_LO, 0x40000308},
+ {DSI_PKT_SEQ_1_LO, 0x40000308},
+ {DSI_PKT_SEQ_3_LO, 0x3F3B2B08},
+ {DSI_PKT_SEQ_3_HI, 0x2CC},
+ {DSI_PKT_SEQ_5_LO, 0x3F3B2B08},
+ {DSI_PKT_SEQ_5_HI, 0x2CC},
+ {DSI_PKT_LEN_0_1, 0xCE0000},
+ {DSI_PKT_LEN_2_3, 0x87001A2},
+ {DSI_PKT_LEN_4_5, 0x190},
+ {DSI_PKT_LEN_6_7, 0x190},
+ {DSI_HOST_CONTROL, 0},
+};
+
+//Clock config.
+static const cfg_op_t _display_config_6[3] = {
+ {0x34, 0x4810C001}, //CLK_RST_CONTROLLER_PLLD_BASE
+ {0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
+ {0x37, 0x2DFC00} //CLK_RST_CONTROLLER_PLLD_MISC
+};
+
+//DSI config.
+static const cfg_op_t _display_config_7[10] = {
+ {DSI_TRIGGER, 0},
+ {DSI_CONTROL, 0},
+ {DSI_SOL_DELAY, 6},
+ {DSI_MAX_THRESHOLD, 0x1E0},
+ {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
+ {DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
+ {DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL| DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
+ {DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE},
+ {DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
+ {DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}
+};
+
+//MIPI CAL config.
+static const cfg_op_t _display_config_8[6] = {
+ {0x18, 0},
+ {2, 0xF3F10000},
+ {0x16, 1},
+ {0x18, 0},
+ {0x18, 0x10010},
+ {0x17, 0x300}
+};
+
+//DSI config.
+static const cfg_op_t _display_config_9[4] = {
+ {DSI_PAD_CONTROL_1, 0},
+ {DSI_PAD_CONTROL_2, 0},
+ {DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
+ {DSI_PAD_CONTROL_4, 0}
+};
+
+//MIPI CAL config.
+static const cfg_op_t _display_config_10[16] = {
+ {0xE, 0x200200},
+ {0xF, 0x200200},
+ {0x19, 0x200002},
+ {0x1A, 0x200002},
+ {5, 0},
+ {6, 0},
+ {7, 0},
+ {8, 0},
+ {9, 0},
+ {0xA, 0},
+ {0x10, 0},
+ {0x11, 0},
+ {0x1A, 0},
+ {0x1C, 0},
+ {0x1D, 0},
+ {0, 0x2A000001}
+};
+
+//Display A config.
+static const cfg_op_t _display_config_11[113] = {
+ {DC_CMD_STATE_ACCESS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_DV_CONTROL, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ /* Setup default YUV colorspace conversion coefficients */
+ {DC_WIN_CSC_YOF, 0xF0},
+ {DC_WIN_CSC_KYRGB, 0x12A},
+ {DC_WIN_CSC_KUR, 0},
+ {DC_WIN_CSC_KVR, 0x198},
+ {DC_WIN_CSC_KUG, 0x39B},
+ {DC_WIN_CSC_KVG, 0x32F},
+ {DC_WIN_CSC_KUB, 0x204},
+ {DC_WIN_CSC_KVB, 0},
+ /* End of color coefficients */
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_DV_CONTROL, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ /* Setup default YUV colorspace conversion coefficients */
+ {DC_WIN_CSC_YOF, 0xF0},
+ {DC_WIN_CSC_KYRGB, 0x12A},
+ {DC_WIN_CSC_KUR, 0},
+ {DC_WIN_CSC_KVR, 0x198},
+ {DC_WIN_CSC_KUG, 0x39B},
+ {DC_WIN_CSC_KVG, 0x32F},
+ {DC_WIN_CSC_KUB, 0x204},
+ {DC_WIN_CSC_KVB, 0},
+ /* End of color coefficients */
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_DV_CONTROL, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ /* Setup default YUV colorspace conversion coefficients */
+ {DC_WIN_CSC_YOF, 0xF0},
+ {DC_WIN_CSC_KYRGB, 0x12A},
+ {DC_WIN_CSC_KUR, 0},
+ {DC_WIN_CSC_KVR, 0x198},
+ {DC_WIN_CSC_KUG, 0x39B},
+ {DC_WIN_CSC_KVG, 0x32F},
+ {DC_WIN_CSC_KUB, 0x204},
+ {DC_WIN_CSC_KVB, 0},
+ /* End of color coefficients */
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
+ {DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
+ {DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
+ {DC_COM_PIN_OUTPUT_POLARITY(3), 0},
+ {0x4E4, 0},
+ {DC_COM_CRC_CONTROL, 0},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {0x716, 0x10000FF},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {0x716, 0x10000FF},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {0x716, 0x10000FF},
+ {DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_COMMAND, 0},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
+ {DC_CMD_STATE_ACCESS, 0},
+ /* Set Display timings */
+ {DC_DISP_DISP_TIMING_OPTIONS, 0},
+ {DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1.
+ {DC_DISP_SYNC_WIDTH, 0x10048},
+ {DC_DISP_BACK_PORCH, 0x90048},
+ {DC_DISP_ACTIVE, 0x50002D0},
+ {DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
+ /* End of Display timings */
+ {DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
+ {DC_COM_PIN_OUTPUT_ENABLE(1), 0},
+ {DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
+ {DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
+ {DC_DISP_DISP_CLOCK_CONTROL, 0},
+ {DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
+ {DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX},
+ {DC_DISP_FRONT_PORCH, 0xA0088},
+ {DC_CMD_STATE_ACCESS, 0},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
+ {DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
+ {DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
+ {DC_CMD_STATE_ACCESS, 0},
+ {DC_DISP_DISP_CLOCK_CONTROL, PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4)},
+ {DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888},
+ {DC_CMD_DISPLAY_COMMAND_OPTION0, 0}
+};
+
+////Display A config.
+static const cfg_op_t _display_config_12[17] = {
+ {DC_DISP_FRONT_PORCH, 0xA0088},
+ {DC_CMD_INT_MASK, 0},
+ {DC_CMD_STATE_ACCESS, 0},
+ {DC_CMD_INT_ENABLE, 0},
+ {DC_CMD_CONT_SYNCPT_VSYNC, 0},
+ {DC_CMD_DISPLAY_COMMAND, 0},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
+ {DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
+ {DC_CMD_GENERAL_INCR_SYNCPT, 0x301},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
+ {DC_CMD_DISPLAY_POWER_CONTROL, 0},
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
+};
+
+//DSI config.
+static const cfg_op_t _display_config_13[16] = {
+ {DSI_POWER_CONTROL, 0},
+ {DSI_PAD_CONTROL_1, 0},
+ {DSI_PHY_TIMING_0, 0x6070601},
+ {DSI_PHY_TIMING_1, 0x40A0E05},
+ {DSI_PHY_TIMING_2, 0x30109},
+ {DSI_BTA_TIMING, 0x190A14},
+ {DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) },
+ {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)},
+ {DSI_TO_TALLY, 0},
+ {DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC},
+ {DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE},
+ {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
+ {DSI_MAX_THRESHOLD, 0x40},
+ {DSI_TRIGGER, 0},
+ {DSI_TX_CRC, 0},
+ {DSI_INIT_SEQ_CONTROL, 0}
+};
+
+//DSI config (if ver == 0x10).
+static const cfg_op_t _display_config_14[22] = {
+ {DSI_WR_DATA, 0x439},
+ {DSI_WR_DATA, 0x9483FFB9},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0x2139},
+ {DSI_WR_DATA, 0x191919D5},
+ {DSI_WR_DATA, 0x19191919},
+ {DSI_WR_DATA, 0x19191919},
+ {DSI_WR_DATA, 0x19191919},
+ {DSI_WR_DATA, 0x19191919},
+ {DSI_WR_DATA, 0x19191919},
+ {DSI_WR_DATA, 0x19191919},
+ {DSI_WR_DATA, 0x19191919},
+ {DSI_WR_DATA, 0x19},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0xB39},
+ {DSI_WR_DATA, 0x4F0F41B1},
+ {DSI_WR_DATA, 0xF179A433},
+ {DSI_WR_DATA, 0x2D81},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST},
+ {DSI_WR_DATA, 0x439},
+ {DSI_WR_DATA, 0xB9},
+ {DSI_TRIGGER, DSI_TRIGGER_HOST}
+};
+
+//Display A config.
+static const cfg_op_t cfg_display_one_color[8] = {
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
+ {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} //DISPLAY_CTRL_MODE: continuous display.
+};
+
+//Display A config.
+static const cfg_op_t cfg_display_framebuffer[32] = {
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
+ {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, //T_A8R8G8B8 //NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_WIN_POSITION, 0}, //(0,0)
+ {DC_WIN_H_INITIAL_DDA, 0},
+ {DC_WIN_V_INITIAL_DDA, 0},
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)}, //Pre-scaled size: 1280x2880 bytes.
+ {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)},
+ {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, //Window size: 1280 vertical lines x 720 horizontal pixels.
+ {DC_WIN_LINE_STRIDE, 0x6000C00}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
+ {DC_WIN_BUFFER_CONTROL, 0},
+ {DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.
+ {DC_WINBUF_START_ADDR, 0xC0000000}, //Framebuffer address.
+ {DC_WINBUF_ADDR_H_OFFSET, 0},
+ {DC_WINBUF_ADDR_V_OFFSET, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
+ {DC_WIN_WIN_OPTIONS, WIN_ENABLE}, //Enable window AD.
+ {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.
+};
diff --git a/fusee/fusee-primary/src/emc.h b/fusee/fusee-primary/src/emc.h
new file mode 100644
index 000000000..007559a85
--- /dev/null
+++ b/fusee/fusee-primary/src/emc.h
@@ -0,0 +1,1089 @@
+/*
+ * arch/arm/mach-tegra/tegra21_emc.h
+ *
+ * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FUSEE_EMC_H_
+#define FUSEE_EMC_H_
+
+#define EMC_BASE 0x7001B000
+#define EMC0_BASE 0x7001E000
+#define EMC1_BASE 0x7001F000
+#define MAKE_EMC_REG(n) MAKE_REG32(EMC_BASE + n)
+#define MAKE_EMC0_REG(n) MAKE_REG32(EMC0_BASE + n)
+#define MAKE_EMC1_REG(n) MAKE_REG32(EMC1_BASE + n)
+
+#define EMC_INTSTATUS 0x0
+#define EMC_INTSTATUS_MRR_DIVLD (0x1 << 5)
+#define EMC_INTSTATUS_CLKCHANGE_COMPLETE (0x1 << 4)
+
+#define EMC_INTMASK 0x4
+#define EMC_DBG 0x8
+#define EMC_DBG_WRITE_MUX_ACTIVE (1 << 1)
+#define EMC_DBG_CFG_SWAP_SHIFT 26
+#define EMC_DBG_CFG_SWAP_MASK \
+ (0x3 << EMC_DBG_CFG_SWAP_SHIFT)
+#define EMC_DBG_WRITE_ACTIVE_ONLY (1 << 30)
+
+#define EMC_CONFIG_SAMPLE_DELAY 0x5f0
+#define EMC_CFG_UPDATE 0x5f4
+#define EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_SHIFT 9
+#define EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_MASK \
+ (0x3 << EMC_CFG_UPDATE_UPDATE_DLL_IN_UPDATE_SHIFT)
+#define EMC_CFG 0xc
+#define EMC_CFG_DRAM_CLKSTOP_PD (1 << 31)
+#define EMC_CFG_DRAM_CLKSTOP_SR (1 << 30)
+#define EMC_CFG_DRAM_ACPD (1 << 29)
+#define EMC_CFG_DYN_SELF_REF (1 << 28)
+#define EMC_CFG_REQACT_ASYNC (1 << 26)
+#define EMC_CFG_AUTO_PRE_WR (1 << 25)
+#define EMC_CFG_AUTO_PRE_RD (1 << 24)
+#define EMC_CFG_MAM_PRE_WR (1 << 23)
+#define EMC_CFG_MAN_PRE_RD (1 << 22)
+#define EMC_CFG_PERIODIC_QRST (1 << 21)
+#define EMC_CFG_PERIODIC_QRST_SHIFT (21)
+#define EMC_CFG_EN_DYNAMIC_PUTERM (1 << 20)
+#define EMC_CFG_DLY_WR_DQ_HALF_CLOCK (1 << 19)
+#define EMC_CFG_DSR_VTTGEN_DRV_EN (1 << 18)
+#define EMC_CFG_EMC2MC_CLK_RATIO (3 << 16)
+#define EMC_CFG_WAIT_FOR_ISP2B_READY_B4_CC (1 << 9)
+#define EMC_CFG_WAIT_FOR_VI2_READY_B4_CC (1 << 8)
+#define EMC_CFG_WAIT_FOR_ISP2_READY_B4_CC (1 << 7)
+#define EMC_CFG_INVERT_DQM (1 << 6)
+#define EMC_CFG_WAIT_FOR_DISPLAYB_READY_B4_CC (1 << 5)
+#define EMC_CFG_WAIT_FOR_DISPLAY_READY_B4_CC (1 << 4)
+#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2 (1 << 3)
+#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1 (1 << 2)
+#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE (1 << 1)
+
+#define EMC_ADR_CFG 0x10
+#define EMC_REFCTRL 0x20
+#define EMC_REFCTRL_DEV_SEL_SHIFT 0
+#define EMC_REFCTRL_DEV_SEL_MASK \
+ (0x3 << EMC_REFCTRL_DEV_SEL_SHIFT)
+#define EMC_REFCTRL_ENABLE (0x1 << 31)
+#define EMC_REFCTRL_ENABLE_ALL(num) \
+ (((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT) \
+ | EMC_REFCTRL_ENABLE)
+#define EMC_REFCTRL_DISABLE_ALL(num) \
+ ((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT)
+
+#define EMC_PIN 0x24
+#define EMC_PIN_PIN_CKE_PER_DEV (1 << 2)
+#define EMC_PIN_PIN_CKEB (1 << 1)
+#define EMC_PIN_PIN_CKE (1 << 0)
+
+#define EMC_CLK_FORCE_CC_TRIGGER (1 << 27)
+
+#define EMC_TIMING_CONTROL 0x28
+#define EMC_RC 0x2c
+#define EMC_RFC 0x30
+#define EMC_RFCPB 0x590
+#define EMC_RAS 0x34
+#define EMC_RP 0x38
+#define EMC_R2W 0x3c
+#define EMC_W2R 0x40
+#define EMC_R2P 0x44
+#define EMC_W2P 0x48
+#define EMC_CCDMW 0x5c0
+#define EMC_RD_RCD 0x4c
+#define EMC_WR_RCD 0x50
+#define EMC_RRD 0x54
+#define EMC_REXT 0x58
+#define EMC_WDV 0x5c
+#define EMC_QUSE 0x60
+#define EMC_QRST 0x64
+#define EMC_ISSUE_QRST 0x428
+#define EMC_QSAFE 0x68
+#define EMC_RDV 0x6c
+#define EMC_REFRESH 0x70
+#define EMC_BURST_REFRESH_NUM 0x74
+#define EMC_PDEX2WR 0x78
+#define EMC_PDEX2RD 0x7c
+#define EMC_PDEX2CKE 0x118
+#define EMC_PCHG2PDEN 0x80
+#define EMC_ACT2PDEN 0x84
+#define EMC_AR2PDEN 0x88
+#define EMC_RW2PDEN 0x8c
+#define EMC_CKE2PDEN 0x11c
+#define EMC_TXSR 0x90
+#define EMC_TCKE 0x94
+#define EMC_TFAW 0x98
+#define EMC_TRPAB 0x9c
+#define EMC_TCLKSTABLE 0xa0
+#define EMC_TCLKSTOP 0xa4
+#define EMC_TREFBW 0xa8
+#define EMC_TPPD 0xac
+#define EMC_PDEX2MRR 0xb4
+#define EMC_ODT_WRITE 0xb0
+#define EMC_WEXT 0xb8
+#define EMC_RFC_SLR 0xc0
+#define EMC_MRS_WAIT_CNT2 0xc4
+#define EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_SHIFT 16
+#define EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_MASK \
+ (0x7ff << EMC_MRS_WAIT_CNT2_MRS_EXT2_WAIT_CNT_SHIFT)
+#define EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_SHIFT 0
+#define EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_MASK \
+ (0x3ff << EMC_MRS_WAIT_CNT2_MRS_EXT1_WAIT_CNT_SHIFT)
+
+#define EMC_MRS_WAIT_CNT 0xc8
+#define EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT 0
+#define EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK \
+ (0x3FF << EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT)
+#define EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT 16
+#define EMC_MRS_WAIT_CNT_LONG_WAIT_MASK \
+ (0x3FF << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT)
+
+#define EMC_MRS 0xcc
+#define EMC_MODE_SET_DLL_RESET (1 << 8)
+#define EMC_MRS_USE_MRS_LONG_CNT (1 << 26)
+
+#define EMC_EMRS 0xd0
+#define EMC_EMRS_USE_EMRS_LONG_CNT (1 << 26)
+
+#define EMC_REF 0xd4
+#define EMC_REF_FORCE_CMD 1
+
+#define EMC_PRE 0xd8
+#define EMC_NOP 0xdc
+#define EMC_SELF_REF 0xe0
+#define EMC_SELF_REF_CMD_ENABLED (1 << 0)
+#define EMC_SELF_REF_ACTIVE_SELF_REF (1 << 8)
+#define EMC_SELF_REF_DEV_SEL_SHIFT 30
+#define EMC_SELF_REF_DEV_SEL_MASK \
+ (0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
+
+#define EMC_DPD 0xe4
+#define EMC_MRW 0xe8
+#define EMC_MRW_MRW_OP_SHIFT 0
+#define EMC_MRW_MRW_OP_MASK \
+ (0xff << EMC_MRW_MRW_OP_SHIFT)
+#define EMC_MRW_MRW_MA_SHIFT 16
+#define EMC_MRW_MRW_MA_MASK \
+ (0xff << EMC_MRW_MRW_MA_SHIFT)
+#define EMC_MRW_USE_MRW_LONG_CNT 26
+#define EMC_MRW_USE_MRW_EXT_CNT 27
+#define EMC_MRW_MRW_DEV_SELECTN_SHIFT 30
+#define EMC_MRW_MRW_DEV_SELECTN_MASK \
+ (0x3 << EMC_MRW_MRW_DEV_SELECTN_SHIFT)
+
+#define EMC_MRR 0xec
+#define EMC_MRR_DEV_SEL_SHIFT 30
+#define EMC_MRR_DEV_SEL_MASK \
+ (0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
+#define EMC_MRR_MA_SHIFT 16
+#define EMC_MRR_MA_MASK \
+ (0xff << EMC_MRR_MA_SHIFT)
+#define EMC_MRR_DATA_SHIFT 0
+#define EMC_MRR_DATA_MASK \
+ (0xffff << EMC_MRR_DATA_SHIFT)
+#define LPDDR2_MR4_TEMP_SHIFT 0
+#define LPDDR2_MR4_TEMP_MASK \
+ (0x7 << LPDDR2_MR4_TEMP_SHIFT)
+
+#define EMC_CMDQ 0xf0
+#define EMC_MC2EMCQ 0xf4
+#define EMC_FBIO_SPARE 0x100
+#define EMC_FBIO_CFG5 0x104
+#define EMC_FBIO_CFG5_DRAM_TYPE_SHIFT 0
+#define EMC_FBIO_CFG5_DRAM_TYPE_MASK \
+ (0x3 << EMC_FBIO_CFG5_DRAM_TYPE_SHIFT)
+#define EMC_FBIO_CFG5_CMD_TX_DIS (1 << 8)
+#define EMC_FBIO_CFG5_CMD_BUS_RETURN_TO_ZERO (1 << 27)
+
+#define EMC_CFG5_QUSE_MODE_SHIFT 13
+#define EMC_CFG5_QUSE_MODE_MASK \
+ (0x7 << EMC_CFG5_QUSE_MODE_SHIFT)
+
+#define EMC_CFG_RSV 0x120
+#define EMC_ACPD_CONTROL 0x124
+#define EMC_MPC 0x128
+#define EMC_EMRS2 0x12c
+#define EMC_EMRS2_USE_EMRS2_LONG_CNT (1 << 26)
+
+#define EMC_EMRS3 0x130
+#define EMC_MRW2 0x134
+#define EMC_MRW3 0x138
+#define EMC_MRW4 0x13c
+#define EMC_MRW5 0x4a0
+#define EMC_MRW6 0x4a4
+#define EMC_MRW7 0x4a8
+#define EMC_MRW8 0x4ac
+#define EMC_MRW9 0x4b0
+#define EMC_MRW10 0x4b4
+#define EMC_MRW11 0x4b8
+#define EMC_MRW12 0x4bc
+#define EMC_MRW13 0x4c0
+#define EMC_MRW14 0x4c4
+#define EMC_MRW15 0x4d0
+#define EMC_CFG_SYNC 0x4d4
+#define EMC_CLKEN_OVERRIDE 0x140
+#define EMC_R2R 0x144
+#define EMC_W2W 0x148
+#define EMC_EINPUT 0x14c
+#define EMC_EINPUT_DURATION 0x150
+#define EMC_PUTERM_EXTRA 0x154
+#define EMC_TCKESR 0x158
+#define EMC_TPD 0x15c
+#define EMC_STAT_CONTROL 0x160
+#define EMC_STAT_STATUS 0x164
+#define EMC_STAT_DRAM_CLOCK_LIMIT_LO 0x19c
+#define EMC_STAT_DRAM_CLOCK_LIMIT_HI 0x1a0
+#define EMC_STAT_DRAM_CLOCKS_LO 0x1a4
+#define EMC_STAT_DRAM_CLOCKS_HI 0x1a8
+#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_LO 0x1ac
+#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_HI 0x1b0
+#define EMC_STAT_DRAM_DEV0_READ_CNT_LO 0x1b4
+#define EMC_STAT_DRAM_DEV0_READ_CNT_HI 0x1b8
+#define EMC_STAT_DRAM_DEV0_READ8_CNT_LO 0x1bc
+#define EMC_STAT_DRAM_DEV0_READ8_CNT_HI 0x1c0
+#define EMC_STAT_DRAM_DEV0_WRITE_CNT_LO 0x1c4
+#define EMC_STAT_DRAM_DEV0_WRITE_CNT_HI 0x1c8
+#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_LO 0x1cc
+#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_HI 0x1d0
+#define EMC_STAT_DRAM_DEV0_REF_CNT_LO 0x1d4
+#define EMC_STAT_DRAM_DEV0_REF_CNT_HI 0x1d8
+#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x1dc
+#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x1e0
+#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x1e4
+#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x1e8
+#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x1ec
+#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x1f0
+#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x1f4
+#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x1f8
+#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x1fc
+#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x200
+#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x204
+#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x208
+#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x20c
+#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x210
+#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x214
+#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x218
+#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_LO 0x21c
+#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_HI 0x220
+#define EMC_STAT_DRAM_DEV0_DSR 0x224
+#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_LO 0x228
+#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_HI 0x22c
+#define EMC_STAT_DRAM_DEV1_READ_CNT_LO 0x230
+#define EMC_STAT_DRAM_DEV1_READ_CNT_HI 0x234
+#define EMC_STAT_DRAM_DEV1_READ8_CNT_LO 0x238
+#define EMC_STAT_DRAM_DEV1_READ8_CNT_HI 0x23c
+#define EMC_STAT_DRAM_DEV1_WRITE_CNT_LO 0x240
+#define EMC_STAT_DRAM_DEV1_WRITE_CNT_HI 0x244
+#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_LO 0x248
+#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_HI 0x24c
+#define EMC_STAT_DRAM_DEV1_REF_CNT_LO 0x250
+#define EMC_STAT_DRAM_DEV1_REF_CNT_HI 0x254
+#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x258
+#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x25c
+#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x260
+#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x264
+#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x268
+#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x26c
+#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x270
+#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x274
+#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x278
+#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x27c
+#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x280
+#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x284
+#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x288
+#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x28c
+#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x290
+#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x294
+#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_LO 0x298
+#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_HI 0x29c
+#define EMC_STAT_DRAM_DEV1_DSR 0x2a0
+#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0xc8c
+#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0xc90
+#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0xc94
+#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0xc98
+#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0xc9c
+#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0xca0
+#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0xca4
+#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0xca8
+#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0xcac
+#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0xcb0
+#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0xcb4
+#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0xcb8
+#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0xcbc
+#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0xcc0
+#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0xcc4
+#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0xcc8
+#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_LO 0xccc
+#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_HI 0xcd0
+#define EMC_STAT_DRAM_IO_DSR 0xcd4
+#define EMC_AUTO_CAL_CONFIG 0x2a4
+#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_COMPUTE_START (1 << 0)
+#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_MEASURE_STALL (1 << 9)
+#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_UPDATE_STALL (1 << 10)
+#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_ENABLE (1 << 29)
+#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_START (1 << 31)
+
+#define EMC_AUTO_CAL_CONFIG2 0x458
+#define EMC_AUTO_CAL_CONFIG3 0x45c
+#define EMC_AUTO_CAL_CONFIG4 0x5b0
+#define EMC_AUTO_CAL_CONFIG5 0x5b4
+#define EMC_AUTO_CAL_CONFIG6 0x5cc
+#define EMC_AUTO_CAL_CONFIG7 0x574
+#define EMC_AUTO_CAL_CONFIG8 0x2dc
+#define EMC_AUTO_CAL_VREF_SEL_0 0x2f8
+#define EMC_AUTO_CAL_VREF_SEL_1 0x300
+#define EMC_AUTO_CAL_INTERVAL 0x2a8
+#define EMC_AUTO_CAL_STATUS 0x2ac
+#define EMC_AUTO_CAL_STATUS2 0x3d4
+#define EMC_AUTO_CAL_CHANNEL 0x464
+#define EMC_PMACRO_RX_TERM 0xc48
+#define EMC_PMACRO_DQ_TX_DRV 0xc70
+#define EMC_PMACRO_CA_TX_DRV 0xc74
+#define EMC_PMACRO_CMD_TX_DRV 0xc4c
+#define EMC_PMACRO_AUTOCAL_CFG_0 0x700
+#define EMC_PMACRO_AUTOCAL_CFG_1 0x704
+#define EMC_PMACRO_AUTOCAL_CFG_2 0x708
+#define EMC_PMACRO_AUTOCAL_CFG_COMMON 0xc78
+#define EMC_PMACRO_AUTOCAL_CFG_COMMON_E_CAL_BYPASS_DVFS (1 << 16)
+
+#define EMC_PMACRO_ZCTRL 0xc44
+#define EMC_XM2COMPPADCTRL 0x30c
+#define EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE (1 << 10)
+
+#define EMC_XM2COMPPADCTRL2 0x578
+#define EMC_XM2COMPPADCTRL3 0x2f4
+#define EMC_COMP_PAD_SW_CTRL 0x57c
+#define EMC_REQ_CTRL 0x2b0
+#define EMC_EMC_STATUS 0x2b4
+#define EMC_EMC_STATUS_MRR_DIVLD (1 << 20)
+#define EMC_EMC_STATUS_TIMING_UPDATE_STALLED (1 << 23)
+#define EMC_EMC_STATUS_DRAM_IN_POWERDOWN_SHIFT 4
+#define EMC_EMC_STATUS_DRAM_IN_POWERDOWN_MASK \
+ (0x3 << EMC_EMC_STATUS_DRAM_IN_POWERDOWN_SHIFT)
+#define EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_SHIFT 8
+#define EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_MASK \
+ (0x3 << EMC_EMC_STATUS_DRAM_IN_SELF_REFRESH_SHIFT)
+
+#define EMC_CFG_2 0x2b8
+#define EMC_CFG_DIG_DLL 0x2bc
+#define EMC_CFG_DIG_DLL_CFG_DLL_EN (1 << 0)
+#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_ALL_UNTIL_LOCK (1 << 1)
+#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_ALL_TRAFFIC (1 << 3)
+#define EMC_CFG_DIG_DLL_CFG_DLL_STALL_RW_UNTIL_LOCK (1 << 4)
+#define EMC_CFG_DIG_DLL_CFG_DLL_MODE_SHIFT 6
+#define EMC_CFG_DIG_DLL_CFG_DLL_MODE_MASK \
+ (0x3 << EMC_CFG_DIG_DLL_CFG_DLL_MODE_SHIFT)
+#define EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_SHIFT 8
+#define EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_MASK \
+ (0x7 << EMC_CFG_DIG_DLL_CFG_DLL_LOCK_LIMIT_SHIFT)
+
+#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
+#define EMC_DIG_DLL_STATUS 0x2c4
+#define EMC_DIG_DLL_STATUS_DLL_LOCK (1 << 15)
+#define EMC_DIG_DLL_STATUS_DLL_PRIV_UPDATED (1 << 17)
+#define EMC_DIG_DLL_STATUS_DLL_OUT_SHIFT 0
+#define EMC_DIG_DLL_STATUS_DLL_OUT_MASK \
+ (0x7ff << EMC_DIG_DLL_STATUS_DLL_OUT_SHIFT)
+
+#define EMC_CFG_DIG_DLL_1 0x2c8
+#define EMC_RDV_MASK 0x2cc
+#define EMC_WDV_MASK 0x2d0
+#define EMC_RDV_EARLY_MASK 0x2d4
+#define EMC_RDV_EARLY 0x2d8
+#define EMC_WDV_CHK 0x4e0
+#define EMC_ZCAL_INTERVAL 0x2e0
+#define EMC_ZCAL_WAIT_CNT 0x2e4
+#define EMC_ZCAL_WAIT_CNT_ZCAL_WAIT_CNT_MASK 0x7ff
+#define EMC_ZCAL_WAIT_CNT_ZCAL_WAIT_CNT_SHIFT 0
+
+#define EMC_ZCAL_MRW_CMD 0x2e8
+#define EMC_ZQ_CAL 0x2ec
+#define EMC_ZQ_CAL_DEV_SEL_SHIFT 30
+#define EMC_ZQ_CAL_DEV_SEL_MASK \
+ (0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
+#define EMC_ZQ_CAL_LONG (1 << 4)
+#define EMC_ZQ_CAL_ZQ_LATCH_CMD (1 << 1)
+#define EMC_ZQ_CAL_ZQ_CAL_CMD (1 << 0)
+#define EMC_ZQ_CAL_LONG_CMD_DEV0 \
+ (DRAM_DEV_SEL_0 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
+#define EMC_ZQ_CAL_LONG_CMD_DEV1 \
+ (DRAM_DEV_SEL_1 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
+
+#define EMC_SCRATCH0 0x324
+#define EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE 0x3c8
+#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3cc
+#define EMC_UNSTALL_RW_AFTER_CLKCHANGE 0x3d0
+#define EMC_FDPD_CTRL_CMD_NO_RAMP 0x4d8
+#define EMC_FDPD_CTRL_CMD_NO_RAMP_CMD_DPD_NO_RAMP_ENABLE (1 << 0)
+
+#define EMC_SEL_DPD_CTRL 0x3d8
+#define EMC_SEL_DPD_CTRL_DATA_SEL_DPD_EN (1 << 8)
+#define EMC_SEL_DPD_CTRL_ODT_SEL_DPD_EN (1 << 5)
+#define EMC_SEL_DPD_CTRL_RESET_SEL_DPD_EN (1 << 4)
+#define EMC_SEL_DPD_CTRL_CA_SEL_DPD_EN (1 << 3)
+#define EMC_SEL_DPD_CTRL_CLK_SEL_DPD_EN (1 << 2)
+#define EMC_SEL_DPD_CTRL_DDR3_MASK \
+ ((0xf << 2) | (0x1 << 8))
+#define EMC_SEL_DPD_CTRL_MAS \
+ ((0x3 << 2) | (0x1 << 5) | (0x1 << 8))
+
+#define EMC_FDPD_CTRL_DQ 0x310
+#define EMC_FDPD_CTRL_CMD 0x314
+#define EMC_PRE_REFRESH_REQ_CNT 0x3dc
+#define EMC_REFCTRL2 0x580
+#define EMC_FBIO_CFG7 0x584
+#define EMC_FBIO_CFG7_CH0_ENABLE (1 << 1)
+#define EMC_FBIO_CFG7_CH1_ENABLE (1 << 2)
+
+#define EMC_DATA_BRLSHFT_0 0x588
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT 21
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT 18
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT 15
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT 12
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT 9
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT 6
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT 3
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT 0
+#define EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT)
+
+#define EMC_DATA_BRLSHFT_1 0x58c
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT 21
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT 18
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT 15
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT 12
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT 9
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT 6
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT 3
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT)
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT 0
+#define EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_MASK \
+ (0x7 << EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT)
+
+#define EMC_DQS_BRLSHFT_0 0x594
+#define EMC_DQS_BRLSHFT_1 0x598
+#define EMC_CMD_BRLSHFT_0 0x59c
+#define EMC_CMD_BRLSHFT_1 0x5a0
+#define EMC_CMD_BRLSHFT_2 0x5a4
+#define EMC_CMD_BRLSHFT_3 0x5a8
+#define EMC_QUSE_BRLSHFT_0 0x5ac
+#define EMC_QUSE_BRLSHFT_1 0x5b8
+#define EMC_QUSE_BRLSHFT_2 0x5bc
+#define EMC_QUSE_BRLSHFT_3 0x5c4
+#define EMC_FBIO_CFG8 0x5c8
+#define EMC_CMD_MAPPING_CMD0_0 0x380
+#define EMC_CMD_MAPPING_CMD0_1 0x384
+#define EMC_CMD_MAPPING_CMD0_2 0x388
+#define EMC_CMD_MAPPING_CMD1_0 0x38c
+#define EMC_CMD_MAPPING_CMD1_1 0x390
+#define EMC_CMD_MAPPING_CMD1_2 0x394
+#define EMC_CMD_MAPPING_CMD2_0 0x398
+#define EMC_CMD_MAPPING_CMD2_1 0x39c
+#define EMC_CMD_MAPPING_CMD2_2 0x3a0
+#define EMC_CMD_MAPPING_CMD3_0 0x3a4
+#define EMC_CMD_MAPPING_CMD3_1 0x3a8
+#define EMC_CMD_MAPPING_CMD3_2 0x3ac
+#define EMC_CMD_MAPPING_BYTE 0x3b0
+#define EMC_DYN_SELF_REF_CONTROL 0x3e0
+#define EMC_TXSRDLL 0x3e4
+#define EMC_CCFIFO_ADDR 0x3e8
+#define EMC_CCFIFO_DATA 0x3ec
+#define EMC_CCFIFO_STATUS 0x3f0
+#define EMC_SWIZZLE_RANK0_BYTE0 0x404
+#define EMC_SWIZZLE_RANK0_BYTE1 0x408
+#define EMC_SWIZZLE_RANK0_BYTE2 0x40c
+#define EMC_SWIZZLE_RANK0_BYTE3 0x410
+#define EMC_SWIZZLE_RANK1_BYTE0 0x418
+#define EMC_SWIZZLE_RANK1_BYTE1 0x41c
+#define EMC_SWIZZLE_RANK1_BYTE2 0x420
+#define EMC_SWIZZLE_RANK1_BYTE3 0x424
+#define EMC_TR_TIMING_0 0x3b4
+#define EMC_TR_CTRL_0 0x3b8
+#define EMC_TR_CTRL_1 0x3bc
+#define EMC_TR_DVFS 0x460
+#define EMC_TR_DVFS_TRAINING_DVFS (1 << 0)
+
+#define EMC_SWITCH_BACK_CTRL 0x3c0
+#define EMC_TR_RDV 0x3c4
+#define EMC_TR_QPOP 0x3f4
+#define EMC_TR_RDV_MASK 0x3f8
+#define EMC_TR_QSAFE 0x3fc
+#define EMC_TR_QRST 0x400
+#define EMC_IBDLY 0x468
+#define EMC_OBDLY 0x46c
+#define EMC_TXDSRVTTGEN 0x480
+#define EMC_WE_DURATION 0x48c
+#define EMC_WS_DURATION 0x490
+#define EMC_WEV 0x494
+#define EMC_WSV 0x498
+#define EMC_CFG_3 0x49c
+#define EMC_CFG_PIPE_2 0x554
+#define EMC_CFG_PIPE_CLK 0x558
+#define EMC_CFG_PIPE_CLK_CLK_ALWAYS_ON (1 << 0)
+
+#define EMC_CFG_PIPE_1 0x55c
+#define EMC_CFG_PIPE 0x560
+#define EMC_QPOP 0x564
+#define EMC_QUSE_WIDTH 0x568
+#define EMC_PUTERM_WIDTH 0x56c
+#define EMC_PROTOBIST_CONFIG_ADR_1 0x5d0
+#define EMC_PROTOBIST_CONFIG_ADR_2 0x5d4
+#define EMC_PROTOBIST_MISC 0x5d8
+#define EMC_PROTOBIST_WDATA_LOWER 0x5dc
+#define EMC_PROTOBIST_WDATA_UPPER 0x5e0
+#define EMC_PROTOBIST_RDATA 0x5ec
+#define EMC_DLL_CFG_0 0x5e4
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_IGNORE_START (1 << 29)
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_DUAL_PASS_LOCK (1 << 28)
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_SHIFT 24
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_MASK \
+ (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_STEP_SIZE_SHIFT)
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_SHIFT 20
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_MASK \
+ (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_END_COUNT_SHIFT)
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_SHIFT 16
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_MASK \
+ (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_FILTER_BITS_SHIFT)
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_SHIFT 12
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_MASK \
+ (0xf << EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_COUNT_SHIFT)
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_SHIFT 4
+#define EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_MASK \
+ (0xff << EMC_DLL_CFG_0_DDLLCAL_CTRL_SAMPLE_DELAY_SHIFT)
+#define EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_SHIFT 0
+#define EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_MASK \
+ (0xf << EMC_DLL_CFG_0_DDLLCAL_UPDATE_CNT_LIMIT_SHIFT)
+
+#define EMC_DLL_CFG_1 0x5e8
+#define EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_SHIFT 10
+#define EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_MASK \
+ (0x7ff << EMC_DLL_CFG_1_DDLLCAL_CTRL_START_TRIM_SHIFT)
+
+#define EMC_TRAINING_CMD 0xe00
+#define EMC_TRAINING_CMD_PRIME (1 << 0)
+#define EMC_TRAINING_CMD_CA (1 << 1)
+#define EMC_TRAINING_CMD_RD (1 << 2)
+#define EMC_TRAINING_CMD_WR (1 << 3)
+#define EMC_TRAINING_CMD_QUSE (1 << 4)
+#define EMC_TRAINING_CMD_CA_VREF (1 << 5)
+#define EMC_TRAINING_CMD_RD_VREF (1 << 6)
+#define EMC_TRAINING_CMD_WR_VREF (1 << 7)
+#define EMC_TRAINING_CMD_QUSE_VREF (1 << 8)
+#define EMC_TRAINING_CMD_GO (1 << 31)
+
+#define EMC_TRAINING_CTRL 0xe04
+#define EMC_TRAINING_CTRL_SWAP_RANK (1 << 14)
+
+#define EMC_TRAINING_STATUS 0xe08
+#define EMC_TRAINING_QUSE_CORS_CTRL 0xe0c
+#define EMC_TRAINING_QUSE_FINE_CTRL 0xe10
+#define EMC_TRAINING_QUSE_CTRL_MISC 0xe14
+#define EMC_TRAINING_WRITE_FINE_CTRL 0xe18
+#define EMC_TRAINING_WRITE_CTRL_MISC 0xe1c
+#define EMC_TRAINING_WRITE_VREF_CTRL 0xe20
+#define EMC_TRAINING_READ_FINE_CTRL 0xe24
+#define EMC_TRAINING_READ_CTRL_MISC 0xe28
+#define EMC_TRAINING_READ_VREF_CTRL 0xe2c
+#define EMC_TRAINING_CA_FINE_CTRL 0xe30
+#define EMC_TRAINING_CA_CTRL_MISC 0xe34
+#define EMC_TRAINING_CA_CTRL_MISC1 0xe38
+#define EMC_TRAINING_CA_VREF_CTRL 0xe3c
+#define EMC_TRAINING_CA_TADR_CTRL 0xe40
+#define EMC_TRAINING_SETTLE 0xe44
+#define EMC_TRAINING_DEBUG_CTRL 0xe48
+#define EMC_TRAINING_DEBUG_DQ0 0xe4c
+#define EMC_TRAINING_DEBUG_DQ1 0xe50
+#define EMC_TRAINING_DEBUG_DQ2 0xe54
+#define EMC_TRAINING_DEBUG_DQ3 0xe58
+#define EMC_TRAINING_MPC 0xe5c
+#define EMC_TRAINING_PATRAM_CTRL 0xe60
+#define EMC_TRAINING_PATRAM_DQ 0xe64
+#define EMC_TRAINING_PATRAM_DMI 0xe68
+#define EMC_TRAINING_VREF_SETTLE 0xe6c
+#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE0 0xe70
+#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE1 0xe74
+#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE2 0xe78
+#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE3 0xe7c
+#define EMC_TRAINING_RW_EYE_CENTER_IB_MISC 0xe80
+#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE0 0xe84
+#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE1 0xe88
+#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE2 0xe8c
+#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE3 0xe90
+#define EMC_TRAINING_RW_EYE_CENTER_OB_MISC 0xe94
+#define EMC_TRAINING_RW_OFFSET_IB_BYTE0 0xe98
+#define EMC_TRAINING_RW_OFFSET_IB_BYTE1 0xe9c
+#define EMC_TRAINING_RW_OFFSET_IB_BYTE2 0xea0
+#define EMC_TRAINING_RW_OFFSET_IB_BYTE3 0xea4
+#define EMC_TRAINING_RW_OFFSET_IB_MISC 0xea8
+#define EMC_TRAINING_RW_OFFSET_OB_BYTE0 0xeac
+#define EMC_TRAINING_RW_OFFSET_OB_BYTE1 0xeb0
+#define EMC_TRAINING_RW_OFFSET_OB_BYTE2 0xeb4
+#define EMC_TRAINING_RW_OFFSET_OB_BYTE3 0xeb8
+#define EMC_TRAINING_RW_OFFSET_OB_MISC 0xebc
+#define EMC_TRAINING_OPT_CA_VREF 0xec0
+#define EMC_TRAINING_OPT_DQ_OB_VREF 0xec4
+#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK0 0xec8
+#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK1 0xecc
+#define EMC_TRAINING_QUSE_VREF_CTRL 0xed0
+#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK0 0xed4
+#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK1 0xed8
+#define EMC_TRAINING_DRAMC_TIMING 0xedc
+#define EMC_PMACRO_QUSE_DDLL_RANK0_0 0x600
+#define EMC_PMACRO_QUSE_DDLL_RANK0_1 0x604
+#define EMC_PMACRO_QUSE_DDLL_RANK0_2 0x608
+#define EMC_PMACRO_QUSE_DDLL_RANK0_3 0x60c
+#define EMC_PMACRO_QUSE_DDLL_RANK0_4 0x610
+#define EMC_PMACRO_QUSE_DDLL_RANK0_5 0x614
+#define EMC_PMACRO_QUSE_DDLL_RANK1_0 0x620
+#define EMC_PMACRO_QUSE_DDLL_RANK1_1 0x624
+#define EMC_PMACRO_QUSE_DDLL_RANK1_2 0x628
+#define EMC_PMACRO_QUSE_DDLL_RANK1_3 0x62c
+#define EMC_PMACRO_QUSE_DDLL_RANK1_4 0x630
+#define EMC_PMACRO_QUSE_DDLL_RANK1_5 0x634
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0 0x640
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_SHIFT \
+ 16
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE1_SHIFT
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_SHIFT \
+ 0
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_OB_DDLL_LONG_DQ_RANK0_BYTE0_SHIFT
+
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1 0x644
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_SHIFT \
+ 16
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE3_SHIFT
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_SHIFT \
+ 0
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_OB_DDLL_LONG_DQ_RANK0_BYTE2_SHIFT
+
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2 0x648
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_SHIFT \
+ 16
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE5_SHIFT
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_SHIFT \
+ 0
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_OB_DDLL_LONG_DQ_RANK0_BYTE4_SHIFT
+
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3 0x64c
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_SHIFT \
+ 16
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE7_SHIFT
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_SHIFT \
+ 0
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_OB_DDLL_LONG_DQ_RANK0_BYTE6_SHIFT
+
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4 0x650
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5 0x654
+
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0 0x660
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_SHIFT \
+ 16
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE1_SHIFT
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_SHIFT \
+ 0
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_OB_DDLL_LONG_DQ_RANK1_BYTE0_SHIFT
+
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1 0x664
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_SHIFT \
+ 16
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE3_SHIFT
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_SHIFT \
+ 0
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_OB_DDLL_LONG_DQ_RANK1_BYTE2_SHIFT
+
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2 0x668
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_SHIFT \
+ 16
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE5_SHIFT
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_SHIFT \
+ 0
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_OB_DDLL_LONG_DQ_RANK1_BYTE4_SHIFT
+
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3 0x66c
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_SHIFT \
+ 16
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE7_SHIFT
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_SHIFT \
+ 0
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_MASK \
+ 0x3ff << \
+ EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_OB_DDLL_LONG_DQ_RANK1_BYTE6_SHIFT
+
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4 0x670
+#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5 0x674
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0 0x680
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1 0x684
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2 0x688
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3 0x68c
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4 0x690
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5 0x694
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0 0x6a0
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1 0x6a4
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2 0x6a8
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3 0x6ac
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4 0x6b0
+#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5 0x6b4
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0 0x6c0
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1 0x6c4
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2 0x6c8
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3 0x6cc
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_4 0x6d0
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_5 0x6d4
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0 0x6e0
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1 0x6e4
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2 0x6e8
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3 0x6ec
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_4 0x6f0
+#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_5 0x6f4
+#define EMC_PMACRO_TX_PWRD_0 0x720
+#define EMC_PMACRO_TX_PWRD_1 0x724
+#define EMC_PMACRO_TX_PWRD_2 0x728
+#define EMC_PMACRO_TX_PWRD_3 0x72c
+#define EMC_PMACRO_TX_PWRD_4 0x730
+#define EMC_PMACRO_TX_PWRD_5 0x734
+#define EMC_PMACRO_TX_SEL_CLK_SRC_0 0x740
+#define EMC_PMACRO_TX_SEL_CLK_SRC_1 0x744
+#define EMC_PMACRO_TX_SEL_CLK_SRC_3 0x74c
+#define EMC_PMACRO_TX_SEL_CLK_SRC_2 0x748
+#define EMC_PMACRO_TX_SEL_CLK_SRC_4 0x750
+#define EMC_PMACRO_TX_SEL_CLK_SRC_5 0x754
+#define EMC_PMACRO_DDLL_BYPASS 0x760
+#define EMC_PMACRO_DDLL_PWRD_0 0x770
+#define EMC_PMACRO_DDLL_PWRD_1 0x774
+#define EMC_PMACRO_DDLL_PWRD_2 0x778
+#define EMC_PMACRO_CMD_CTRL_0 0x780
+#define EMC_PMACRO_CMD_CTRL_1 0x784
+#define EMC_PMACRO_CMD_CTRL_2 0x788
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0 0x800
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1 0x804
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2 0x808
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3 0x80c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0 0x810
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1 0x814
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2 0x818
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3 0x81c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0 0x820
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1 0x824
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2 0x828
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3 0x82c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0 0x830
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1 0x834
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2 0x838
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3 0x83c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0 0x840
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1 0x844
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2 0x848
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3 0x84c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0 0x850
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1 0x854
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2 0x858
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3 0x85c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0 0x860
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1 0x864
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2 0x868
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3 0x86c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0 0x870
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1 0x874
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2 0x878
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3 0x87c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0 0x880
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1 0x884
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2 0x888
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3 0x88c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0 0x890
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1 0x894
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2 0x898
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3 0x89c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0 0x8a0
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1 0x8a4
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2 0x8a8
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3 0x8ac
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0 0x8b0
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1 0x8b4
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2 0x8b8
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3 0x8bc
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0 0x900
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1 0x904
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2 0x908
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3 0x90c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0 0x910
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1 0x914
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2 0x918
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3 0x91c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0 0x920
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1 0x924
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2 0x928
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3 0x92c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0 0x930
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1 0x934
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2 0x938
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3 0x93c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0 0x940
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1 0x944
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2 0x948
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3 0x94c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0 0x950
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1 0x954
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2 0x958
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3 0x95c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0 0x960
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1 0x964
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2 0x968
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3 0x96c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0 0x970
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1 0x974
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2 0x978
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3 0x97c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0 0x980
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1 0x984
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2 0x988
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3 0x98c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0 0x990
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1 0x994
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2 0x998
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3 0x99c
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0 0x9a0
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1 0x9a4
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2 0x9a8
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3 0x9ac
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0 0x9b0
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1 0x9b4
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2 0x9b8
+#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3 0x9bc
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0 0xa00
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1 0xa04
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2 0xa08
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0 0xa10
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1 0xa14
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2 0xa18
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0 0xa20
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1 0xa24
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2 0xa28
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0 0xa30
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1 0xa34
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2 0xa38
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0 0xa40
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1 0xa44
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2 0xa48
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0 0xa50
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1 0xa54
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2 0xa58
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0 0xa60
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1 0xa64
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2 0xa68
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0 0xa70
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1 0xa74
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2 0xa78
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_0 0xa80
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_1 0xa84
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_2 0xa88
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_0 0xa90
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_1 0xa94
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_2 0xa98
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_0 0xaa0
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_1 0xaa4
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_2 0xaa8
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_0 0xab0
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_1 0xab4
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_2 0xab8
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0 0xb00
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1 0xb04
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2 0xb08
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0 0xb10
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1 0xb14
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2 0xb18
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0 0xb20
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1 0xb24
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2 0xb28
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0 0xb30
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1 0xb34
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2 0xb38
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0 0xb40
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1 0xb44
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2 0xb48
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0 0xb50
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1 0xb54
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2 0xb58
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0 0xb60
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1 0xb64
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2 0xb68
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0 0xb70
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1 0xb74
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2 0xb78
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_0 0xb80
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_1 0xb84
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_2 0xb88
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_0 0xb90
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_1 0xb94
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_2 0xb98
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_0 0xba0
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_1 0xba4
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_2 0xba8
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_0 0xbb0
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_1 0xbb4
+#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_2 0xbb8
+#define EMC_PMACRO_IB_VREF_DQ_0 0xbe0
+#define EMC_PMACRO_IB_VREF_DQ_1 0xbe4
+#define EMC_PMACRO_IB_VREF_DQ_2 0xbe8
+#define EMC_PMACRO_IB_VREF_DQS_0 0xbf0
+#define EMC_PMACRO_IB_VREF_DQS_1 0xbf4
+#define EMC_PMACRO_IB_VREF_DQS_2 0xbf8
+#define EMC_PMACRO_IB_RXRT 0xcf4
+#define EMC_PMACRO_DDLL_LONG_CMD_0 0xc00
+#define EMC_PMACRO_DDLL_LONG_CMD_1 0xc04
+#define EMC_PMACRO_DDLL_LONG_CMD_2 0xc08
+#define EMC_PMACRO_DDLL_LONG_CMD_3 0xc0c
+#define EMC_PMACRO_DDLL_LONG_CMD_4 0xc10
+#define EMC_PMACRO_DDLL_LONG_CMD_5 0xc14
+#define EMC_PMACRO_DDLL_SHORT_CMD_0 0xc20
+#define EMC_PMACRO_DDLL_SHORT_CMD_1 0xc24
+#define EMC_PMACRO_DDLL_SHORT_CMD_2 0xc28
+#define EMC_PMACRO_CFG_PM_GLOBAL_0 0xc30
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE0 (1 << 16)
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE1 (1 << 17)
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE2 (1 << 18)
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE3 (1 << 19)
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE4 (1 << 20)
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE5 (1 << 21)
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE6 (1 << 22)
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_BYTE7 (1 << 23)
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD0 (1 << 24)
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD1 (1 << 25)
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD2 (1 << 26)
+#define EMC_PMACRO_CFG_PM_GLOBAL_0_DISABLE_CFG_CMD3 (1 << 27)
+
+#define EMC_PMACRO_VTTGEN_CTRL_0 0xc34
+#define EMC_PMACRO_VTTGEN_CTRL_1 0xc38
+#define EMC_PMACRO_VTTGEN_CTRL_2 0xcf0
+#define EMC_PMACRO_BG_BIAS_CTRL_0 0xc3c
+#define EMC_PMACRO_BG_BIAS_CTRL_0_BG_E_PWRD (1 << 0)
+#define EMC_PMACRO_BG_BIAS_CTRL_0_BG_MODE (1 << 1)
+#define EMC_PMACRO_BG_BIAS_CTRL_0_BGLP_E_PWRD (1 << 2)
+
+#define EMC_PMACRO_PAD_CFG_CTRL 0xc40
+#define EMC_PMACRO_CMD_PAD_RX_CTRL 0xc50
+#define EMC_PMACRO_DATA_PAD_RX_CTRL 0xc54
+#define EMC_PMACRO_CMD_RX_TERM_MODE 0xc58
+#define EMC_PMACRO_DATA_RX_TERM_MODE 0xc5c
+#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_SHIFT 8
+#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_MASK (0x3 << \
+ EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_SHIFT)
+#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_SHIFT 4
+#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_MASK (0x3 << \
+ EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_SHIFT)
+#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_SHIFT 0
+#define EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_MASK (0x3 << \
+ EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_SHIFT)
+
+#define RX_TERM_MODE \
+ ~(EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSN_RX_TERM_MODE_MASK | \
+ EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQSP_RX_TERM_MODE_MASK | \
+ EMC_PMACRO_DATA_RX_TERM_MODE_DATA_DQ_RX_TERM_MODE_MASK)
+
+#define EMC_PMACRO_CMD_PAD_TX_CTRL 0xc60
+#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQ_TX_E_DCC (1 << 1)
+#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQSP_TX_E_DCC (1 << 9)
+#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQSN_TX_E_DCC (1 << 16)
+#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_CMD_TX_E_DCC (1 << 24)
+#define EMC_PMACRO_CMD_PAD_TX_CTRL_CMD_DQ_TX_DRVFORCEON (1 << 26)
+
+#define EMC_PMACRO_DATA_PAD_TX_CTRL 0xc64
+#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQ_E_IVREF (1 << 0)
+#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQ_TX_E_DCC (1 << 1)
+#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQS_E_IVREF (1 << 8)
+#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQSP_TX_E_DCC (1 << 9)
+#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_DQSN_TX_E_DCC (1 << 16)
+#define EMC_PMACRO_DATA_PAD_TX_CTRL_DATA_CMD_TX_E_DCC (1 << 24)
+
+#define EMC_PMACRO_COMMON_PAD_TX_CTRL 0xc68
+#define EMC_PMACRO_BRICK_MAPPING_0 0xc80
+#define EMC_PMACRO_BRICK_MAPPING_1 0xc84
+#define EMC_PMACRO_BRICK_MAPPING_2 0xc88
+#define EMC_PMACRO_DDLLCAL_CAL 0xce0
+#define EMC_PMACRO_DDLL_OFFSET 0xce4
+#define EMC_PMACRO_DDLL_PERIODIC_OFFSET 0xce8
+#define EMC_PMACRO_BRICK_CTRL_RFU1 0x330
+#define EMC_PMACRO_BRICK_CTRL_RFU2 0x334
+#define EMC_PMACRO_CMD_BRICK_CTRL_FDPD 0x318
+#define EMC_PMACRO_DATA_BRICK_CTRL_FDPD 0x31c
+#define EMC_PMACRO_TRAINING_CTRL_0 0xcf8
+#define EMC_PMACRO_TRAINING_CTRL_0_CH0_TRAINING_E_WRPTR (1 << 3)
+
+#define EMC_PMACRO_TRAINING_CTRL_1 0xcfc
+#define EMC_PMACRO_TRAINING_CTRL_1_CH1_TRAINING_E_WRPTR (1 << 3)
+
+#define EMC_PMC_SCRATCH1 0x440
+#define EMC_PMC_SCRATCH2 0x444
+#define EMC_PMC_SCRATCH3 0x448
+
+#endif
diff --git a/fusee/fusee-primary/src/exception_handlers.c b/fusee/fusee-primary/src/exception_handlers.c
index 0d71e9ecb..e0e5392b0 100644
--- a/fusee/fusee-primary/src/exception_handlers.c
+++ b/fusee/fusee-primary/src/exception_handlers.c
@@ -1,9 +1,24 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "exception_handlers.h"
-#include "lib/driver_utils.h"
#include "utils.h"
-#include "display/video_fb.h"
+#include "lib/log.h"
#define CODE_DUMP_SIZE 0x30
#define STACK_DUMP_SIZE 0x60
@@ -39,26 +54,28 @@ void exception_handler_main(uint32_t *registers, unsigned int exception_type) {
uint32_t instr_addr = pc + ((cpsr & 0x20) ? 2 : 4) - CODE_DUMP_SIZE;
- printk("\nSomething went wrong...\n");
+ print(SCREEN_LOG_LEVEL_ERROR, "\nSomething went wrong...\n");
code_dump_size = safecpy(code_dump, (const void *)instr_addr, CODE_DUMP_SIZE);
stack_dump_size = safecpy(stack_dump, (const void *)registers[13], STACK_DUMP_SIZE);
- printk("\nException type: %s\n", exception_names[exception_type]);
- printk("\nRegisters:\n\n");
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nException type: %s\n",
+ exception_names[exception_type]);
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nRegisters:\n\n");
/* Print r0 to pc. */
for (int i = 0; i < 16; i += 2) {
- printk("%-7s%08"PRIX32" %-7s%08"PRIX32"\n", register_names[i], registers[i], register_names[i+1], registers[i+1]);
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "%-7s%08"PRIX32" %-7s%08"PRIX32"\n",
+ register_names[i], registers[i], register_names[i+1], registers[i+1]);
}
/* Print cpsr. */
- printk("%-7s%08"PRIX32"\n", register_names[16], registers[16]);
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "%-7s%08"PRIX32"\n", register_names[16], registers[16]);
- printk("\nCode dump:\n");
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nCode dump:\n");
hexdump(code_dump, code_dump_size, instr_addr);
- printk("\nStack dump:\n");
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nStack dump:\n");
hexdump(stack_dump, stack_dump_size, registers[13]);
- printk("\n");
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\n");
fatal_error("An exception occured!\n");
}
diff --git a/fusee/fusee-primary/src/exception_handlers.h b/fusee/fusee-primary/src/exception_handlers.h
index 8e79b4136..7fda29867 100644
--- a/fusee/fusee-primary/src/exception_handlers.h
+++ b/fusee/fusee-primary/src/exception_handlers.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_EXCEPTION_HANDLERS_H
#define FUSEE_EXCEPTION_HANDLERS_H
diff --git a/fusee/fusee-primary/src/exception_handlers_asm.s b/fusee/fusee-primary/src/exception_handlers_asm.s
index 3a0be6514..84b34308b 100644
--- a/fusee/fusee-primary/src/exception_handlers_asm.s
+++ b/fusee/fusee-primary/src/exception_handlers_asm.s
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
.macro GEN_USUAL_HANDLER name, index, lr_arm_displ, lr_thumb_displ
_exception_handler_\name:
ldr sp, =_regs
diff --git a/fusee/fusee-primary/src/flow.h b/fusee/fusee-primary/src/flow.h
new file mode 100644
index 000000000..cd98d8983
--- /dev/null
+++ b/fusee/fusee-primary/src/flow.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_FLOW_CTLR_H
+#define FUSEE_FLOW_CTLR_H
+
+#include
+
+#define FLOW_CTLR_BASE 0x60007000
+#define MAKE_FLOW_REG(n) MAKE_REG32(FLOW_CTLR_BASE + n)
+
+#define FLOW_CTLR_HALT_COP_EVENTS_0 MAKE_FLOW_REG(0x004)
+#define FLOW_CTLR_RAM_REPAIR_0 MAKE_FLOW_REG(0x040)
+#define FLOW_CTLR_FLOW_DBG_QUAL_0 MAKE_FLOW_REG(0x050)
+#define FLOW_CTLR_L2FLUSH_CONTROL_0 MAKE_FLOW_REG(0x094)
+#define FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 MAKE_FLOW_REG(0x098)
+
+#endif
diff --git a/fusee/fusee-primary/src/fs_utils.c b/fusee/fusee-primary/src/fs_utils.c
index c3ee71d4c..f788c1f94 100644
--- a/fusee/fusee-primary/src/fs_utils.c
+++ b/fusee/fusee-primary/src/fs_utils.c
@@ -1,7 +1,23 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include "fs_utils.h"
-#include "hwinit.h"
-#include "lib/printk.h"
+#include "mc.h"
#include "lib/fatfs/ff.h"
+#include "lib/log.h"
FATFS sd_fs;
static bool g_sd_mounted = false;
@@ -28,7 +44,7 @@ bool mount_sd(void)
/* Mount SD. */
if (f_mount(&sd_fs, "", 1) == FR_OK) {
- printk("Mounted SD card!\n");
+ print(SCREEN_LOG_LEVEL_INFO, "Mounted SD card!\n");
g_sd_mounted = true;
}
}
@@ -47,6 +63,12 @@ void unmount_sd(void)
sdmmc_device_finish(&g_sd_device);
g_sd_mounted = false;
}
+
+ /* Disable AHB redirection if necessary. */
+ if (g_ahb_redirect_enabled) {
+ mc_disable_ahb_redirect();
+ g_ahb_redirect_enabled = false;
+ }
}
uint32_t get_file_size(const char *filename)
diff --git a/fusee/fusee-primary/src/fs_utils.h b/fusee/fusee-primary/src/fs_utils.h
index 322e8b9a8..c70df83f6 100644
--- a/fusee/fusee-primary/src/fs_utils.h
+++ b/fusee/fusee-primary/src/fs_utils.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_FS_UTILS_H
#define FUSEE_FS_UTILS_H
diff --git a/fusee/fusee-primary/src/fuse.c b/fusee/fusee-primary/src/fuse.c
index 2bdfa3740..cc5656cc7 100644
--- a/fusee/fusee-primary/src/fuse.c
+++ b/fusee/fusee-primary/src/fuse.c
@@ -1,8 +1,24 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include
-#include "hwinit.h"
+#include "car.h"
#include "fuse.h"
#include "timers.h"
@@ -13,154 +29,155 @@ void fuse_enable_power(void);
void fuse_disable_power(void);
void fuse_wait_idle(void);
-/* Initialize the FUSE driver */
-void fuse_init(void)
-{
- /*
- Already done by hwinit, except maybe fuse_secondary_private_key_disable (?)
- fuse_make_regs_visible();
- fuse_secondary_private_key_disable();
- fuse_disable_programming();
- */
+/* Initialize the fuse driver */
+void fuse_init(void) {
+ fuse_make_regs_visible();
+ 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)
-{
- clock_enable_fuse(1);
+void fuse_make_regs_visible(void) {
+ clkrst_enable_fuse_regs(true);
}
/* Enable power to the fuse hardware array */
-void fuse_enable_power(void)
-{
- FUSE_REGS->FUSE_PWR_GOOD_SW = 1;
- wait(1);
+void fuse_enable_power(void) {
+ volatile tegra_fuse_t *fuse = fuse_get_regs();
+ fuse->FUSE_PWR_GOOD_SW = 1;
+ udelay(1);
}
/* Disable power to the fuse hardware array */
-void fuse_disable_power(void)
-{
- FUSE_REGS->FUSE_PWR_GOOD_SW = 0;
- wait(1);
+void fuse_disable_power(void) {
+ volatile tegra_fuse_t *fuse = fuse_get_regs();
+ fuse->FUSE_PWR_GOOD_SW = 0;
+ udelay(1);
}
/* 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();
uint32_t ctrl_val = 0;
/* Wait for STATE_IDLE */
while ((ctrl_val & (0xF0000)) != 0x40000)
{
- wait(1);
- ctrl_val = FUSE_REGS->FUSE_CTRL;
+ udelay(1);
+ ctrl_val = fuse->FUSE_CTRL;
}
}
/* 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();
fuse_wait_idle();
/* Program the target address */
- FUSE_REGS->FUSE_REG_ADDR = addr;
+ fuse->FUSE_REG_ADDR = addr;
/* Enable read operation in control register */
- uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
+ uint32_t ctrl_val = fuse->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x1; /* Set FUSE_READ command */
- FUSE_REGS->FUSE_CTRL = ctrl_val;
+ fuse->FUSE_CTRL = ctrl_val;
fuse_wait_idle();
- return FUSE_REGS->FUSE_REG_READ;
+ return fuse->FUSE_REG_READ;
}
/* 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();
fuse_wait_idle();
/* Program the target address and value */
- FUSE_REGS->FUSE_REG_ADDR = addr;
- FUSE_REGS->FUSE_REG_WRITE = value;
+ fuse->FUSE_REG_ADDR = addr;
+ fuse->FUSE_REG_WRITE = value;
/* Enable write operation in control register */
- uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
+ uint32_t ctrl_val = fuse->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x2; /* Set FUSE_WRITE command */
- FUSE_REGS->FUSE_CTRL = ctrl_val;
+ fuse->FUSE_CTRL = ctrl_val;
fuse_wait_idle();
}
/* 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();
fuse_wait_idle();
/* Enable sense operation in control register */
- uint32_t ctrl_val = FUSE_REGS->FUSE_CTRL;
+ uint32_t ctrl_val = fuse->FUSE_CTRL;
ctrl_val &= ~0x3;
ctrl_val |= 0x3; /* Set FUSE_SENSE command */
- FUSE_REGS->FUSE_CTRL = ctrl_val;
+ fuse->FUSE_CTRL = ctrl_val;
fuse_wait_idle();
}
/* Disables all fuse programming. */
void fuse_disable_programming(void) {
- FUSE_REGS->FUSE_DIS_PGM = 1;
+ 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) {
- FUSE_REGS->FUSE_PRIVATEKEYDISABLE = 0x10;
+ 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)
-{
- return FUSE_CHIP_REGS->FUSE_SKU_INFO;
+uint32_t fuse_get_sku_info(void) {
+ volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
+ return fuse_chip->FUSE_SKU_INFO;
}
/* Read the bootrom patch version from a register in the shadow cache */
-uint32_t fuse_get_bootrom_patch_version(void)
-{
- return FUSE_CHIP_REGS->FUSE_SOC_SPEEDO_1;
+uint32_t fuse_get_bootrom_patch_version(void) {
+ volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
+ return fuse_chip->FUSE_SOC_SPEEDO_1;
}
/* 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) {
return 0;
}
- return FUSE_CHIP_REGS->FUSE_SPARE_BIT[idx];
+ return fuse_chip->FUSE_SPARE_BIT[idx];
}
/* 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) {
return 0;
}
- return FUSE_CHIP_REGS->FUSE_RESERVED_ODM[idx];
+ return fuse_chip->FUSE_RESERVED_ODM[idx];
}
/* Derive the Device ID using values in the shadow cache */
uint64_t fuse_get_device_id(void) {
+ volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
+
uint64_t device_id = 0;
- uint64_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF;
- uint64_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF;
- uint64_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F;
- uint32_t lot_code = FUSE_CHIP_REGS->FUSE_LOT_CODE_0;
- uint64_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F;
+ uint64_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
+ uint64_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
+ uint64_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
+ uint32_t lot_code = fuse_chip->FUSE_LOT_CODE_0;
+ uint64_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
uint64_t derived_lot_code = 0;
for (unsigned int i = 0; i < 5; i++) {
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
@@ -177,24 +194,27 @@ uint64_t fuse_get_device_id(void) {
/* Get the DRAM ID using values in the shadow cache */
uint32_t fuse_get_dram_id(void) {
- return (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 3) & 0x7;
+ volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
+ return (fuse_chip->FUSE_RESERVED_ODM[4] >> 3) & 0x7;
}
/* Derive the Hardware Type using values in the shadow cache */
uint32_t fuse_get_hardware_type(void) {
+ 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_REGS->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 2) & 1);
+ 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_REGS->FUSE_RESERVED_ODM[4] >> 14) & 0x3C;
+ 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) {
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;
} else {
return 3;
@@ -204,8 +224,10 @@ uint32_t fuse_get_hardware_type(void) {
/* Derive the Retail Type using values in the shadow cache */
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 retail_type = ((FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] >> 7) & 4) | (FUSE_CHIP_REGS->FUSE_RESERVED_ODM[4] & 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. */
return 1;
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
@@ -216,16 +238,17 @@ uint32_t fuse_get_retail_type(void) {
/* Derive the 16-byte Hardware Info using values in the shadow cache, and copy to output buffer. */
void fuse_get_hardware_info(void *dst) {
+ volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
uint32_t hw_info[0x4];
- uint32_t unk_hw_fuse = FUSE_CHIP_REGS->_0x120 & 0x3F;
- uint32_t y_coord = FUSE_CHIP_REGS->FUSE_Y_COORDINATE & 0x1FF;
- uint32_t x_coord = FUSE_CHIP_REGS->FUSE_X_COORDINATE & 0x1FF;
- uint32_t wafer_id = FUSE_CHIP_REGS->FUSE_WAFER_ID & 0x3F;
- uint32_t lot_code_0 = FUSE_CHIP_REGS->FUSE_LOT_CODE_0;
- uint32_t lot_code_1 = FUSE_CHIP_REGS->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
- uint32_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F;
- uint32_t vendor_code = FUSE_CHIP_REGS->FUSE_VENDOR_CODE & 0xF;
+ uint32_t unk_hw_fuse = fuse_chip->_0x120 & 0x3F;
+ uint32_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
+ uint32_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
+ uint32_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
+ uint32_t lot_code_0 = fuse_chip->FUSE_LOT_CODE_0;
+ uint32_t lot_code_1 = fuse_chip->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
+ uint32_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
+ uint32_t vendor_code = fuse_chip->FUSE_VENDOR_CODE & 0xF;
/* Hardware Info = unk_hw_fuse || 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));
diff --git a/fusee/fusee-primary/src/fuse.h b/fusee/fusee-primary/src/fuse.h
index 989f564bf..528b0aff4 100644
--- a/fusee/fusee-primary/src/fuse.h
+++ b/fusee/fusee-primary/src/fuse.h
@@ -1,6 +1,27 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_FUSE_H
#define FUSEE_FUSE_H
+#define FUSE_BASE 0x7000F800
+#define FUSE_CHIP_BASE (FUSE_BASE + 0x100)
+#define MAKE_FUSE_REG(n) MAKE_REG32(FUSE_BASE + n)
+#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
+
typedef struct {
uint32_t FUSE_CTRL;
uint32_t FUSE_REG_ADDR;
@@ -17,7 +38,7 @@ typedef struct {
uint32_t FUSE_WRITE_ACCESS;
uint32_t FUSE_PWR_GOOD_SW;
uint32_t _0x38[0x32];
-} fuse_registers_t;
+} tegra_fuse_t;
typedef struct {
uint32_t FUSE_PRODUCTION_MODE;
@@ -160,17 +181,15 @@ typedef struct {
uint32_t _0x278;
uint32_t _0x27C;
uint32_t FUSE_SPARE_BIT[0x20];
-} fuse_chip_registers_t;
+} tegra_fuse_chip_t;
-static inline volatile fuse_registers_t *get_fuse_regs(void) {
- return (volatile fuse_registers_t *)(0x7000F000 + 0x800);
+static inline volatile tegra_fuse_t *fuse_get_regs(void) {
+ return (volatile tegra_fuse_t *)FUSE_BASE;
}
-static inline volatile fuse_chip_registers_t *get_fuse_chip_regs(void) {
- return (volatile fuse_chip_registers_t *)(0x7000F000 + 0x900);
+static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) {
+ return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE;
}
-#define FUSE_REGS (get_fuse_regs())
-#define FUSE_CHIP_REGS (get_fuse_chip_regs())
void fuse_init(void);
diff --git a/fusee/fusee-primary/src/gpio.c b/fusee/fusee-primary/src/gpio.c
index cfa2f38be..9cfec5c2f 100644
--- a/fusee/fusee-primary/src/gpio.c
+++ b/fusee/fusee-primary/src/gpio.c
@@ -1,10 +1,25 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include
#include "gpio.h"
#include "utils.h"
-#include "lib/printk.h"
/**
* Returns a GPIO bank object that corresponds to the given GPIO pin,
diff --git a/fusee/fusee-primary/src/gpio.h b/fusee/fusee-primary/src/gpio.h
index b3da7dc56..41781a0ca 100644
--- a/fusee/fusee-primary/src/gpio.h
+++ b/fusee/fusee-primary/src/gpio.h
@@ -1,6 +1,27 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_GPIO_H
#define FUSEE_GPIO_H
+#include
+
+#define GPIO_BASE 0x6000D000
+#define MAKE_GPIO_REG(n) MAKE_REG32(GPIO_BASE + n)
+
#define TEGRA_GPIO_PORTS 4
#define TEGRA_GPIO_BANKS 8
#define GPIO_BANK_SHIFT 5
@@ -68,7 +89,7 @@ typedef struct {
static inline volatile tegra_gpio_t *gpio_get_regs(void)
{
- return (volatile tegra_gpio_t *)0x6000D000;
+ return (volatile tegra_gpio_t *)GPIO_BASE;
}
#define TEGRA_GPIO(port, offset) \
@@ -87,9 +108,16 @@ static inline volatile tegra_gpio_t *gpio_get_regs(void)
#define GPIO_LEVEL_HIGH 1
/* Named GPIOs */
+#define GPIO_BUTTON_VOL_DOWN TEGRA_GPIO(X, 7)
+#define GPIO_BUTTON_VOL_UP TEGRA_GPIO(X, 6)
#define GPIO_MICROSD_CARD_DETECT TEGRA_GPIO(Z, 1)
#define GPIO_MICROSD_WRITE_PROTECT TEGRA_GPIO(Z, 4)
#define GPIO_MICROSD_SUPPLY_ENABLE TEGRA_GPIO(E, 4)
+#define GPIO_LCD_BL_P5V TEGRA_GPIO(I, 0)
+#define GPIO_LCD_BL_N5V TEGRA_GPIO(I, 1)
+#define GPIO_LCD_BL_PWM TEGRA_GPIO(V, 0)
+#define GPIO_LCD_BL_EN TEGRA_GPIO(V, 1)
+#define GPIO_LCD_BL_RST TEGRA_GPIO(V, 2)
void gpio_configure_mode(uint32_t pin, uint32_t mode);
void gpio_configure_direction(uint32_t pin, uint32_t dir);
diff --git a/fusee/fusee-primary/src/hwinit.c b/fusee/fusee-primary/src/hwinit.c
new file mode 100644
index 000000000..d3c7b82a2
--- /dev/null
+++ b/fusee/fusee-primary/src/hwinit.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "hwinit.h"
+#include "apb_misc.h"
+#include "car.h"
+#include "di.h"
+#include "fuse.h"
+#include "gpio.h"
+#include "i2c.h"
+#include "max77620.h"
+#include "mc.h"
+#include "pinmux.h"
+#include "pmc.h"
+#include "se.h"
+#include "sdram.h"
+#include "sysctr0.h"
+#include "sysreg.h"
+#include "timers.h"
+#include "uart.h"
+
+void config_oscillators()
+{
+ volatile tegra_car_t *car = car_get_regs();
+ volatile tegra_pmc_t *pmc = pmc_get_regs();
+
+ car->spare_reg0 = ((car->spare_reg0 & 0xFFFFFFF3) | 4);
+
+ SYSCTR0_CNTFID0_0 = 19200000;
+ TIMERUS_USEC_CFG_0 = 0x45F;
+
+ car->osc_ctrl = 0x50000071;
+ pmc->osc_edpd_over = ((pmc->osc_edpd_over & 0xFFFFFF81) | 0xE);
+ pmc->osc_edpd_over = ((pmc->osc_edpd_over & 0xFFBFFFFF) | 0x400000);
+ pmc->cntrl2 = ((pmc->cntrl2 & 0xFFFFEFFF) | 0x1000);
+ pmc->scratch188 = ((pmc->scratch188 & 0xFCFFFFFF) | 0x2000000);
+ car->clk_sys_rate = 0x10;
+ car->pllmb_base &= 0xBFFFFFFF;
+ pmc->tsc_mult = ((pmc->tsc_mult & 0xFFFF0000) | 0x249F); /* 0x249F = 19200000 * (16 / 32.768 kHz) */
+ car->sclk_brst_pol = 0x20004444;
+ car->super_sclk_div = 0x80000000;
+ car->clk_sys_rate = 2;
+}
+
+void config_gpios()
+{
+ volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
+
+ pinmux->uart2_tx = 0;
+ pinmux->uart3_tx = 0;
+ pinmux->pe6 = PINMUX_INPUT;
+ pinmux->ph6 = PINMUX_INPUT;
+
+ gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO);
+ gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO);
+ gpio_configure_mode(TEGRA_GPIO(E, 6), GPIO_MODE_GPIO);
+ gpio_configure_mode(TEGRA_GPIO(H, 6), GPIO_MODE_GPIO);
+ gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT);
+ gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT);
+ gpio_configure_direction(TEGRA_GPIO(E, 6), GPIO_DIRECTION_INPUT);
+ gpio_configure_direction(TEGRA_GPIO(H, 6), GPIO_DIRECTION_INPUT);
+
+ pinmux->gen1_i2c_scl = PINMUX_INPUT;
+ pinmux->gen1_i2c_sda = PINMUX_INPUT;
+ pinmux->pwr_i2c_scl = PINMUX_INPUT;
+ pinmux->pwr_i2c_sda = PINMUX_INPUT;
+ pinmux->uart1_rx = 0;
+ pinmux->uart1_tx = (PINMUX_INPUT | PINMUX_PULL_UP);
+ pinmux->uart1_rts = 0;
+ pinmux->uart1_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
+
+ /* Configure volume up/down as inputs. */
+ gpio_configure_mode(GPIO_BUTTON_VOL_UP, GPIO_MODE_GPIO);
+ gpio_configure_mode(GPIO_BUTTON_VOL_DOWN, GPIO_MODE_GPIO);
+ gpio_configure_direction(GPIO_BUTTON_VOL_UP, GPIO_DIRECTION_INPUT);
+ gpio_configure_direction(GPIO_BUTTON_VOL_DOWN, GPIO_DIRECTION_INPUT);
+}
+
+void config_pmc_scratch()
+{
+ volatile tegra_pmc_t *pmc = pmc_get_regs();
+
+ pmc->scratch20 &= 0xFFF3FFFF;
+ pmc->scratch190 &= 0xFFFFFFFE;
+ pmc->secure_scratch21 |= 0x10;
+}
+
+void mbist_workaround()
+{
+ volatile tegra_car_t *car = car_get_regs();
+
+ car->clk_source_sor1 = ((car->clk_source_sor1 | 0x8000) & 0xFFFFBFFF);
+ car->plld_base |= 0x40800000u;
+ car->rst_dev_y_clr = 0x40;
+ car->rst_dev_x_clr = 0x40000;
+ car->rst_dev_l_clr = 0x18000000;
+ udelay(2);
+
+ /* Setup I2S. */
+ MAKE_I2S_REG(0x0A0) |= 0x400;
+ MAKE_I2S_REG(0x088) &= 0xFFFFFFFE;
+ MAKE_I2S_REG(0x1A0) |= 0x400;
+ MAKE_I2S_REG(0x188) &= 0xFFFFFFFE;
+ MAKE_I2S_REG(0x2A0) |= 0x400;
+ MAKE_I2S_REG(0x288) &= 0xFFFFFFFE;
+ MAKE_I2S_REG(0x3A0) |= 0x400;
+ MAKE_I2S_REG(0x388) &= 0xFFFFFFFE;
+ MAKE_I2S_REG(0x4A0) |= 0x400;
+ MAKE_I2S_REG(0x488) &= 0xFFFFFFFE;
+
+ MAKE_DI_REG(DC_COM_DSC_TOP_CTL) |= 4;
+ MAKE_VIC_REG(0x8C) = 0xFFFFFFFF;
+ udelay(2);
+
+ /* Set devices in reset. */
+ car->rst_dev_y_set = 0x40;
+ car->rst_dev_l_set = 0x18000000;
+ car->rst_dev_x_set = 0x40000;
+
+ /* Clock out enables. */
+ car->clk_out_enb_h = 0xC0;
+ car->clk_out_enb_l = 0x80000130;
+ car->clk_out_enb_u = 0x1F00200;
+ car->clk_out_enb_v = 0x80400808;
+ car->clk_out_enb_w = 0x402000FC;
+ car->clk_out_enb_x = 0x23000780;
+ car->clk_out_enb_y = 0x300;
+
+ /* LVL2 clock gate overrides. */
+ car->lvl2_clk_gate_ovra = 0;
+ car->lvl2_clk_gate_ovrb = 0;
+ car->lvl2_clk_gate_ovrc = 0;
+ car->lvl2_clk_gate_ovrd = 0;
+ car->lvl2_clk_gate_ovre = 0;
+
+ /* Configure clock sources. */
+ car->plld_base &= 0x1F7FFFFF;
+ car->clk_source_sor1 &= 0xFFFF3FFF;
+ car->clk_source_vi = ((car->clk_source_vi & 0x1FFFFFFF) | 0x80000000);
+ car->clk_source_host1x = ((car->clk_source_host1x & 0x1FFFFFFF) | 0x80000000);
+ car->clk_source_nvenc = ((car->clk_source_nvenc & 0x1FFFFFFF) | 0x80000000);
+}
+
+void config_se_brom()
+{
+ volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
+ volatile tegra_se_t *se = se_get_regs();
+ volatile tegra_pmc_t *pmc = pmc_get_regs();
+
+ /* Bootrom part we skipped. */
+ uint32_t sbk[4] = {fuse_chip->FUSE_PRIVATE_KEY[0], fuse_chip->FUSE_PRIVATE_KEY[1], fuse_chip->FUSE_PRIVATE_KEY[2], fuse_chip->FUSE_PRIVATE_KEY[3]};
+ set_aes_keyslot(0xE, sbk, 0x10);
+
+ /* Lock SBK from being read. */
+ se->AES_KEYSLOT_FLAGS[0xE] = 0x7E;
+
+ /* This memset needs to happen here, else TZRAM will behave weirdly later on. */
+ memset((void *)0x7C010000, 0, 0x10000);
+
+ pmc->crypto_op = 0;
+ se->INT_STATUS_REG = 0x1F;
+
+ /* Lock SSK (although it's not set and unused anyways). */
+ se->AES_KEYSLOT_FLAGS[0xF] = 0x7E;
+
+ /* Clear the boot reason to avoid problems later */
+ pmc->scratch200 = 0;
+ pmc->reset_status = 0;
+}
+
+void nx_hwinit()
+{
+ volatile tegra_pmc_t *pmc = pmc_get_regs();
+ volatile tegra_car_t *car = car_get_regs();
+
+ /* Bootrom stuff we skipped by going through RCM. */
+ config_se_brom();
+
+ AHB_AHB_SPARE_REG_0 &= 0xFFFFFF9F;
+ pmc->scratch49 = (((pmc->scratch49 >> 1) << 1) & 0xFFFFFFFD);
+
+ /* Apply the memory built-in self test workaround. */
+ mbist_workaround();
+
+ /* Reboot SE. */
+ clkrst_reboot(CARDEVICE_SE);
+
+ /* Initialize the fuse driver. */
+ fuse_init();
+
+ /* Initialize the memory controller. */
+ mc_enable();
+
+ /* Configure oscillators. */
+ config_oscillators();
+
+ /* Disable pinmux tristate input clamping. */
+ APB_MISC_PP_PINMUX_GLOBAL_0 = 0;
+
+ /* Configure GPIOs. */
+ /* NOTE: [3.0.0+] Part of the GPIO configuration is skipped if the unit is SDEV. */
+ /* NOTE: [6.0.0+] The GPIO configuration's order was changed a bit. */
+ config_gpios();
+
+ /* Uncomment for UART debugging. */
+ /*
+ clkrst_reboot(CARDEVICE_UARTC);
+ uart_init(UART_C, 115200);
+ */
+
+ /* Reboot CL-DVFS. */
+ clkrst_reboot(CARDEVICE_CL_DVFS);
+
+ /* Reboot I2C1. */
+ clkrst_reboot(CARDEVICE_I2C1);
+
+ /* Reboot I2C5. */
+ clkrst_reboot(CARDEVICE_I2C5);
+
+ /* Reboot SE. */
+ /* NOTE: [4.0.0+] This was removed. */
+ /* clkrst_reboot(CARDEVICE_SE); */
+
+ /* Reboot unknown device. */
+ clkrst_reboot(CARDEVICE_UNK);
+
+ /* Initialize I2C1. */
+ /* NOTE: [6.0.0+] This was moved to after the PMIC is configured. */
+ i2c_init(I2C_1);
+
+ /* Initialize I2C5. */
+ i2c_init(I2C_5);
+
+ /* Configure the PMIC. */
+ uint8_t val = 0x40;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
+ val = 0x60;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
+ val = 0x38;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1);
+ val = 0x3A;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG1, &val, 1);
+ val = 0x38;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG2, &val, 1);
+ val = 0xF;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO4, &val, 1);
+ val = 0xC7;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO8, &val, 1);
+ val = 0x4F;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD0, &val, 1);
+ val = 0x29;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD1, &val, 1);
+ val = 0x1B;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD3, &val, 1);
+
+ /* NOTE: [3.0.0+] This was added. */
+ val = 0x22;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_GPIO3, &val, 1);
+
+ /* TODO: In 3.x+, if the unit is SDEV, the MBLPD bit is set. */
+ /*
+ i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
+ val |= 0x40;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
+ */
+
+ /* Configure SD0 voltage. */
+ val = 42; /* 42 = (1125000 - 600000) / 12500 -> 1.125V */
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD0, &val, 1);
+
+ /* Configure and lock PMC scratch registers. */
+ /* NOTE: [4.0.0+] This was removed. */
+ config_pmc_scratch();
+
+ /* Set super clock burst policy. */
+ car->sclk_brst_pol = ((car->sclk_brst_pol & 0xFFFF8888) | 0x3333);
+
+ /* Configure memory controller carveouts. */
+ /* NOTE: [4.0.0+] This is now done in the Secure Monitor. */
+ /* mc_config_carveout(); */
+
+ /* Initialize SDRAM. */
+ sdram_init();
+
+ /* Save SDRAM LP0 parameters. */
+ sdram_lp0_save_params(sdram_get_params());
+}
\ No newline at end of file
diff --git a/fusee/fusee-primary/src/hwinit.h b/fusee/fusee-primary/src/hwinit.h
index 7b66f07b7..d76512ef3 100644
--- a/fusee/fusee-primary/src/hwinit.h
+++ b/fusee/fusee-primary/src/hwinit.h
@@ -1,39 +1,27 @@
-#ifndef FUSEE_HWINIT_H
-#define FUSEE_HWINIT_H
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_HWINIT_H_
+#define FUSEE_HWINIT_H_
-/* Symbols from hwinit that we're using, but w/o importing macro definitions that may clash with ours */
+#define I2S_BASE 0x702D1000
+#define MAKE_I2S_REG(n) MAKE_REG32(I2S_BASE + n)
-#include "hwinit/types.h"
-#include "hwinit/hwinit.h"
-#include "hwinit/i2c.h"
+void nx_hwinit();
-#include
-
-#define UART_A 0
-#define UART_B 1
-#define UART_C 2
-#define BAUD_115200 115200
-
-void uart_init(u32 idx, u32 baud);
-void uart_wait_idle(u32 idx, u32 which);
-void uart_send(u32 idx, u8 *buf, u32 len);
-void uart_recv(u32 idx, u8 *buf, u32 len);
-
-void display_init();
-void display_end();
-
-void clock_enable_fuse(u32 enable);
-
-/*! Show one single color on the display. */
-void display_color_screen(u32 color);
-
-/*! Init display in full 1280x720 resolution (32bpp, line stride 768, framebuffer size = 1280*768*4 bytes). */
-u32 *display_init_framebuffer(void *address);
-
-/*! Enable or disable the backlight. Should only be called when the screen is completely set up, to avoid flickering. */
-void display_enable_backlight(bool on);
-
-void cluster_enable_cpu0(u64 entry, u32 ns_disable);
-
-void mc_enable_ahb_redirect();
#endif
diff --git a/fusee/fusee-primary/src/hwinit/btn.c b/fusee/fusee-primary/src/hwinit/btn.c
deleted file mode 100644
index 50bf1b37d..000000000
--- a/fusee/fusee-primary/src/hwinit/btn.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#include "btn.h"
-#include "i2c.h"
-#include "t210.h"
-
-u32 btn_read()
-{
- u32 res = 0;
- if(!(GPIO_6(0x3C) & 0x80))
- res |= BTN_VOL_DOWN;
- if(!(GPIO_6(0x3C) & 0x40))
- res |= BTN_VOL_UP;
- if(i2c_recv_byte(4, 0x3C, 0x15) & 0x4)
- res |= BTN_POWER;
- return res;
-}
-
-u32 btn_wait()
-{
- u32 res = 0, btn = btn_read();
- do
- {
- res = btn_read();
- } while (btn == res);
- return res;
-}
diff --git a/fusee/fusee-primary/src/hwinit/btn.h b/fusee/fusee-primary/src/hwinit/btn.h
deleted file mode 100644
index 7ae7af9e7..000000000
--- a/fusee/fusee-primary/src/hwinit/btn.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _BTN_H_
-#define _BTN_H_
-
-#include "types.h"
-
-#define BTN_POWER 0x1
-#define BTN_VOL_DOWN 0x2
-#define BTN_VOL_UP 0x4
-
-u32 btn_read();
-u32 btn_wait();
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/clock.c b/fusee/fusee-primary/src/hwinit/clock.c
deleted file mode 100644
index b0b4ab93b..000000000
--- a/fusee/fusee-primary/src/hwinit/clock.c
+++ /dev/null
@@ -1,145 +0,0 @@
-#include "clock.h"
-#include "t210.h"
-#include "util.h"
-
-static const clock_t _clock_uart[] = {
- /* UART A */ { 4, 0x10, 0x178, 6, 0, 0 },
- /* UART B */ { 4, 0x10, 0x17C, 7, 0, 0 },
- /* UART C */ { 8, 0x14, 0x1A0, 0x17, 0, 0 },
- /* UART D */ { 0 },
- /* UART E */ { 0 }
-};
-
-static const clock_t _clock_i2c[] = {
- /* I2C1 */ { 4, 0x10, 0x124, 0xC, 6, 0 },
- /* I2C2 */ { 0 },
- /* I2C3 */ { 0 },
- /* I2C4 */ { 0 },
- /* I2C5 */ { 8, 0x14, 0x128, 0xF, 6, 0 },
- /* I2C6 */ { 0 }
-};
-
-static clock_t _clock_se = { 0x358, 0x360, 0x42C, 0x1F, 0, 0 };
-
-static clock_t _clock_host1x = { 4, 0x10, 0x180, 0x1C, 4, 3 };
-static clock_t _clock_tsec = { 0xC, 0x18, 0x1F4, 0x13, 0, 2 };
-static clock_t _clock_sor_safe = { 0x2A4, 0x298, 0, 0x1E, 0, 0 };
-static clock_t _clock_sor0 = { 0x28C, 0x280, 0, 0x16, 0, 0 };
-static clock_t _clock_sor1 = { 0x28C, 0x280, 0x410, 0x17, 0, 2 };
-static clock_t _clock_kfuse = { 8, 0x14, 0, 8, 0, 0 };
-
-static clock_t _clock_coresight = { 0xC, 0x18, 0x1D4, 9, 0, 4};
-
-void clock_enable(const clock_t *clk)
-{
- //Put clock into reset.
- CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index);
- //Disable.
- CLOCK(clk->enable) &= ~(1 << clk->index);
- //Configure clock source if required.
- if (clk->source)
- CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
- //Enable.
- CLOCK(clk->enable) = CLOCK(clk->enable) & ~(1 << clk->index) | (1 << clk->index);
- //Take clock off reset.
- CLOCK(clk->reset) &= ~(1 << clk->index);
-}
-
-void clock_disable(const clock_t *clk)
-{
- //Put clock into reset.
- CLOCK(clk->reset) = CLOCK(clk->reset) & ~(1 << clk->index) | (1 << clk->index);
- //Disable.
- CLOCK(clk->enable) &= ~(1 << clk->index);
-}
-
-void clock_enable_fuse(u32 enable)
-{
- CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) = CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) & 0xEFFFFFFF | ((enable & 1) << 28) & 0x10000000;
-}
-
-void clock_enable_uart(u32 idx)
-{
- clock_enable(&_clock_uart[idx]);
-}
-
-void clock_enable_i2c(u32 idx)
-{
- clock_enable(&_clock_i2c[idx]);
-}
-
-void clock_enable_se()
-{
- clock_enable(&_clock_se);
-}
-
-void clock_enable_host1x()
-{
- clock_enable(&_clock_host1x);
-}
-
-void clock_enable_tsec()
-{
- clock_enable(&_clock_tsec);
-}
-
-void clock_enable_sor_safe()
-{
- clock_enable(&_clock_sor_safe);
-}
-
-void clock_enable_sor0()
-{
- clock_enable(&_clock_sor0);
-}
-
-void clock_enable_sor1()
-{
- clock_enable(&_clock_sor1);
-}
-
-void clock_enable_kfuse()
-{
- //clock_enable(&_clock_kfuse);
- CLOCK(0x8) = CLOCK(0x8) & 0xFFFFFEFF | 0x100;
- CLOCK(0x14) &= 0xFFFFFEFF;
- CLOCK(0x14) = CLOCK(0x14) & 0xFFFFFEFF | 0x100;
- sleep(10);
- CLOCK(0x8) &= 0xFFFFFEFF;
- sleep(20);
-}
-
-void clock_disable_host1x()
-{
- clock_disable(&_clock_host1x);
-}
-
-void clock_disable_tsec()
-{
- clock_disable(&_clock_tsec);
-}
-
-void clock_disable_sor_safe()
-{
- clock_disable(&_clock_sor_safe);
-}
-
-void clock_disable_sor0()
-{
- clock_disable(&_clock_sor0);
-}
-
-void clock_disable_sor1()
-{
- clock_disable(&_clock_sor1);
-}
-
-void clock_disable_kfuse()
-{
- clock_disable(&_clock_kfuse);
-}
-
-void clock_enable_coresight()
-{
- clock_enable(&_clock_coresight);
-}
diff --git a/fusee/fusee-primary/src/hwinit/clock.h b/fusee/fusee-primary/src/hwinit/clock.h
deleted file mode 100644
index 027fd4b26..000000000
--- a/fusee/fusee-primary/src/hwinit/clock.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _CLOCK_H_
-#define _CLOCK_H_
-
-#include "types.h"
-
-/*! Clock registers. */
-#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY 0x28
-#define CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER 0x2C
-#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30
-#define CLK_RST_CONTROLLER_MISC_CLK_ENB 0x48
-#define CLK_RST_CONTROLLER_OSC_CTRL 0x50
-#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19C
-#define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284
-#define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308
-#define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328
-#define CLK_RST_CONTROLLER_RST_DEVICES_V 0x358
-#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR 0x454
-#define CLK_RST_CONTROLLER_SPARE_REG0 0x55C
-#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
-
-typedef struct _clock_t
-{
- u32 reset;
- u32 enable;
- u32 source;
- u8 index;
- u8 clk_src;
- u8 clk_div;
-} clock_t;
-
-void clock_enable(const clock_t *clk);
-void clock_disable(const clock_t *clk);
-void clock_enable_fuse(u32 enable);
-void clock_enable_uart(u32 idx);
-void clock_enable_i2c(u32 idx);
-void clock_enable_se();
-void clock_enable_host1x();
-void clock_enable_tsec();
-void clock_enable_sor_safe();
-void clock_enable_sor0();
-void clock_enable_sor1();
-void clock_enable_kfuse();
-void clock_disable_host1x();
-void clock_disable_tsec();
-void clock_disable_sor_safe();
-void clock_disable_sor0();
-void clock_disable_sor1();
-void clock_disable_kfuse();
-void clock_enable_coresight();
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/cluster.c b/fusee/fusee-primary/src/hwinit/cluster.c
deleted file mode 100644
index 90015205f..000000000
--- a/fusee/fusee-primary/src/hwinit/cluster.c
+++ /dev/null
@@ -1,114 +0,0 @@
-#include "cluster.h"
-#include "i2c.h"
-#include "clock.h"
-#include "util.h"
-#include "pmc.h"
-#include "t210.h"
-
-void _cluster_enable_power()
-{
- u8 tmp;
-
- if (i2c_recv_buf_small(&tmp, 1, I2C_5, 0x3C, 0x40))
- {
- tmp &= 0xDFu;
- i2c_send_byte(I2C_5, 0x3C, 0x40, tmp);
- }
- i2c_send_byte(I2C_5, 0x3C, 0x3B, 0x09);
-
- //Enable cores power.
- i2c_send_byte(I2C_5, 0x1B, 0x02, 0x20);
- i2c_send_byte(I2C_5, 0x1B, 0x03, 0x8D);
- i2c_send_byte(I2C_5, 0x1B, 0x00, 0xB7);
- i2c_send_byte(I2C_5, 0x1B, 0x01, 0xB7);
-}
-
-int _cluster_pmc_enable_partition(u32 part, u32 toggle)
-{
- //Check if the partition has already been turned on.
- if (PMC(APBDEV_PMC_PWRGATE_STATUS) & part)
- return 0;
-
- u32 i = 5001;
- while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)
- {
- sleep(1);
- i--;
- if (i < 1)
- return 0;
- }
-
- PMC(APBDEV_PMC_PWRGATE_TOGGLE) = toggle | 0x100;
-
- i = 5001;
- while (i > 0)
- {
- if (PMC(APBDEV_PMC_PWRGATE_STATUS) & part)
- break;
- sleep(1);
- i--;
- }
-
- return 1;
-}
-
-void cluster_enable_cpu0(u64 entry, u32 ns_disable)
-{
- //Set ACTIVE_CLUSER to FAST.
- FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE;
-
- _cluster_enable_power();
-
- if (!(CLOCK(0xE0) & 0x40000000))
- {
- CLOCK(0x518) &= 0xFFFFFFF7;
- sleep(2);
- CLOCK(0xE4) = CLOCK(0xE4) & 0xFFFBFFFF | 0x40000;
- CLOCK(0xE0) = 0x40404E02;
- }
- while (!(CLOCK(0xE0) & 0x8000000))
- ;
-
- CLOCK(0x3B4) = CLOCK(0x3B4) & 0x1FFFFF00 | 6;
- CLOCK(0x360) = CLOCK(0x360) & 0xFFFFFFF7 | 8;
- CLOCK(0x20) = 0x20008888;
- CLOCK(0x24) = 0x80000000;
- CLOCK(0x440) = 1;
-
- clock_enable_coresight();
-
- CLOCK(0x388) = CLOCK(0x388) & 0xFFFFE000;
-
- //Enable CPU rail.
- _cluster_pmc_enable_partition(1, 0);
- //Enable cluster 0 non-CPU.
- _cluster_pmc_enable_partition(0x8000, 15);
- //Enable CE0.
- _cluster_pmc_enable_partition(0x4000, 14);
-
- //Request and wait for RAM repair.
- FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1;
- while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & 2))
- ;
-
- EXCP_VEC(0x100) = 0;
-
- if(ns_disable)
- {
- //Set reset vectors.
- SB(SB_AA64_RESET_LOW) = (u32)entry | 1;
- SB(SB_AA64_RESET_HIGH) = (u32)(entry >> 32);
- //Non-secure reset vector write disable.
- SB(SB_CSR_0) = 2;
- }
- else
- {
- //Set reset vectors.
- SB(SB_AA64_RESET_LOW) = (u32)entry;
- SB(SB_AA64_RESET_HIGH) = (u32)(entry >> 32);
- }
-
- //Until here the CPU was in reset, this kicks execution.
- CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7;
- CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x411F000F;
-}
diff --git a/fusee/fusee-primary/src/hwinit/cluster.h b/fusee/fusee-primary/src/hwinit/cluster.h
deleted file mode 100644
index 41ae68f52..000000000
--- a/fusee/fusee-primary/src/hwinit/cluster.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _CLUSTER_H_
-#define _CLUSTER_H_
-
-#include "types.h"
-
-/*! Flow controller registers. */
-#define FLOW_CTLR_RAM_REPAIR 0x40
-#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98
-
-void cluster_enable_cpu0(u64 entry, u32 ns_disable);
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/di.c b/fusee/fusee-primary/src/hwinit/di.c
deleted file mode 100644
index a168f8dc4..000000000
--- a/fusee/fusee-primary/src/hwinit/di.c
+++ /dev/null
@@ -1,209 +0,0 @@
-#include "di.h"
-#include "t210.h"
-#include "util.h"
-#include "i2c.h"
-#include "pmc.h"
-
-#include "di.inl"
-
-static u32 _display_ver = 0;
-
-static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
-{
- u32 end = TMR(0x10) + timeout;
- while (TMR(0x10) < end && DSI(off) & mask)
- ;
- sleep(5);
-}
-
-void display_init()
-{
- //Power on.
- i2c_send_byte(I2C_5, 0x3C, 0x23, 0xD0);
- i2c_send_byte(I2C_5, 0x3C, 0x3D, 0x09);
-
- //Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks.
- CLOCK(0x30C) = 0x1010000;
- CLOCK(0x328) = 0x1010000;
- CLOCK(0x304) = 0x18000000;
- CLOCK(0x320) = 0x18000000;
- CLOCK(0x284) = 0x20000;
- CLOCK(0x66C) = 0xA;
- CLOCK(0x448) = 0x80000;
- CLOCK(0x620) = 0xA;
-
- //DPD idle.
- PMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000;
- PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000;
-
- //Config pins.
- PINMUX_AUX(0x1D0) &= 0xFFFFFFEF;
- PINMUX_AUX(0x1D4) &= 0xFFFFFFEF;
- PINMUX_AUX(0x1FC) &= 0xFFFFFFEF;
- PINMUX_AUX(0x200) &= 0xFFFFFFEF;
- PINMUX_AUX(0x204) &= 0xFFFFFFEF;
-
- GPIO_3(0x00) = GPIO_3(0x00) & 0xFFFFFFFC | 0x3;
- GPIO_3(0x10) = GPIO_3(0x10) & 0xFFFFFFFC | 0x3;
- GPIO_3(0x20) = GPIO_3(0x20) & 0xFFFFFFFE | 0x1;
-
- sleep(10000u);
-
- GPIO_3(0x20) = GPIO_3(0x20) & 0xFFFFFFFD | 0x2;
-
- sleep(10000);
-
- GPIO_6(0x04) = GPIO_6(0x04) & 0xFFFFFFF8 | 0x7;
- GPIO_6(0x14) = GPIO_6(0x14) & 0xFFFFFFF8 | 0x7;
- GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFD | 0x2;
-
- //Config display interface and display.
- MIPI_CAL(0x60) = 0;
-
- exec_cfg((u32 *)CLOCK_BASE, _display_config_1, 4);
- exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_2, 94);
- exec_cfg((u32 *)DSI_BASE, _display_config_3, 60);
-
- sleep(10000);
-
- GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFB | 0x4;
-
- sleep(60000);
-
- DSI(_DSIREG(DSI_DSI_BTA_TIMING)) = 0x50204;
- DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x337;
- DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;
- _display_dsi_wait(250000, _DSIREG(DSI_DSI_TRIGGER), 3);
-
- DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x406;
- DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;
- _display_dsi_wait(250000, _DSIREG(DSI_DSI_TRIGGER), 3);
-
- DSI(_DSIREG(DSI_HOST_DSI_CONTROL)) = 0x200B;
- _display_dsi_wait(150000, _DSIREG(DSI_HOST_DSI_CONTROL), 8);
-
- sleep(5000);
-
- _display_ver = DSI(_DSIREG(DSI_DSI_RD_DATA));
- if (_display_ver == 0x10)
- exec_cfg((u32 *)DSI_BASE, _display_config_4, 43);
-
- DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x1105;
- DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;
-
- sleep(180000);
-
- DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x2905;
- DSI(_DSIREG(DSI_DSI_TRIGGER)) = 0x2;
-
- sleep(20000);
-
- exec_cfg((u32 *)DSI_BASE, _display_config_5, 21);
- exec_cfg((u32 *)CLOCK_BASE, _display_config_6, 3);
- DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4;
- exec_cfg((u32 *)DSI_BASE, _display_config_7, 10);
-
- sleep(10000);
-
- exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_8, 6);
- exec_cfg((u32 *)DSI_BASE, _display_config_9, 4);
- exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_10, 16);
-
- sleep(10000);
-
- exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_11, 113);
-}
-
-void display_end()
-{
- GPIO_6(0x24) &= 0xFFFFFFFE;
- DSI(_DSIREG(DSI_DSI_VID_MODE_CONTROL)) = 1;
- DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x2805;
-
- u32 end = HOST1X(0x30A4) + 5;
- while (HOST1X(0x30A4) < end)
- ;
-
- DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = 5;
- DSI(_DSIREG(DSI_DSI_VID_MODE_CONTROL)) = 0;
-
- exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_12, 17);
- exec_cfg((u32 *)DSI_BASE, _display_config_13, 16);
-
- sleep(10000);
-
- if (_display_ver == 0x10)
- exec_cfg((u32 *)DSI_BASE, _display_config_14, 22);
-
- DSI(_DSIREG(DSI_DSI_WR_DATA)) = 0x1005;
- DSI(_DSIREG(DSI_DSI_TRIGGER)) = 2;
-
- sleep(50000);
-
- GPIO_6(0x24) &= 0xFFFFFFFB;
-
- sleep(10000);
-
- GPIO_3(0x20) &= 0xFFFFFFFD;
-
- sleep(10000);
-
- GPIO_3(0x20) = (GPIO_3(0x20) >> 1) << 1;
-
- sleep(10000);
-
- //Disable clocks.
- CLOCK(0x308) = 0x1010000;
- CLOCK(0x32C) = 0x1010000;
- CLOCK(0x300) = 0x18000000;
- CLOCK(0x324) = 0x18000000;
-
- DSI(_DSIREG(DSI_PAD_CONTROL)) = 0x10F010F;
- DSI(_DSIREG(DSI_DSI_POWER_CONTROL)) = 0;
-
- GPIO_6(0x04) &= 0xFFFFFFFE;
-
- PINMUX_AUX(0x1FC) = PINMUX_AUX(0x1FC) & 0xFFFFFFEF | 0x10;
- PINMUX_AUX(0x1FC) = (PINMUX_AUX(0x1FC) >> 2) << 2 | 1;
-}
-
-void display_color_screen(u32 color)
-{
- exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8);
-
- //Configure display to show single color.
- DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;
- DISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0;
- DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;
- DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
- DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE | 1;
-
- sleep(35000);
-
- GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFE | 1;
-}
-
-void display_enable_backlight(bool on) {
- GPIO_6(0x24) = GPIO_6(0x24) & 0xFFFFFFFE | !!on;
-}
-
-
-u32 *display_init_framebuffer(void *address)
-{
- static cfg_op_t conf[sizeof(cfg_display_framebuffer)/sizeof(cfg_op_t)] = {0};
- if(conf[0].val == 0) {
- for (u32 i = 0; i < sizeof(cfg_display_framebuffer)/sizeof(cfg_op_t); i++) {
- conf[i] = cfg_display_framebuffer[i];
- }
- }
-
- u32 *lfb_addr = (u32 *)address;
-
- conf[19].val = (u32)address;
- //This configures the framebuffer @ address with a resolution of 1280x720 (line stride 768).
- exec_cfg((u32 *)DISPLAY_A_BASE, conf, 32);
-
- sleep(35000);
-
- return lfb_addr;
-}
diff --git a/fusee/fusee-primary/src/hwinit/di.h b/fusee/fusee-primary/src/hwinit/di.h
deleted file mode 100644
index 9d482e072..000000000
--- a/fusee/fusee-primary/src/hwinit/di.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef _DI_H_
-#define _DI_H_
-
-#include "types.h"
-#include
-
-/*! Display registers. */
-#define _DIREG(reg) ((reg) * 4)
-#define DC_CMD_DISPLAY_COMMAND 0x32
-#define DC_CMD_STATE_ACCESS 0x40
-#define DC_CMD_STATE_CONTROL 0x41
-#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
-#define DC_DISP_DISP_WIN_OPTIONS 0x402
-#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
-#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
-#define DC_WIN_AD_WIN_OPTIONS 0xB80
-#define DC_WIN_BD_WIN_OPTIONS 0xD80
-#define DC_WIN_CD_WIN_OPTIONS 0xF80
-
-//The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).
-#define DC_X_WIN_XD_WIN_OPTIONS 0x700
-#define DC_X_WIN_XD_COLOR_DEPTH 0x703
-#define DC_X_WIN_XD_POSITION 0x704
-#define DC_X_WIN_XD_SIZE 0x705
-#define DC_X_WIN_XD_PRESCALED_SIZE 0x706
-#define DC_X_WIN_XD_H_INITIAL_DDA 0x707
-#define DC_X_WIN_XD_V_INITIAL_DDA 0x708
-#define DC_X_WIN_XD_DDA_INCREMENT 0x709
-#define DC_X_WIN_XD_LINE_STRIDE 0x70A
-
-//The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER).
-#define DC_X_WINBUF_XD_START_ADDR 0x800
-#define DC_X_WINBUF_XD_ADDR_H_OFFSET 0x806
-#define DC_X_WINBUF_XD_ADDR_V_OFFSET 0x808
-#define DC_X_WINBUF_XD_SURFACE_KIND 0x80B
-
-/*! Display serial interface registers. */
-#define _DSIREG(reg) ((reg) * 4)
-#define DSI_DSI_RD_DATA 0x9
-#define DSI_DSI_WR_DATA 0xA
-#define DSI_DSI_POWER_CONTROL 0xB
-#define DSI_HOST_DSI_CONTROL 0xF
-#define DSI_DSI_TRIGGER 0x13
-#define DSI_DSI_BTA_TIMING 0x3F
-#define DSI_PAD_CONTROL 0x4B
-#define DSI_DSI_VID_MODE_CONTROL 0x4E
-
-void display_init();
-void display_end();
-
-/*! Show one single color on the display. */
-void display_color_screen(u32 color);
-
-/*! Init display in full 1280x720 resolution (32bpp, line stride 768, framebuffer size = 1280*768*4 bytes). */
-u32 *display_init_framebuffer(void *address);
-
-/*! Enable or disable the backlight. Should only be called when the screen is completely set up, to avoid flickering. */
-void display_enable_backlight(bool on);
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/di.inl b/fusee/fusee-primary/src/hwinit/di.inl
deleted file mode 100644
index b2e6d1533..000000000
--- a/fusee/fusee-primary/src/hwinit/di.inl
+++ /dev/null
@@ -1,532 +0,0 @@
-//Clock config.
-static const cfg_op_t _display_config_1[4] = {
- {0x4E, 0x40000000}, //CLK_RST_CONTROLLER_CLK_SOURCE_DISP1
- {0x34, 0x4830A001}, //CLK_RST_CONTROLLER_PLLD_BASE
- {0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
- {0x37, 0x2D0AAA} //CLK_RST_CONTROLLER_PLLD_MISC
-};
-
-//Display A config.
-static const cfg_op_t _display_config_2[94] = {
- {0x40, 0},
- {DC_CMD_STATE_CONTROL, 0x100},
- {DC_CMD_STATE_CONTROL, 1},
- {0x43, 0x54},
- {DC_CMD_STATE_CONTROL, 0x100},
- {DC_CMD_STATE_CONTROL, 1},
- {0x42, 0x10},
- {0x42, 0x20},
- {0x42, 0x40},
- {0x480, 0},
- {0x403, 0},
- {0x404, 0},
- {0x36, 0x50155},
- {1, 0x100},
- {0x28, 0x109},
- {DC_CMD_STATE_CONTROL, 0xF00},
- {DC_CMD_STATE_CONTROL, 0xF},
- {0x40, 0},
- {0x42, 0x10},
- {0x700, 0},
- {0x42, 0x10},
- {0x70E, 0},
- {0x700, 0},
- {0x42, 0x10},
- {0x42, 0x10},
- {0x611, 0xF0},
- {0x612, 0x12A},
- {0x613, 0},
- {0x614, 0x198},
- {0x615, 0x39B},
- {0x616, 0x32F},
- {0x617, 0x204},
- {0x618, 0},
- {0x42, 0x20},
- {0x700, 0},
- {0x42, 0x20},
- {0x70E, 0},
- {0x700, 0},
- {0x42, 0x20},
- {0x42, 0x20},
- {0x611, 0xF0},
- {0x612, 0x12A},
- {0x613, 0},
- {0x614, 0x198},
- {0x615, 0x39B},
- {0x616, 0x32F},
- {0x617, 0x204},
- {0x618, 0},
- {0x42, 0x40},
- {0x700, 0},
- {0x42, 0x40},
- {0x70E, 0},
- {0x700, 0},
- {0x42, 0x40},
- {0x42, 0x40},
- {0x611, 0xF0},
- {0x612, 0x12A},
- {0x613, 0},
- {0x614, 0x198},
- {0x615, 0x39B},
- {0x616, 0x32F},
- {0x617, 0x204},
- {0x618, 0},
- {0x42, 0x10},
- {0x700, 0},
- {0x42, 0x20},
- {0x700, 0},
- {0x42, 0x40},
- {0x700, 0},
- {0x430, 8},
- {0x42F, 0},
- {0x307, 0x1000000},
- {0x309, 0},
- {0x4E4, 0},
- {0x300, 0},
- {DC_CMD_STATE_CONTROL, 0xF00},
- {DC_CMD_STATE_CONTROL, 0xF},
- {0x42, 0x10},
- {0x716, 0x10000FF},
- {0x42, 0x20},
- {0x716, 0x10000FF},
- {0x42, 0x40},
- {0x716, 0x10000FF},
- {0x31, 0},
- {0x42, 0x10},
- {0x700, 0},
- {0x42, 0x20},
- {0x700, 0},
- {0x42, 0x40},
- {0x700, 0},
- {0x402, 0},
- {0x32, 0},
- {DC_CMD_STATE_CONTROL, 0xF00},
- {DC_CMD_STATE_CONTROL, 0xF}
-};
-
-//DSI config.
-static const cfg_op_t _display_config_3[60] = {
- {0xA, 0},
- {0xC, 0},
- {0xD, 0},
- {0xE, 0},
- {0x1B, 0},
- {0x1C, 0},
- {0x1D, 0},
- {0x1E, 0},
- {0x33, 0},
- {0x23, 0},
- {0x25, 0},
- {0x27, 0},
- {0x29, 0},
- {0x2B, 0},
- {0x2D, 0},
- {0x24, 0},
- {0x26, 0},
- {0x28, 0},
- {0x2A, 0},
- {0x2C, 0},
- {0x2E, 0},
- {0x10, 0},
- {0x4C, 0},
- {0x11, 0x18},
- {0x12, 0x1E0},
- {0x13, 0},
- {0x1A, 0},
- {0x34, 0},
- {0x35, 0},
- {0x36, 0},
- {0x37, 0},
- {0x4F, 0},
- {0x3C, 0x6070601},
- {0x3D, 0x40A0E05},
- {0x3E, 0x30109},
- {0x3F, 0x190A14},
- {0x44, 0x2000FFFF},
- {0x45, 0x7652000},
- {0x46, 0},
- {0x4B, 0},
- {DSI_DSI_POWER_CONTROL, 1},
- {DSI_DSI_POWER_CONTROL, 1},
- {DSI_DSI_POWER_CONTROL, 0},
- {DSI_DSI_POWER_CONTROL, 0},
- {0x4F, 0},
- {0x3C, 0x6070601},
- {0x3D, 0x40A0E05},
- {0x3E, 0x30118},
- {0x3F, 0x190A14},
- {0x44, 0x2000FFFF},
- {0x45, 0x13432000},
- {0x46, 0},
- {0xF, 0x102003},
- {0x10, 0x31},
- {DSI_DSI_POWER_CONTROL, 1},
- {DSI_DSI_POWER_CONTROL, 1},
- {0x12, 0x40},
- {0x13, 0},
- {0x14, 0},
- {0x1A, 0}
-};
-
-//DSI config (if ver == 0x10).
-static const cfg_op_t _display_config_4[43] = {
- {DSI_DSI_WR_DATA, 0x439},
- {DSI_DSI_WR_DATA, 0x9483FFB9},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0xBD15},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0x1939},
- {DSI_DSI_WR_DATA, 0xAAAAAAD8},
- {DSI_DSI_WR_DATA, 0xAAAAAAEB},
- {DSI_DSI_WR_DATA, 0xAAEBAAAA},
- {DSI_DSI_WR_DATA, 0xAAAAAAAA},
- {DSI_DSI_WR_DATA, 0xAAAAAAEB},
- {DSI_DSI_WR_DATA, 0xAAEBAAAA},
- {DSI_DSI_WR_DATA, 0xAA},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0x1BD15},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0x2739},
- {DSI_DSI_WR_DATA, 0xFFFFFFD8},
- {DSI_DSI_WR_DATA, 0xFFFFFFFF},
- {DSI_DSI_WR_DATA, 0xFFFFFFFF},
- {DSI_DSI_WR_DATA, 0xFFFFFFFF},
- {DSI_DSI_WR_DATA, 0xFFFFFFFF},
- {DSI_DSI_WR_DATA, 0xFFFFFFFF},
- {DSI_DSI_WR_DATA, 0xFFFFFFFF},
- {DSI_DSI_WR_DATA, 0xFFFFFFFF},
- {DSI_DSI_WR_DATA, 0xFFFFFFFF},
- {DSI_DSI_WR_DATA, 0xFFFFFF},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0x2BD15},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0xF39},
- {DSI_DSI_WR_DATA, 0xFFFFFFD8},
- {DSI_DSI_WR_DATA, 0xFFFFFFFF},
- {DSI_DSI_WR_DATA, 0xFFFFFFFF},
- {DSI_DSI_WR_DATA, 0xFFFFFF},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0xBD15},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0x6D915},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0x439},
- {DSI_DSI_WR_DATA, 0xB9},
- {DSI_DSI_TRIGGER, 2}
-};
-
-//DSI config.
-static const cfg_op_t _display_config_5[21] = {
- {0x4F, 0},
- {0x3C, 0x6070601},
- {0x3D, 0x40A0E05},
- {0x3E, 0x30172},
- {0x3F, 0x190A14},
- {0x44, 0x20000A40},
- {0x45, 0x5A2F2000},
- {0x46, 0},
- {0x23, 0x40000208},
- {0x27, 0x40000308},
- {0x2B, 0x40000308},
- {0x25, 0x40000308},
- {0x29, 0x3F3B2B08},
- {0x2A, 0x2CC},
- {0x2D, 0x3F3B2B08},
- {0x2E, 0x2CC},
- {0x34, 0xCE0000},
- {0x35, 0x87001A2},
- {0x36, 0x190},
- {0x37, 0x190},
- {0xF, 0},
-};
-
-//Clock config.
-static const cfg_op_t _display_config_6[3] = {
- {0x34, 0x4810C001}, //CLK_RST_CONTROLLER_PLLD_BASE
- {0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
- {0x37, 0x2DFC00} //CLK_RST_CONTROLLER_PLLD_MISC
-};
-
-//DSI config.
-static const cfg_op_t _display_config_7[10] = {
- {0x13, 0},
- {0x10, 0},
- {0x11, 6},
- {0x12, 0x1E0},
- {DSI_DSI_POWER_CONTROL, 1},
- {0x10, 0x103032},
- {0xF, 0x33},
- {0x10, 0x103032},
- {0xF, 3},
- {0xF, 0x23}
-};
-
-//MIPI CAL config.
-static const cfg_op_t _display_config_8[6] = {
- {0x18, 0},
- {2, 0xF3F10000},
- {0x16, 1},
- {0x18, 0},
- {0x18, 0x10010},
- {0x17, 0x300}
-};
-
-//DSI config.
-static const cfg_op_t _display_config_9[4] = {
- {0x4F, 0},
- {0x50, 0},
- {0x51, 0x3333},
- {0x52, 0}
-};
-
-//MIPI CAL config.
-static const cfg_op_t _display_config_10[16] = {
- {0xE, 0x200200},
- {0xF, 0x200200},
- {0x19, 0x200002},
- {0x1A, 0x200002},
- {5, 0},
- {6, 0},
- {7, 0},
- {8, 0},
- {9, 0},
- {0xA, 0},
- {0x10, 0},
- {0x11, 0},
- {0x1A, 0},
- {0x1C, 0},
- {0x1D, 0},
- {0, 0x2A000001}
-};
-
-//Display A config.
-static const cfg_op_t _display_config_11[113] = {
- {0x40, 0},
- {0x42, 0x10},
- {0x700, 0},
- {0x42, 0x10},
- {0x70E, 0},
- {0x700, 0},
- {0x42, 0x10},
- {0x42, 0x10},
- {0x611, 0xF0},
- {0x612, 0x12A},
- {0x613, 0},
- {0x614, 0x198},
- {0x615, 0x39B},
- {0x616, 0x32F},
- {0x617, 0x204},
- {0x618, 0},
- {0x42, 0x20},
- {0x700, 0},
- {0x42, 0x20},
- {0x70E, 0},
- {0x700, 0},
- {0x42, 0x20},
- {0x42, 0x20},
- {0x611, 0xF0},
- {0x612, 0x12A},
- {0x613, 0},
- {0x614, 0x198},
- {0x615, 0x39B},
- {0x616, 0x32F},
- {0x617, 0x204},
- {0x618, 0},
- {0x42, 0x40},
- {0x700, 0},
- {0x42, 0x40},
- {0x70E, 0},
- {0x700, 0},
- {0x42, 0x40},
- {0x42, 0x40},
- {0x611, 0xF0},
- {0x612, 0x12A},
- {0x613, 0},
- {0x614, 0x198},
- {0x615, 0x39B},
- {0x616, 0x32F},
- {0x617, 0x204},
- {0x618, 0},
- {0x42, 0x10},
- {0x700, 0},
- {0x42, 0x20},
- {0x700, 0},
- {0x42, 0x40},
- {0x700, 0},
- {0x430, 8},
- {0x42F, 0},
- {0x307, 0x1000000},
- {0x309, 0},
- {0x4E4, 0},
- {0x300, 0},
- {DC_CMD_STATE_CONTROL, 0xF00},
- {DC_CMD_STATE_CONTROL, 0xF},
- {0x42, 0x10},
- {0x716, 0x10000FF},
- {0x42, 0x20},
- {0x716, 0x10000FF},
- {0x42, 0x40},
- {0x716, 0x10000FF},
- {0x31, 0},
- {0x42, 0x10},
- {0x700, 0},
- {0x42, 0x20},
- {0x700, 0},
- {0x42, 0x40},
- {0x700, 0},
- {0x402, 0},
- {0x32, 0},
- {DC_CMD_STATE_CONTROL, 0xF00},
- {DC_CMD_STATE_CONTROL, 0xF},
- {0x40, 0},
- {0x405, 0},
- {0x406, 0x10000},
- {0x407, 0x10048},
- {0x408, 0x90048},
- {0x409, 0x50002D0},
- {0x40A, 0xA0088},
- {0x431, 0x10001},
- {0x303, 0},
- {0x432, 5},
- {0x42F, 0},
- {0x42E, 0},
- {0x31, 0},
- {0x42, 0x10},
- {0x700, 0},
- {0x42, 0x20},
- {0x700, 0},
- {0x42, 0x40},
- {0x700, 0},
- {0x402, 0},
- {0x32, 0x20},
- {DC_CMD_STATE_CONTROL, 0x100},
- {DC_CMD_STATE_CONTROL, 1},
- {0x40, 5},
- {0x40A, 0xA0088},
- {0x40, 0},
- {DC_CMD_STATE_CONTROL, 0x100},
- {DC_CMD_STATE_CONTROL, 1},
- {0, 0x301},
- {0, 0x301},
- {DC_CMD_STATE_CONTROL, 0x100},
- {DC_CMD_STATE_CONTROL, 1},
- {0x40, 0},
- {0x42E, 4},
- {0x430, 8},
- {0x31, 0}
-};
-
-////Display A config.
-static const cfg_op_t _display_config_12[17] = {
- {0x40A, 0xA0088},
- {0x38, 0},
- {0x40, 0},
- {0x39, 0},
- {0x28, 0},
- {0x32, 0},
- {DC_CMD_STATE_CONTROL, 0x100},
- {DC_CMD_STATE_CONTROL, 1},
- {DC_CMD_STATE_CONTROL, 0x100},
- {DC_CMD_STATE_CONTROL, 1},
- {0, 0x301},
- {0, 0x301},
- {DC_CMD_STATE_CONTROL, 0x100},
- {DC_CMD_STATE_CONTROL, 1},
- {0x36, 0},
- {DC_CMD_STATE_CONTROL, 0x100},
- {DC_CMD_STATE_CONTROL, 1}
-};
-
-//DSI config.
-static const cfg_op_t _display_config_13[16] = {
- {DSI_DSI_POWER_CONTROL, 0},
- {0x4F, 0},
- {0x3C, 0x6070601},
- {0x3D, 0x40A0E05},
- {0x3E, 0x30109},
- {0x3F, 0x190A14},
- {0x44, 0x2000FFFF},
- {0x45, 0x7652000},
- {0x46, 0},
- {0xF, 0x102003},
- {0x10, 0x31},
- {DSI_DSI_POWER_CONTROL, 1},
- {0x12, 0x40},
- {0x13, 0},
- {0x14, 0},
- {0x1A, 0}
-};
-
-//DSI config (if ver == 0x10).
-static const cfg_op_t _display_config_14[22] = {
- {DSI_DSI_WR_DATA, 0x439},
- {DSI_DSI_WR_DATA, 0x9483FFB9},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0x2139},
- {DSI_DSI_WR_DATA, 0x191919D5},
- {DSI_DSI_WR_DATA, 0x19191919},
- {DSI_DSI_WR_DATA, 0x19191919},
- {DSI_DSI_WR_DATA, 0x19191919},
- {DSI_DSI_WR_DATA, 0x19191919},
- {DSI_DSI_WR_DATA, 0x19191919},
- {DSI_DSI_WR_DATA, 0x19191919},
- {DSI_DSI_WR_DATA, 0x19191919},
- {DSI_DSI_WR_DATA, 0x19},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0xB39},
- {DSI_DSI_WR_DATA, 0x4F0F41B1},
- {DSI_DSI_WR_DATA, 0xF179A433},
- {DSI_DSI_WR_DATA, 0x2D81},
- {DSI_DSI_TRIGGER, 2},
- {DSI_DSI_WR_DATA, 0x439},
- {DSI_DSI_WR_DATA, 0xB9},
- {DSI_DSI_TRIGGER, 2}
-};
-
-//Display A config.
-static const cfg_op_t cfg_display_one_color[8] = {
- {DC_CMD_DISPLAY_WINDOW_HEADER, 0x10}, //Enable window A.
- {DC_X_WIN_XD_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, 0x20}, //Enable window B.
- {DC_X_WIN_XD_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, 0x40}, //Enable window C.
- {DC_X_WIN_XD_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE
- {DC_CMD_DISPLAY_COMMAND, 0x20} //DISPLAY_CTRL_MODE: continuous display.
-};
-
-//Display A config.
-static const cfg_op_t cfg_display_framebuffer[32] = {
- {DC_CMD_DISPLAY_WINDOW_HEADER, 0x40}, //Enable window C.
- {DC_X_WIN_XD_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, 0x20}, //Enable window B.
- {DC_X_WIN_XD_WIN_OPTIONS, 0},
- {DC_CMD_DISPLAY_WINDOW_HEADER, 0x10}, //Enable window A.
- {DC_X_WIN_XD_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE
- {DC_X_WIN_XD_COLOR_DEPTH, 0xD}, //T_A8B8G8R8
- {DC_X_WIN_XD_WIN_OPTIONS, 0},
- {DC_X_WIN_XD_WIN_OPTIONS, 0},
- {DC_X_WIN_XD_POSITION, 0}, //(0,0)
- {DC_X_WIN_XD_H_INITIAL_DDA, 0},
- {DC_X_WIN_XD_V_INITIAL_DDA, 0},
- {DC_X_WIN_XD_PRESCALED_SIZE, 0x5000B40}, //Pre-scaled size: 1280x2880 bytes (= 0x500 vertical lines x 0xB40 bytes).
- {DC_X_WIN_XD_DDA_INCREMENT, 0x10001000},
- {DC_X_WIN_XD_SIZE, 0x50002D0}, //Window size: 1280x720 (= 0x500 vertical lines x 0x2D0 horizontal pixels).
- {DC_X_WIN_XD_LINE_STRIDE, 0x6000C00}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
- {0x702, 0},
- {DC_X_WINBUF_XD_SURFACE_KIND, 0}, //Regular surface.
- {DC_X_WINBUF_XD_START_ADDR, 0xC0000000}, //Framebuffer address.
- {DC_X_WINBUF_XD_ADDR_H_OFFSET, 0},
- {DC_X_WINBUF_XD_ADDR_V_OFFSET, 0},
- {DC_X_WIN_XD_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE
- {DC_X_WIN_XD_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE
- {DC_X_WIN_XD_WIN_OPTIONS, 0},
- {DC_DISP_DISP_WIN_OPTIONS, 0x20000000}, //DSI_ENABLE
- {DC_X_WIN_XD_WIN_OPTIONS, 0x40000000}, //Enable window AD.
- {DC_CMD_DISPLAY_COMMAND, 0x20}, //DISPLAY_CTRL_MODE: continuous display.
- {DC_CMD_STATE_CONTROL, 0x300}, //General update; window A update.
- {DC_CMD_STATE_CONTROL, 3} //General activation request; window A activation request.
-};
diff --git a/fusee/fusee-primary/src/hwinit/emc.h b/fusee/fusee-primary/src/hwinit/emc.h
deleted file mode 100644
index ce134c2fe..000000000
--- a/fusee/fusee-primary/src/hwinit/emc.h
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
-* arch/arm/mach-tegra/tegra21_emc.h
-*
-* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that 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, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*
-*/
-
-#ifndef _EMC_H_
-#define _EMC_H_
-
-#define EMC_CONFIG_SAMPLE_DELAY 0x5f0
-#define EMC_CFG_UPDATE 0x5f4
-#define EMC_ADR_CFG 0x10
-#define EMC_REFCTRL 0x20
-#define EMC_PIN 0x24
-#define EMC_TIMING_CONTROL 0x28
-#define EMC_RC 0x2c
-#define EMC_RFC 0x30
-#define EMC_RFCPB 0x590
-#define EMC_RAS 0x34
-#define EMC_RP 0x38
-#define EMC_R2W 0x3c
-#define EMC_W2R 0x40
-#define EMC_R2P 0x44
-#define EMC_W2P 0x48
-#define EMC_CCDMW 0x5c0
-#define EMC_RD_RCD 0x4c
-#define EMC_WR_RCD 0x50
-#define EMC_RRD 0x54
-#define EMC_REXT 0x58
-#define EMC_WDV 0x5c
-#define EMC_QUSE 0x60
-#define EMC_QRST 0x64
-#define EMC_ISSUE_QRST 0x428
-#define EMC_QSAFE 0x68
-#define EMC_RDV 0x6c
-#define EMC_REFRESH 0x70
-#define EMC_BURST_REFRESH_NUM 0x74
-#define EMC_PDEX2WR 0x78
-#define EMC_PDEX2RD 0x7c
-#define EMC_PDEX2CKE 0x118
-#define EMC_PCHG2PDEN 0x80
-#define EMC_ACT2PDEN 0x84
-#define EMC_AR2PDEN 0x88
-#define EMC_RW2PDEN 0x8c
-#define EMC_CKE2PDEN 0x11c
-#define EMC_TXSR 0x90
-#define EMC_TCKE 0x94
-#define EMC_TFAW 0x98
-#define EMC_TRPAB 0x9c
-#define EMC_TCLKSTABLE 0xa0
-#define EMC_TCLKSTOP 0xa4
-#define EMC_TREFBW 0xa8
-#define EMC_TPPD 0xac
-#define EMC_PDEX2MRR 0xb4
-#define EMC_ODT_WRITE 0xb0
-#define EMC_WEXT 0xb8
-#define EMC_RFC_SLR 0xc0
-#define EMC_MRS_WAIT_CNT2 0xc4
-#define EMC_MRS_WAIT_CNT 0xc8
-#define EMC_MRS 0xcc
-#define EMC_EMRS 0xd0
-#define EMC_REF 0xd4
-#define EMC_PRE 0xd8
-#define EMC_NOP 0xdc
-#define EMC_SELF_REF 0xe0
-#define EMC_DPD 0xe4
-#define EMC_MRW 0xe8
-#define EMC_MRR 0xec
-#define EMC_CMDQ 0xf0
-#define EMC_MC2EMCQ 0xf4
-#define EMC_FBIO_SPARE 0x100
-#define EMC_FBIO_CFG5 0x104
-#define EMC_CFG_RSV 0x120
-#define EMC_ACPD_CONTROL 0x124
-#define EMC_MPC 0x128
-#define EMC_EMRS2 0x12c
-#define EMC_EMRS3 0x130
-#define EMC_MRW2 0x134
-#define EMC_MRW3 0x138
-#define EMC_MRW4 0x13c
-#define EMC_MRW5 0x4a0
-#define EMC_MRW6 0x4a4
-#define EMC_MRW7 0x4a8
-#define EMC_MRW8 0x4ac
-#define EMC_MRW9 0x4b0
-#define EMC_MRW10 0x4b4
-#define EMC_MRW11 0x4b8
-#define EMC_MRW12 0x4bc
-#define EMC_MRW13 0x4c0
-#define EMC_MRW14 0x4c4
-#define EMC_MRW15 0x4d0
-#define EMC_CFG_SYNC 0x4d4
-#define EMC_CLKEN_OVERRIDE 0x140
-#define EMC_R2R 0x144
-#define EMC_W2W 0x148
-#define EMC_EINPUT 0x14c
-#define EMC_EINPUT_DURATION 0x150
-#define EMC_PUTERM_EXTRA 0x154
-#define EMC_TCKESR 0x158
-#define EMC_TPD 0x15c
-#define EMC_STAT_CONTROL 0x160
-#define EMC_STAT_STATUS 0x164
-#define EMC_STAT_DRAM_CLOCK_LIMIT_LO 0x19c
-#define EMC_STAT_DRAM_CLOCK_LIMIT_HI 0x1a0
-#define EMC_STAT_DRAM_CLOCKS_LO 0x1a4
-#define EMC_STAT_DRAM_CLOCKS_HI 0x1a8
-#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_LO 0x1ac
-#define EMC_STAT_DRAM_DEV0_ACTIVATE_CNT_HI 0x1b0
-#define EMC_STAT_DRAM_DEV0_READ_CNT_LO 0x1b4
-#define EMC_STAT_DRAM_DEV0_READ_CNT_HI 0x1b8
-#define EMC_STAT_DRAM_DEV0_READ8_CNT_LO 0x1bc
-#define EMC_STAT_DRAM_DEV0_READ8_CNT_HI 0x1c0
-#define EMC_STAT_DRAM_DEV0_WRITE_CNT_LO 0x1c4
-#define EMC_STAT_DRAM_DEV0_WRITE_CNT_HI 0x1c8
-#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_LO 0x1cc
-#define EMC_STAT_DRAM_DEV0_WRITE8_CNT_HI 0x1d0
-#define EMC_STAT_DRAM_DEV0_REF_CNT_LO 0x1d4
-#define EMC_STAT_DRAM_DEV0_REF_CNT_HI 0x1d8
-#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x1dc
-#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x1e0
-#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x1e4
-#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x1e8
-#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x1ec
-#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x1f0
-#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x1f4
-#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x1f8
-#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x1fc
-#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x200
-#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x204
-#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x208
-#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x20c
-#define EMC_STAT_DRAM_DEV0_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x210
-#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x214
-#define EMC_STAT_DRAM_DEV0_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x218
-#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_LO 0x21c
-#define EMC_STAT_DRAM_DEV0_SR_CKE_EQ0_CLKS_HI 0x220
-#define EMC_STAT_DRAM_DEV0_DSR 0x224
-#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_LO 0x228
-#define EMC_STAT_DRAM_DEV1_ACTIVATE_CNT_HI 0x22c
-#define EMC_STAT_DRAM_DEV1_READ_CNT_LO 0x230
-#define EMC_STAT_DRAM_DEV1_READ_CNT_HI 0x234
-#define EMC_STAT_DRAM_DEV1_READ8_CNT_LO 0x238
-#define EMC_STAT_DRAM_DEV1_READ8_CNT_HI 0x23c
-#define EMC_STAT_DRAM_DEV1_WRITE_CNT_LO 0x240
-#define EMC_STAT_DRAM_DEV1_WRITE_CNT_HI 0x244
-#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_LO 0x248
-#define EMC_STAT_DRAM_DEV1_WRITE8_CNT_HI 0x24c
-#define EMC_STAT_DRAM_DEV1_REF_CNT_LO 0x250
-#define EMC_STAT_DRAM_DEV1_REF_CNT_HI 0x254
-#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x258
-#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x25c
-#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0x260
-#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0x264
-#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x268
-#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x26c
-#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0x270
-#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0x274
-#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x278
-#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x27c
-#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0x280
-#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0x284
-#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x288
-#define EMC_STAT_DRAM_DEV1_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x28c
-#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0x290
-#define EMC_STAT_DRAM_DEV1_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0x294
-#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_LO 0x298
-#define EMC_STAT_DRAM_DEV1_SR_CKE_EQ0_CLKS_HI 0x29c
-#define EMC_STAT_DRAM_DEV1_DSR 0x2a0
-#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0xc8c
-#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0xc90
-#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_LO 0xc94
-#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_NO_BANKS_ACTIVE_CLKS_HI 0xc98
-#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0xc9c
-#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0xca0
-#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_LO 0xca4
-#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_NO_BANKS_ACTIVE_CLKS_HI 0xca8
-#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0xcac
-#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0xcb0
-#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_LO 0xcb4
-#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ0_SOME_BANKS_ACTIVE_CLKS_HI 0xcb8
-#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0xcbc
-#define EMC_STAT_DRAM_IO_EXTCLKS_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0xcc0
-#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_LO 0xcc4
-#define EMC_STAT_DRAM_IO_CLKSTOP_CKE_EQ1_SOME_BANKS_ACTIVE_CLKS_HI 0xcc8
-#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_LO 0xccc
-#define EMC_STAT_DRAM_IO_SR_CKE_EQ0_CLKS_HI 0xcd0
-#define EMC_STAT_DRAM_IO_DSR 0xcd4
-#define EMC_AUTO_CAL_CONFIG 0x2a4
-#define EMC_AUTO_CAL_CONFIG2 0x458
-#define EMC_AUTO_CAL_CONFIG3 0x45c
-#define EMC_AUTO_CAL_CONFIG4 0x5b0
-#define EMC_AUTO_CAL_CONFIG5 0x5b4
-#define EMC_AUTO_CAL_CONFIG6 0x5cc
-#define EMC_AUTO_CAL_CONFIG7 0x574
-#define EMC_AUTO_CAL_CONFIG8 0x2dc
-#define EMC_AUTO_CAL_VREF_SEL_0 0x2f8
-#define EMC_AUTO_CAL_VREF_SEL_1 0x300
-#define EMC_AUTO_CAL_INTERVAL 0x2a8
-#define EMC_AUTO_CAL_STATUS 0x2ac
-#define EMC_AUTO_CAL_STATUS2 0x3d4
-#define EMC_AUTO_CAL_CHANNEL 0x464
-#define EMC_PMACRO_RX_TERM 0xc48
-#define EMC_PMACRO_DQ_TX_DRV 0xc70
-#define EMC_PMACRO_CA_TX_DRV 0xc74
-#define EMC_PMACRO_CMD_TX_DRV 0xc4c
-#define EMC_PMACRO_AUTOCAL_CFG_0 0x700
-#define EMC_PMACRO_AUTOCAL_CFG_1 0x704
-#define EMC_PMACRO_AUTOCAL_CFG_2 0x708
-#define EMC_PMACRO_AUTOCAL_CFG_COMMON 0xc78
-#define EMC_PMACRO_ZCTRL 0xc44
-#define EMC_XM2COMPPADCTRL 0x30c
-#define EMC_XM2COMPPADCTRL2 0x578
-#define EMC_XM2COMPPADCTRL3 0x2f4
-#define EMC_COMP_PAD_SW_CTRL 0x57c
-#define EMC_REQ_CTRL 0x2b0
-#define EMC_EMC_STATUS 0x2b4
-#define EMC_CFG_2 0x2b8
-#define EMC_CFG_DIG_DLL 0x2bc
-#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
-#define EMC_DIG_DLL_STATUS 0x2c4
-#define EMC_CFG_DIG_DLL_1 0x2c8
-#define EMC_RDV_MASK 0x2cc
-#define EMC_WDV_MASK 0x2d0
-#define EMC_RDV_EARLY_MASK 0x2d4
-#define EMC_RDV_EARLY 0x2d8
-#define EMC_WDV_CHK 0x4e0
-#define EMC_ZCAL_INTERVAL 0x2e0
-#define EMC_ZCAL_WAIT_CNT 0x2e4
-#define EMC_ZCAL_MRW_CMD 0x2e8
-#define EMC_ZQ_CAL 0x2ec
-#define EMC_SCRATCH0 0x324
-#define EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE 0x3c8
-#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3cc
-#define EMC_UNSTALL_RW_AFTER_CLKCHANGE 0x3d0
-#define EMC_FDPD_CTRL_CMD_NO_RAMP 0x4d8
-#define EMC_SEL_DPD_CTRL 0x3d8
-#define EMC_FDPD_CTRL_DQ 0x310
-#define EMC_FDPD_CTRL_CMD 0x314
-#define EMC_PRE_REFRESH_REQ_CNT 0x3dc
-#define EMC_REFCTRL2 0x580
-#define EMC_FBIO_CFG7 0x584
-#define EMC_DATA_BRLSHFT_0 0x588
-#define EMC_DATA_BRLSHFT_1 0x58c
-#define EMC_DQS_BRLSHFT_0 0x594
-#define EMC_DQS_BRLSHFT_1 0x598
-#define EMC_CMD_BRLSHFT_0 0x59c
-#define EMC_CMD_BRLSHFT_1 0x5a0
-#define EMC_CMD_BRLSHFT_2 0x5a4
-#define EMC_CMD_BRLSHFT_3 0x5a8
-#define EMC_QUSE_BRLSHFT_0 0x5ac
-#define EMC_QUSE_BRLSHFT_1 0x5b8
-#define EMC_QUSE_BRLSHFT_2 0x5bc
-#define EMC_QUSE_BRLSHFT_3 0x5c4
-#define EMC_FBIO_CFG8 0x5c8
-#define EMC_CMD_MAPPING_CMD0_0 0x380
-#define EMC_CMD_MAPPING_CMD0_1 0x384
-#define EMC_CMD_MAPPING_CMD0_2 0x388
-#define EMC_CMD_MAPPING_CMD1_0 0x38c
-#define EMC_CMD_MAPPING_CMD1_1 0x390
-#define EMC_CMD_MAPPING_CMD1_2 0x394
-#define EMC_CMD_MAPPING_CMD2_0 0x398
-#define EMC_CMD_MAPPING_CMD2_1 0x39c
-#define EMC_CMD_MAPPING_CMD2_2 0x3a0
-#define EMC_CMD_MAPPING_CMD3_0 0x3a4
-#define EMC_CMD_MAPPING_CMD3_1 0x3a8
-#define EMC_CMD_MAPPING_CMD3_2 0x3ac
-#define EMC_CMD_MAPPING_BYTE 0x3b0
-#define EMC_DYN_SELF_REF_CONTROL 0x3e0
-#define EMC_TXSRDLL 0x3e4
-#define EMC_CCFIFO_ADDR 0x3e8
-#define EMC_CCFIFO_DATA 0x3ec
-#define EMC_CCFIFO_STATUS 0x3f0
-#define EMC_SWIZZLE_RANK0_BYTE0 0x404
-#define EMC_SWIZZLE_RANK0_BYTE1 0x408
-#define EMC_SWIZZLE_RANK0_BYTE2 0x40c
-#define EMC_SWIZZLE_RANK0_BYTE3 0x410
-#define EMC_SWIZZLE_RANK1_BYTE0 0x418
-#define EMC_SWIZZLE_RANK1_BYTE1 0x41c
-#define EMC_SWIZZLE_RANK1_BYTE2 0x420
-#define EMC_SWIZZLE_RANK1_BYTE3 0x424
-#define EMC_TR_TIMING_0 0x3b4
-#define EMC_TR_CTRL_0 0x3b8
-#define EMC_TR_CTRL_1 0x3bc
-#define EMC_TR_DVFS 0x460
-#define EMC_SWITCH_BACK_CTRL 0x3c0
-#define EMC_TR_RDV 0x3c4
-#define EMC_TR_QPOP 0x3f4
-#define EMC_TR_RDV_MASK 0x3f8
-#define EMC_TR_QSAFE 0x3fc
-#define EMC_TR_QRST 0x400
-#define EMC_IBDLY 0x468
-#define EMC_OBDLY 0x46c
-#define EMC_TXDSRVTTGEN 0x480
-#define EMC_WE_DURATION 0x48c
-#define EMC_WS_DURATION 0x490
-#define EMC_WEV 0x494
-#define EMC_WSV 0x498
-#define EMC_CFG_3 0x49c
-#define EMC_CFG_PIPE_2 0x554
-#define EMC_CFG_PIPE_CLK 0x558
-#define EMC_CFG_PIPE_1 0x55c
-#define EMC_CFG_PIPE 0x560
-#define EMC_QPOP 0x564
-#define EMC_QUSE_WIDTH 0x568
-#define EMC_PUTERM_WIDTH 0x56c
-#define EMC_PROTOBIST_CONFIG_ADR_1 0x5d0
-#define EMC_PROTOBIST_CONFIG_ADR_2 0x5d4
-#define EMC_PROTOBIST_MISC 0x5d8
-#define EMC_PROTOBIST_WDATA_LOWER 0x5dc
-#define EMC_PROTOBIST_WDATA_UPPER 0x5e0
-#define EMC_PROTOBIST_RDATA 0x5ec
-#define EMC_DLL_CFG_0 0x5e4
-#define EMC_DLL_CFG_1 0x5e8
-#define EMC_TRAINING_CMD 0xe00
-#define EMC_TRAINING_CTRL 0xe04
-#define EMC_TRAINING_STATUS 0xe08
-#define EMC_TRAINING_QUSE_CORS_CTRL 0xe0c
-#define EMC_TRAINING_QUSE_FINE_CTRL 0xe10
-#define EMC_TRAINING_QUSE_CTRL_MISC 0xe14
-#define EMC_TRAINING_WRITE_FINE_CTRL 0xe18
-#define EMC_TRAINING_WRITE_CTRL_MISC 0xe1c
-#define EMC_TRAINING_WRITE_VREF_CTRL 0xe20
-#define EMC_TRAINING_READ_FINE_CTRL 0xe24
-#define EMC_TRAINING_READ_CTRL_MISC 0xe28
-#define EMC_TRAINING_READ_VREF_CTRL 0xe2c
-#define EMC_TRAINING_CA_FINE_CTRL 0xe30
-#define EMC_TRAINING_CA_CTRL_MISC 0xe34
-#define EMC_TRAINING_CA_CTRL_MISC1 0xe38
-#define EMC_TRAINING_CA_VREF_CTRL 0xe3c
-#define EMC_TRAINING_CA_TADR_CTRL 0xe40
-#define EMC_TRAINING_SETTLE 0xe44
-#define EMC_TRAINING_DEBUG_CTRL 0xe48
-#define EMC_TRAINING_DEBUG_DQ0 0xe4c
-#define EMC_TRAINING_DEBUG_DQ1 0xe50
-#define EMC_TRAINING_DEBUG_DQ2 0xe54
-#define EMC_TRAINING_DEBUG_DQ3 0xe58
-#define EMC_TRAINING_MPC 0xe5c
-#define EMC_TRAINING_PATRAM_CTRL 0xe60
-#define EMC_TRAINING_PATRAM_DQ 0xe64
-#define EMC_TRAINING_PATRAM_DMI 0xe68
-#define EMC_TRAINING_VREF_SETTLE 0xe6c
-#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE0 0xe70
-#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE1 0xe74
-#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE2 0xe78
-#define EMC_TRAINING_RW_EYE_CENTER_IB_BYTE3 0xe7c
-#define EMC_TRAINING_RW_EYE_CENTER_IB_MISC 0xe80
-#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE0 0xe84
-#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE1 0xe88
-#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE2 0xe8c
-#define EMC_TRAINING_RW_EYE_CENTER_OB_BYTE3 0xe90
-#define EMC_TRAINING_RW_EYE_CENTER_OB_MISC 0xe94
-#define EMC_TRAINING_RW_OFFSET_IB_BYTE0 0xe98
-#define EMC_TRAINING_RW_OFFSET_IB_BYTE1 0xe9c
-#define EMC_TRAINING_RW_OFFSET_IB_BYTE2 0xea0
-#define EMC_TRAINING_RW_OFFSET_IB_BYTE3 0xea4
-#define EMC_TRAINING_RW_OFFSET_IB_MISC 0xea8
-#define EMC_TRAINING_RW_OFFSET_OB_BYTE0 0xeac
-#define EMC_TRAINING_RW_OFFSET_OB_BYTE1 0xeb0
-#define EMC_TRAINING_RW_OFFSET_OB_BYTE2 0xeb4
-#define EMC_TRAINING_RW_OFFSET_OB_BYTE3 0xeb8
-#define EMC_TRAINING_RW_OFFSET_OB_MISC 0xebc
-#define EMC_TRAINING_OPT_CA_VREF 0xec0
-#define EMC_TRAINING_OPT_DQ_OB_VREF 0xec4
-#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK0 0xec8
-#define EMC_TRAINING_OPT_DQ_IB_VREF_RANK1 0xecc
-#define EMC_TRAINING_QUSE_VREF_CTRL 0xed0
-#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK0 0xed4
-#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK1 0xed8
-#define EMC_TRAINING_DRAMC_TIMING 0xedc
-#define EMC_PMACRO_QUSE_DDLL_RANK0_0 0x600
-#define EMC_PMACRO_QUSE_DDLL_RANK0_1 0x604
-#define EMC_PMACRO_QUSE_DDLL_RANK0_2 0x608
-#define EMC_PMACRO_QUSE_DDLL_RANK0_3 0x60c
-#define EMC_PMACRO_QUSE_DDLL_RANK0_4 0x610
-#define EMC_PMACRO_QUSE_DDLL_RANK0_5 0x614
-#define EMC_PMACRO_QUSE_DDLL_RANK1_0 0x620
-#define EMC_PMACRO_QUSE_DDLL_RANK1_1 0x624
-#define EMC_PMACRO_QUSE_DDLL_RANK1_2 0x628
-#define EMC_PMACRO_QUSE_DDLL_RANK1_3 0x62c
-#define EMC_PMACRO_QUSE_DDLL_RANK1_4 0x630
-#define EMC_PMACRO_QUSE_DDLL_RANK1_5 0x634
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0 0x640
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1 0x644
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2 0x648
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3 0x64c
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4 0x650
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5 0x654
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0 0x660
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1 0x664
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2 0x668
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3 0x66c
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4 0x670
-#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5 0x674
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0 0x680
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1 0x684
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2 0x688
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3 0x68c
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4 0x690
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5 0x694
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0 0x6a0
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1 0x6a4
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2 0x6a8
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3 0x6ac
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4 0x6b0
-#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5 0x6b4
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0 0x6c0
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1 0x6c4
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2 0x6c8
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3 0x6cc
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_4 0x6d0
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_5 0x6d4
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0 0x6e0
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1 0x6e4
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2 0x6e8
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3 0x6ec
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_4 0x6f0
-#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_5 0x6f4
-#define EMC_PMACRO_TX_PWRD_0 0x720
-#define EMC_PMACRO_TX_PWRD_1 0x724
-#define EMC_PMACRO_TX_PWRD_2 0x728
-#define EMC_PMACRO_TX_PWRD_3 0x72c
-#define EMC_PMACRO_TX_PWRD_4 0x730
-#define EMC_PMACRO_TX_PWRD_5 0x734
-#define EMC_PMACRO_TX_SEL_CLK_SRC_0 0x740
-#define EMC_PMACRO_TX_SEL_CLK_SRC_1 0x744
-#define EMC_PMACRO_TX_SEL_CLK_SRC_3 0x74c
-#define EMC_PMACRO_TX_SEL_CLK_SRC_2 0x748
-#define EMC_PMACRO_TX_SEL_CLK_SRC_4 0x750
-#define EMC_PMACRO_TX_SEL_CLK_SRC_5 0x754
-#define EMC_PMACRO_DDLL_BYPASS 0x760
-#define EMC_PMACRO_DDLL_PWRD_0 0x770
-#define EMC_PMACRO_DDLL_PWRD_1 0x774
-#define EMC_PMACRO_DDLL_PWRD_2 0x778
-#define EMC_PMACRO_CMD_CTRL_0 0x780
-#define EMC_PMACRO_CMD_CTRL_1 0x784
-#define EMC_PMACRO_CMD_CTRL_2 0x788
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0 0x800
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1 0x804
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2 0x808
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3 0x80c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0 0x810
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1 0x814
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2 0x818
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3 0x81c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0 0x820
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1 0x824
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2 0x828
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3 0x82c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0 0x830
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1 0x834
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2 0x838
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3 0x83c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0 0x840
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1 0x844
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2 0x848
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3 0x84c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0 0x850
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1 0x854
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2 0x858
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3 0x85c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0 0x860
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1 0x864
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2 0x868
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3 0x86c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0 0x870
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1 0x874
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2 0x878
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3 0x87c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0 0x880
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1 0x884
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2 0x888
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3 0x88c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0 0x890
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1 0x894
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2 0x898
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3 0x89c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0 0x8a0
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1 0x8a4
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2 0x8a8
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3 0x8ac
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0 0x8b0
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1 0x8b4
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2 0x8b8
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3 0x8bc
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0 0x900
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1 0x904
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2 0x908
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3 0x90c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0 0x910
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1 0x914
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2 0x918
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3 0x91c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0 0x920
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1 0x924
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2 0x928
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3 0x92c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0 0x930
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1 0x934
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2 0x938
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3 0x93c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0 0x940
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1 0x944
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2 0x948
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3 0x94c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0 0x950
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1 0x954
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2 0x958
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3 0x95c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0 0x960
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1 0x964
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2 0x968
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3 0x96c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0 0x970
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1 0x974
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2 0x978
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3 0x97c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0 0x980
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1 0x984
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2 0x988
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3 0x98c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0 0x990
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1 0x994
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2 0x998
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3 0x99c
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0 0x9a0
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1 0x9a4
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2 0x9a8
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3 0x9ac
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0 0x9b0
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1 0x9b4
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2 0x9b8
-#define EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3 0x9bc
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0 0xa00
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1 0xa04
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2 0xa08
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0 0xa10
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1 0xa14
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2 0xa18
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0 0xa20
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1 0xa24
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2 0xa28
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0 0xa30
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1 0xa34
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2 0xa38
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0 0xa40
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1 0xa44
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2 0xa48
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0 0xa50
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1 0xa54
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2 0xa58
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0 0xa60
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1 0xa64
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2 0xa68
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0 0xa70
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1 0xa74
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2 0xa78
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_0 0xa80
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_1 0xa84
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD0_2 0xa88
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_0 0xa90
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_1 0xa94
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD1_2 0xa98
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_0 0xaa0
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_1 0xaa4
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD2_2 0xaa8
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_0 0xab0
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_1 0xab4
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_CMD3_2 0xab8
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0 0xb00
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1 0xb04
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2 0xb08
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0 0xb10
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1 0xb14
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2 0xb18
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0 0xb20
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1 0xb24
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2 0xb28
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0 0xb30
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1 0xb34
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2 0xb38
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0 0xb40
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1 0xb44
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2 0xb48
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0 0xb50
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1 0xb54
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2 0xb58
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0 0xb60
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1 0xb64
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2 0xb68
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0 0xb70
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1 0xb74
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2 0xb78
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_0 0xb80
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_1 0xb84
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD0_2 0xb88
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_0 0xb90
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_1 0xb94
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD1_2 0xb98
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_0 0xba0
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_1 0xba4
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD2_2 0xba8
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_0 0xbb0
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_1 0xbb4
-#define EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_CMD3_2 0xbb8
-#define EMC_PMACRO_IB_VREF_DQ_0 0xbe0
-#define EMC_PMACRO_IB_VREF_DQ_1 0xbe4
-#define EMC_PMACRO_IB_VREF_DQ_2 0xbe8
-#define EMC_PMACRO_IB_VREF_DQS_0 0xbf0
-#define EMC_PMACRO_IB_VREF_DQS_1 0xbf4
-#define EMC_PMACRO_IB_VREF_DQS_2 0xbf8
-#define EMC_PMACRO_IB_RXRT 0xcf4
-#define EMC_PMACRO_DDLL_LONG_CMD_0 0xc00
-#define EMC_PMACRO_DDLL_LONG_CMD_1 0xc04
-#define EMC_PMACRO_DDLL_LONG_CMD_2 0xc08
-#define EMC_PMACRO_DDLL_LONG_CMD_3 0xc0c
-#define EMC_PMACRO_DDLL_LONG_CMD_4 0xc10
-#define EMC_PMACRO_DDLL_LONG_CMD_5 0xc14
-#define EMC_PMACRO_DDLL_SHORT_CMD_0 0xc20
-#define EMC_PMACRO_DDLL_SHORT_CMD_1 0xc24
-#define EMC_PMACRO_DDLL_SHORT_CMD_2 0xc28
-#define EMC_PMACRO_CFG_PM_GLOBAL_0 0xc30
-#define EMC_PMACRO_VTTGEN_CTRL_0 0xc34
-#define EMC_PMACRO_VTTGEN_CTRL_1 0xc38
-#define EMC_PMACRO_VTTGEN_CTRL_2 0xcf0
-#define EMC_PMACRO_BG_BIAS_CTRL_0 0xc3c
-#define EMC_PMACRO_PAD_CFG_CTRL 0xc40
-#define EMC_PMACRO_CMD_PAD_RX_CTRL 0xc50
-#define EMC_PMACRO_DATA_PAD_RX_CTRL 0xc54
-#define EMC_PMACRO_CMD_RX_TERM_MODE 0xc58
-#define EMC_PMACRO_DATA_RX_TERM_MODE 0xc5c
-#define EMC_PMACRO_CMD_PAD_TX_CTRL 0xc60
-#define EMC_PMACRO_DATA_PAD_TX_CTRL 0xc64
-#define EMC_PMACRO_COMMON_PAD_TX_CTRL 0xc68
-#define EMC_PMACRO_BRICK_MAPPING_0 0xc80
-#define EMC_PMACRO_BRICK_MAPPING_1 0xc84
-#define EMC_PMACRO_BRICK_MAPPING_2 0xc88
-#define EMC_PMACRO_DDLLCAL_CAL 0xce0
-#define EMC_PMACRO_DDLL_OFFSET 0xce4
-#define EMC_PMACRO_DDLL_PERIODIC_OFFSET 0xce8
-#define EMC_PMACRO_BRICK_CTRL_RFU1 0x330
-#define EMC_PMACRO_BRICK_CTRL_RFU2 0x334
-#define EMC_PMACRO_CMD_BRICK_CTRL_FDPD 0x318
-#define EMC_PMACRO_DATA_BRICK_CTRL_FDPD 0x31c
-#define EMC_PMACRO_TRAINING_CTRL_0 0xcf8
-#define EMC_PMACRO_TRAINING_CTRL_1 0xcfc
-#define EMC_PMC_SCRATCH1 0x440
-#define EMC_PMC_SCRATCH2 0x444
-#define EMC_PMC_SCRATCH3 0x448
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/fuse.h b/fusee/fusee-primary/src/hwinit/fuse.h
deleted file mode 100644
index 1f19f466f..000000000
--- a/fusee/fusee-primary/src/hwinit/fuse.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _FUSE_H_
-#define _FUSE_H_
-
-#include "types.h"
-
-/*! Fuse registers. */
-#define FUSE_CTRL 0x0
-#define FUSE_ADDR 0x4
-#define FUSE_RDATA 0x8
-#define FUSE_WDATA 0xC
-#define FUSE_TIME_RD1 0x10
-#define FUSE_TIME_RD2 0x14
-#define FUSE_TIME_PGM1 0x18
-#define FUSE_TIME_PGM2 0x1C
-#define FUSE_PRIV2INTFC 0x20
-#define FUSE_FUSEBYPASS 0x24
-#define FUSE_PRIVATEKEYDISABLE 0x28
-#define FUSE_DISABLEREGPROGRAM 0x2C
-#define FUSE_WRITE_ACCESS_SW 0x30
-#define FUSE_PWR_GOOD_SW 0x34
-
-/*! Fuse cache registers. */
-#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
-
-void fuse_disable_program();
-u32 fuse_read_odm(u32 idx);
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/hwinit.c b/fusee/fusee-primary/src/hwinit/hwinit.c
deleted file mode 100644
index 467efdee5..000000000
--- a/fusee/fusee-primary/src/hwinit/hwinit.c
+++ /dev/null
@@ -1,280 +0,0 @@
-#include "clock.h"
-#include "uart.h"
-#include "i2c.h"
-#include "sdram.h"
-#include "di.h"
-#include "mc.h"
-#include "t210.h"
-#include "pmc.h"
-#include "pinmux.h"
-#include "fuse.h"
-#include "util.h"
-
-void config_oscillators()
-{
- CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3 | 4;
- SYSCTR0(SYSCTR0_CNTFID0) = 19200000;
- TMR(0x14) = 0x45F;
- CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071;
- PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81 | 0xE;
- PMC(APBDEV_PMC_OSC_EDPD_OVER) = PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF | 0x400000;
- PMC(APBDEV_PMC_CNTRL2) = PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF | 0x1000;
- PMC(APBDEV_PMC_SCRATCH188) = PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF | 0x2000000;
- CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF;
- PMC(APBDEV_PMC_TSC_MULT) = PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000 | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
- CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444;
- CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000;
- CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2;
-}
-
-void config_gpios()
-{
- PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
- PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
-
- PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = 0x40;
- PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = 0x40;
-
- GPIO_2(0x8) = GPIO_2(0x8) & 0xFFFFFFFE | 1;
- GPIO_1(0xC) = GPIO_1(0xC) & 0xFFFFFFFD | 2;
- GPIO_2(0x0) = GPIO_2(0x0) & 0xFFFFFFBF | 0x40;
- GPIO_2(0xC) = GPIO_2(0xC) & 0xFFFFFFBF | 0x40;
- GPIO_2(0x18) &= 0xFFFFFFFE;
- GPIO_1(0x1C) &= 0xFFFFFFFD;
- GPIO_2(0x10) &= 0xFFFFFFBF;
- GPIO_2(0x1C) &= 0xFFFFFFBF;
-
- pinmux_config_i2c(I2C_1);
- pinmux_config_i2c(I2C_5);
- pinmux_config_uart(UART_A);
-
- GPIO_6(0xC) = GPIO_6(0xC) & 0xFFFFFFBF | 0x40;
- GPIO_6(0xC) = GPIO_6(0xC) & 0xFFFFFF7F | 0x80;
- GPIO_6(0x1C) &= 0xFFFFFFBF;
- GPIO_6(0x1C) &= 0xFFFFFF7F;
-}
-
-void config_pmc_scratch()
-{
- PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF;
- PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE;
- PMC(APBDEV_PMC_SECURE_SCRATCH21) |= 0x10;
-}
-
-void mc_config_tsec_carveout(u32 bom, u32 size1mb, int lock)
-{
- MC(0x670) = 0x90000000;
- MC(0x674) = 1;
- if (lock)
- MC(0x678) = 1;
-}
-
-void mc_config_carveout()
-{
- *(vu32 *)0x8005FFFC = 0xC0EDBBCC;
- MC(0x984) = 1;
- MC(0x988) = 0;
- MC(0x648) = 0;
- MC(0x64C) = 0;
- MC(0x650) = 1;
-
- //Official code disables and locks the carveout here.
- //mc_config_tsec_carveout(0, 0, 1);
-
- MC(0x9A0) = 0;
- MC(0x9A4) = 0;
- MC(0x9A8) = 0;
- MC(0x9AC) = 1;
- MC(0xC0C) = 0;
- MC(0xC10) = 0;
- MC(0xC14) = 0;
- MC(0xC18) = 0;
- MC(0xC1C) = 0;
- MC(0xC20) = 0;
- MC(0xC24) = 0;
- MC(0xC28) = 0;
- MC(0xC2C) = 0;
- MC(0xC30) = 0;
- MC(0xC34) = 0;
- MC(0xC38) = 0;
- MC(0xC3C) = 0;
- MC(0xC08) = 0x4000006;
- MC(0xC5C) = 0x80020000;
- MC(0xC60) = 0;
- MC(0xC64) = 2;
- MC(0xC68) = 0;
- MC(0xC6C) = 0;
- MC(0xC70) = 0x3000000;
- MC(0xC74) = 0;
- MC(0xC78) = 0x300;
- MC(0xC7C) = 0;
- MC(0xC80) = 0;
- MC(0xC84) = 0;
- MC(0xC88) = 0;
- MC(0xC8C) = 0;
- MC(0xC58) = 0x440167E;
- MC(0xCAC) = 0;
- MC(0xCB0) = 0;
- MC(0xCB4) = 0;
- MC(0xCB8) = 0;
- MC(0xCBC) = 0;
- MC(0xCC0) = 0x3000000;
- MC(0xCC4) = 0;
- MC(0xCC8) = 0x300;
- MC(0xCCC) = 0;
- MC(0xCD0) = 0;
- MC(0xCD4) = 0;
- MC(0xCD8) = 0;
- MC(0xCDC) = 0;
- MC(0xCA8) = 0x4401E7E;
- MC(0xCFC) = 0;
- MC(0xD00) = 0;
- MC(0xD04) = 0;
- MC(0xD08) = 0;
- MC(0xD0C) = 0;
- MC(0xD10) = 0;
- MC(0xD14) = 0;
- MC(0xD18) = 0;
- MC(0xD1C) = 0;
- MC(0xD20) = 0;
- MC(0xD24) = 0;
- MC(0xD28) = 0;
- MC(0xD2C) = 0;
- MC(0xCF8) = 0x8F;
- MC(0xD4C) = 0;
- MC(0xD50) = 0;
- MC(0xD54) = 0;
- MC(0xD58) = 0;
- MC(0xD5C) = 0;
- MC(0xD60) = 0;
- MC(0xD64) = 0;
- MC(0xD68) = 0;
- MC(0xD6C) = 0;
- MC(0xD70) = 0;
- MC(0xD74) = 0;
- MC(0xD78) = 0;
- MC(0xD7C) = 0;
- MC(0xD48) = 0x8F;
-}
-
-void enable_clocks()
-{
- CLOCK(0x410) = (CLOCK(0x410) | 0x8000) & 0xFFFFBFFF;
- CLOCK(0xD0) |= 0x40800000u;
- CLOCK(0x2AC) = 64;
- CLOCK(0x294) = 0x40000;
- CLOCK(0x304) = 0x18000000;
- sleep(2);
-
- I2S(0x0A0) |= 0x400;
- I2S(0x088) &= 0xFFFFFFFE;
- I2S(0x1A0) |= 0x400;
- I2S(0x188) &= 0xFFFFFFFE;
- I2S(0x2A0) |= 0x400;
- I2S(0x288) &= 0xFFFFFFFE;
- I2S(0x3A0) |= 0x400;
- I2S(0x388) &= 0xFFFFFFFE;
- I2S(0x4A0) |= 0x400;
- I2S(0x488) &= 0xFFFFFFFE;
- DISPLAY_A(0xCF8) |= 4;
- VIC(0x8C) = 0xFFFFFFFF;
- sleep(2);
-
- CLOCK(0x2A8) = 0x40;
- CLOCK(0x300) = 0x18000000;
- CLOCK(0x290) = 0x40000;
- CLOCK(0x14) = 0xC0;
- CLOCK(0x10) = 0x80000130;
- CLOCK(0x18) = 0x1F00200;
- CLOCK(0x360) = 0x80400808;
- CLOCK(0x364) = 0x402000FC;
- CLOCK(0x280) = 0x23000780;
- CLOCK(0x298) = 0x300;
- CLOCK(0xF8) = 0;
- CLOCK(0xFC) = 0;
- CLOCK(0x3A0) = 0;
- CLOCK(0x3A4) = 0;
- CLOCK(0x554) = 0;
- CLOCK(0xD0) &= 0x1F7FFFFFu;
- CLOCK(0x410) &= 0xFFFF3FFF;
- CLOCK(0x148) = CLOCK(0x148) & 0x1FFFFFFF | 0x80000000;
- CLOCK(0x180) = CLOCK(0x180) & 0x1FFFFFFF | 0x80000000;
- CLOCK(0x6A0) = CLOCK(0x6A0) & 0x1FFFFFFF | 0x80000000;
-}
-
-void mc_enable_ahb_redirect()
-{
- CLOCK(0x3A4) = CLOCK(0x3A4) & 0xFFF7FFFF | 0x80000;
- //MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE;
- MC(MC_IRAM_BOM) = 0x40000000;
- MC(MC_IRAM_TOM) = 0x4003F000;
-}
-
-void mc_disable_ahb_redirect()
-{
- MC(MC_IRAM_BOM) = 0xFFFFF000;
- MC(MC_IRAM_TOM) = 0;
- //Disable IRAM_CFG_WRITE_ACCESS (sticky).
- //MC(MC_IRAM_REG_CTRL) = MC(MC_IRAM_REG_CTRL) & 0xFFFFFFFE | 1;
- CLOCK(0x3A4) &= 0xFFF7FFFF;
-}
-
-void mc_enable()
-{
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF | 0x40000000;
- //Enable MIPI CAL clock.
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFDFFFFFF | 0x2000000;
- //Enable MC clock.
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE | 1;
- //Enable EMC DLL clock.
- CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & 0xFFFFBFFF | 0x4000;
- CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x2000001; //Clear EMC and MC reset.
- sleep(5);
-}
-
-clock_t clock_unk1 = { 0x358, 0x360, 0x42C, 0x1F, 0, 0 };
-clock_t clock_unk2 = { 0x358, 0x360, 0, 0x1E, 0, 0 };
-
-void nx_hwinit()
-{
- enable_clocks();
- clock_enable_se();
- clock_enable_fuse(1);
- fuse_disable_program();
-
- mc_enable();
-
- config_oscillators();
- _REG(0x70000000, 0x40) = 0;
-
- config_gpios();
-
- clock_enable_i2c(I2C_1);
- clock_enable_i2c(I2C_5);
- clock_enable(&clock_unk1);
- clock_enable(&clock_unk2);
-
- i2c_init(I2C_1);
- i2c_init(I2C_5);
-
- //Config PMIC (TODO: use max77620.h)
- i2c_send_byte(I2C_5, 0x3C, 4, 0x40);
- i2c_send_byte(I2C_5, 0x3C, 0x41, 0x78);
- i2c_send_byte(I2C_5, 0x3C, 0x43, 0x38);
- i2c_send_byte(I2C_5, 0x3C, 0x44, 0x3A);
- i2c_send_byte(I2C_5, 0x3C, 0x45, 0x38);
- i2c_send_byte(I2C_5, 0x3C, 0x4A, 0xF);
- i2c_send_byte(I2C_5, 0x3C, 0x4E, 0xC7);
- i2c_send_byte(I2C_5, 0x3C, 0x4F, 0x4F);
- i2c_send_byte(I2C_5, 0x3C, 0x50, 0x29);
- i2c_send_byte(I2C_5, 0x3C, 0x52, 0x1B);
- i2c_send_byte(I2C_5, 0x3C, 0x16, 42); //42 = (1000 * 1125 - 600000) / 12500
-
- config_pmc_scratch();
-
- CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & 0xFFFF8888 | 0x3333;
-
- mc_config_carveout();
-
- sdram_init();
-}
diff --git a/fusee/fusee-primary/src/hwinit/hwinit.h b/fusee/fusee-primary/src/hwinit/hwinit.h
deleted file mode 100644
index fda89d4f4..000000000
--- a/fusee/fusee-primary/src/hwinit/hwinit.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _HWINIT_H_
-#define _HWINIT_H_
-
-void mc_config_tsec_carveout(u32 bom, u32 size1mb, int lock);
-void mc_enable_ahb_redirect();
-void mc_disable_ahb_redirect();
-void nx_hwinit();
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/hwinit_fuse.c b/fusee/fusee-primary/src/hwinit/hwinit_fuse.c
deleted file mode 100644
index 80fa85788..000000000
--- a/fusee/fusee-primary/src/hwinit/hwinit_fuse.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "fuse.h"
-#include "t210.h"
-
-void fuse_disable_program()
-{
- FUSE(FUSE_DISABLEREGPROGRAM) = 1;
-}
-
-u32 fuse_read_odm(u32 idx)
-{
- return FUSE(FUSE_RESERVED_ODMX(idx));
-}
diff --git a/fusee/fusee-primary/src/hwinit/i2c.c b/fusee/fusee-primary/src/hwinit/i2c.c
deleted file mode 100644
index b44b9ffa5..000000000
--- a/fusee/fusee-primary/src/hwinit/i2c.c
+++ /dev/null
@@ -1,116 +0,0 @@
-#include
-
-#include "i2c.h"
-#include "util.h"
-
-static u32 i2c_addrs[] = { 0x7000C000, 0x7000C400, 0x7000C500, 0x7000C700, 0x7000D000, 0x7000D100 };
-
-static void _i2c_wait(vu32 *base)
-{
- base[0x23] = 0x25;
- for (u32 i = 0; i < 20; i++)
- {
- sleep(1);
- if (!(base[0x23] & 1))
- break;
- }
-}
-
-static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
-{
- if (size > 4)
- return 0;
-
- u32 tmp = 0;
- memcpy(&tmp, buf, size);
-
- vu32 *base = (vu32 *)i2c_addrs[idx];
- base[1] = x << 1; //Set x (send mode).
- base[3] = tmp; //Set value.
- base[0] = (2 * size - 2) | 0x2800; //Set size and send mode.
- _i2c_wait(base); //Kick transaction.
-
- base[0] = base[0] & 0xFFFFFDFF | 0x200;
- while (base[7] & 0x100)
- ;
-
- if (base[7] << 28)
- return 0;
-
- return 1;
-}
-
-static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
-{
- if (size > 4)
- return 0;
-
- vu32 *base = (vu32 *)i2c_addrs[idx];
- base[1] = (x << 1) | 1; //Set x (recv mode).
- base[0] = (2 * size - 2) | 0x2840; //Set size and recv mode.
- _i2c_wait(base); //Kick transaction.
-
- base[0] = base[0] & 0xFFFFFDFF | 0x200;
- while (base[7] & 0x100)
- ;
-
- if (base[7] << 28)
- return 0;
-
- u32 tmp = base[3]; //Get value.
- memcpy(buf, &tmp, size);
-
- return 1;
-}
-
-void i2c_init(u32 idx)
-{
- vu32 *base = (vu32 *)i2c_addrs[idx];
-
- base[0x1B] = 0x50001;
- base[0x21] = 0x90003;
- _i2c_wait(base);
-
- for (u32 i = 0; i < 10; i++)
- {
- sleep(20000);
- if (base[0x1A] & 0x800)
- break;
- }
-
- vu32 dummy = base[0x22];
- base[0x1A] = base[0x1A];
-}
-
-int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
-{
- u8 tmp[4];
-
- if (size > 3)
- return 0;
-
- tmp[0] = y;
- memcpy(tmp + 1, buf, size);
-
- return _i2c_send_pkt(idx, x, tmp, size + 1);
-}
-
-int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
-{
- int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);
- if (res)
- res = _i2c_recv_pkt(idx, buf, size, x);
- return res;
-}
-
-void i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)
-{
- i2c_send_buf_small(idx, x, y, &b, 1);
-}
-
-u8 i2c_recv_byte(u32 idx, u32 x, u32 y)
-{
- u8 tmp;
- i2c_recv_buf_small(&tmp, 1, idx, x, y);
- return tmp;
-}
diff --git a/fusee/fusee-primary/src/hwinit/i2c.h b/fusee/fusee-primary/src/hwinit/i2c.h
deleted file mode 100644
index 921533d6b..000000000
--- a/fusee/fusee-primary/src/hwinit/i2c.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _I2C_H_
-#define _I2C_H_
-
-#include "types.h"
-
-#define I2C_1 0
-#define I2C_2 1
-#define I2C_3 2
-#define I2C_4 3
-#define I2C_5 4
-#define I2C_6 5
-
-void i2c_init(u32 idx);
-int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
-int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);
-void i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
-u8 i2c_recv_byte(u32 idx, u32 x, u32 y);
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/max77620.h b/fusee/fusee-primary/src/hwinit/max77620.h
deleted file mode 100644
index 7223067dc..000000000
--- a/fusee/fusee-primary/src/hwinit/max77620.h
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Defining registers address and its bit definitions of MAX77620 and MAX20024
- *
- * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
- *
- * 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.
- */
-
-#ifndef _MFD_MAX77620_H_
-#define _MFD_MAX77620_H_
-
-/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */
-#define MAX77620_REG_CNFGGLBL1 0x00
-#define MAX77620_REG_CNFGGLBL2 0x01
-#define MAX77620_REG_CNFGGLBL3 0x02
-#define MAX77620_REG_CNFG1_32K 0x03
-#define MAX77620_REG_CNFGBBC 0x04
-#define MAX77620_REG_IRQTOP 0x05
-#define MAX77620_REG_INTLBT 0x06
-#define MAX77620_REG_IRQSD 0x07
-#define MAX77620_REG_IRQ_LVL2_L0_7 0x08
-#define MAX77620_REG_IRQ_LVL2_L8 0x09
-#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A
-#define MAX77620_REG_ONOFFIRQ 0x0B
-#define MAX77620_REG_NVERC 0x0C
-#define MAX77620_REG_IRQTOPM 0x0D
-#define MAX77620_REG_INTENLBT 0x0E
-#define MAX77620_REG_IRQMASKSD 0x0F
-#define MAX77620_REG_IRQ_MSK_L0_7 0x10
-#define MAX77620_REG_IRQ_MSK_L8 0x11
-#define MAX77620_REG_ONOFFIRQM 0x12
-#define MAX77620_REG_STATLBT 0x13
-#define MAX77620_REG_STATSD 0x14
-#define MAX77620_REG_ONOFFSTAT 0x15
-
-/* SD and LDO Registers */
-#define MAX77620_REG_SD0 0x16
-#define MAX77620_REG_SD1 0x17
-#define MAX77620_REG_SD2 0x18
-#define MAX77620_REG_SD3 0x19
-#define MAX77620_REG_SD4 0x1A
-#define MAX77620_REG_DVSSD0 0x1B
-#define MAX77620_REG_DVSSD1 0x1C
-#define MAX77620_REG_SD0_CFG 0x1D
-#define MAX77620_REG_SD1_CFG 0x1E
-#define MAX77620_REG_SD2_CFG 0x1F
-#define MAX77620_REG_SD3_CFG 0x20
-#define MAX77620_REG_SD4_CFG 0x21
-#define MAX77620_REG_SD_CFG2 0x22
-#define MAX77620_REG_LDO0_CFG 0x23
-#define MAX77620_REG_LDO0_CFG2 0x24
-#define MAX77620_REG_LDO1_CFG 0x25
-#define MAX77620_REG_LDO1_CFG2 0x26
-#define MAX77620_REG_LDO2_CFG 0x27
-#define MAX77620_REG_LDO2_CFG2 0x28
-#define MAX77620_REG_LDO3_CFG 0x29
-#define MAX77620_REG_LDO3_CFG2 0x2A
-#define MAX77620_REG_LDO4_CFG 0x2B
-#define MAX77620_REG_LDO4_CFG2 0x2C
-#define MAX77620_REG_LDO5_CFG 0x2D
-#define MAX77620_REG_LDO5_CFG2 0x2E
-#define MAX77620_REG_LDO6_CFG 0x2F
-#define MAX77620_REG_LDO6_CFG2 0x30
-#define MAX77620_REG_LDO7_CFG 0x31
-#define MAX77620_REG_LDO7_CFG2 0x32
-#define MAX77620_REG_LDO8_CFG 0x33
-#define MAX77620_REG_LDO8_CFG2 0x34
-#define MAX77620_REG_LDO_CFG3 0x35
-
-#define MAX77620_LDO_SLEW_RATE_MASK 0x1
-
-/* LDO Configuration 3 */
-#define MAX77620_TRACK4_MASK (1 << 5)
-#define MAX77620_TRACK4_SHIFT 5
-
-/* Voltage */
-#define MAX77620_SDX_VOLT_MASK 0xFF
-#define MAX77620_SD0_VOLT_MASK 0x3F
-#define MAX77620_SD1_VOLT_MASK 0x7F
-#define MAX77620_LDO_VOLT_MASK 0x3F
-
-#define MAX77620_REG_GPIO0 0x36
-#define MAX77620_REG_GPIO1 0x37
-#define MAX77620_REG_GPIO2 0x38
-#define MAX77620_REG_GPIO3 0x39
-#define MAX77620_REG_GPIO4 0x3A
-#define MAX77620_REG_GPIO5 0x3B
-#define MAX77620_REG_GPIO6 0x3C
-#define MAX77620_REG_GPIO7 0x3D
-#define MAX77620_REG_PUE_GPIO 0x3E
-#define MAX77620_REG_PDE_GPIO 0x3F
-#define MAX77620_REG_AME_GPIO 0x40
-#define MAX77620_REG_ONOFFCNFG1 0x41
-#define MAX77620_REG_ONOFFCNFG2 0x42
-
-/* FPS Registers */
-#define MAX77620_REG_FPS_CFG0 0x43
-#define MAX77620_REG_FPS_CFG1 0x44
-#define MAX77620_REG_FPS_CFG2 0x45
-#define MAX77620_REG_FPS_LDO0 0x46
-#define MAX77620_REG_FPS_LDO1 0x47
-#define MAX77620_REG_FPS_LDO2 0x48
-#define MAX77620_REG_FPS_LDO3 0x49
-#define MAX77620_REG_FPS_LDO4 0x4A
-#define MAX77620_REG_FPS_LDO5 0x4B
-#define MAX77620_REG_FPS_LDO6 0x4C
-#define MAX77620_REG_FPS_LDO7 0x4D
-#define MAX77620_REG_FPS_LDO8 0x4E
-#define MAX77620_REG_FPS_SD0 0x4F
-#define MAX77620_REG_FPS_SD1 0x50
-#define MAX77620_REG_FPS_SD2 0x51
-#define MAX77620_REG_FPS_SD3 0x52
-#define MAX77620_REG_FPS_SD4 0x53
-#define MAX77620_REG_FPS_NONE 0
-
-#define MAX77620_FPS_SRC_MASK 0xC0
-#define MAX77620_FPS_SRC_SHIFT 6
-#define MAX77620_FPS_PU_PERIOD_MASK 0x38
-#define MAX77620_FPS_PU_PERIOD_SHIFT 3
-#define MAX77620_FPS_PD_PERIOD_MASK 0x07
-#define MAX77620_FPS_PD_PERIOD_SHIFT 0
-#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
-#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
-#define MAX77620_FPS_EN_SRC_MASK 0x06
-#define MAX77620_FPS_EN_SRC_SHIFT 1
-#define MAX77620_FPS_ENFPS_SW_MASK 0x01
-#define MAX77620_FPS_ENFPS_SW 0x01
-
-/* Minimum and maximum FPS period time (in microseconds) are
- * different for MAX77620 and Max20024.
- */
-#define MAX77620_FPS_PERIOD_MIN_US 40
-#define MAX20024_FPS_PERIOD_MIN_US 20
-
-#define MAX77620_FPS_PERIOD_MAX_US 2560
-#define MAX20024_FPS_PERIOD_MAX_US 5120
-
-#define MAX77620_REG_FPS_GPIO1 0x54
-#define MAX77620_REG_FPS_GPIO2 0x55
-#define MAX77620_REG_FPS_GPIO3 0x56
-#define MAX77620_REG_FPS_RSO 0x57
-#define MAX77620_REG_CID0 0x58
-#define MAX77620_REG_CID1 0x59
-#define MAX77620_REG_CID2 0x5A
-#define MAX77620_REG_CID3 0x5B
-#define MAX77620_REG_CID4 0x5C
-#define MAX77620_REG_CID5 0x5D
-
-#define MAX77620_REG_DVSSD4 0x5E
-#define MAX20024_REG_MAX_ADD 0x70
-
-#define MAX77620_CID_DIDM_MASK 0xF0
-#define MAX77620_CID_DIDM_SHIFT 4
-
-/* CNCG2SD */
-#define MAX77620_SD_CNF2_ROVS_EN_SD1 (1 << 1)
-#define MAX77620_SD_CNF2_ROVS_EN_SD0 (1 << 2)
-
-/* Device Identification Metal */
-#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
-/* Device Indentification OTP */
-#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
-
-/* SD CNFG1 */
-#define MAX77620_SD_SR_MASK 0xC0
-#define MAX77620_SD_SR_SHIFT 6
-#define MAX77620_SD_POWER_MODE_MASK 0x30
-#define MAX77620_SD_POWER_MODE_SHIFT 4
-#define MAX77620_SD_CFG1_ADE_MASK (1 << 3)
-#define MAX77620_SD_CFG1_ADE_DISABLE 0
-#define MAX77620_SD_CFG1_ADE_ENABLE (1 << 3)
-#define MAX77620_SD_FPWM_MASK 0x04
-#define MAX77620_SD_FPWM_SHIFT 2
-#define MAX77620_SD_FSRADE_MASK 0x01
-#define MAX77620_SD_FSRADE_SHIFT 0
-#define MAX77620_SD_CFG1_FPWM_SD_MASK (1 << 2)
-#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
-#define MAX77620_SD_CFG1_FPWM_SD_FPWM (1 << 2)
-#define MAX20024_SD_CFG1_MPOK_MASK (1 << 1)
-#define MAX77620_SD_CFG1_FSRADE_SD_MASK (1 << 0)
-#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
-#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE (1 << 0)
-
-/* LDO_CNFG2 */
-#define MAX77620_LDO_POWER_MODE_MASK 0xC0
-#define MAX77620_LDO_POWER_MODE_SHIFT 6
-#define MAX20024_LDO_CFG2_MPOK_MASK (1 << 2)
-#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
-#define MAX77620_LDO_CFG2_ADE_DISABLE 0
-#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
-#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
-#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
-#define MAX77620_LDO_CFG2_SS_SLOW 0
-
-#define MAX77620_IRQ_TOP_GLBL_MASK (1 << 7)
-#define MAX77620_IRQ_TOP_SD_MASK (1 << 6)
-#define MAX77620_IRQ_TOP_LDO_MASK (1 << 5)
-#define MAX77620_IRQ_TOP_GPIO_MASK (1 << 4)
-#define MAX77620_IRQ_TOP_RTC_MASK (1 << 3)
-#define MAX77620_IRQ_TOP_32K_MASK (1 << 2)
-#define MAX77620_IRQ_TOP_ONOFF_MASK (1 << 1)
-
-#define MAX77620_IRQ_LBM_MASK (1 << 3)
-#define MAX77620_IRQ_TJALRM1_MASK (1 << 2)
-#define MAX77620_IRQ_TJALRM2_MASK (1 << 1)
-
-#define MAX77620_CNFG_GPIO_DRV_MASK (1 << 0)
-#define MAX77620_CNFG_GPIO_DRV_PUSHPULL (1 << 0)
-#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN 0
-#define MAX77620_CNFG_GPIO_DIR_MASK (1 << 1)
-#define MAX77620_CNFG_GPIO_DIR_INPUT (1 << 1)
-#define MAX77620_CNFG_GPIO_DIR_OUTPUT 0
-#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK (1 << 2)
-#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK (1 << 3)
-#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH (1 << 3)
-#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW 0
-#define MAX77620_CNFG_GPIO_INT_MASK (0x3 << 4)
-#define MAX77620_CNFG_GPIO_INT_FALLING (1 << 4)
-#define MAX77620_CNFG_GPIO_INT_RISING (1 << 5)
-#define MAX77620_CNFG_GPIO_DBNC_MASK (0x3 << 6)
-#define MAX77620_CNFG_GPIO_DBNC_None (0x0 << 6)
-#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
-#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
-#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
-
-#define MAX77620_IRQ_LVL2_GPIO_EDGE0 (1 << 0)
-#define MAX77620_IRQ_LVL2_GPIO_EDGE1 (1 << 1)
-#define MAX77620_IRQ_LVL2_GPIO_EDGE2 (1 << 2)
-#define MAX77620_IRQ_LVL2_GPIO_EDGE3 (1 << 3)
-#define MAX77620_IRQ_LVL2_GPIO_EDGE4 (1 << 4)
-#define MAX77620_IRQ_LVL2_GPIO_EDGE5 (1 << 5)
-#define MAX77620_IRQ_LVL2_GPIO_EDGE6 (1 << 6)
-#define MAX77620_IRQ_LVL2_GPIO_EDGE7 (1 << 7)
-
-#define MAX77620_CNFG1_32K_OUT0_EN (1 << 2)
-
-#define MAX77620_ONOFFCNFG1_SFT_RST (1 << 7)
-#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
-#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
-#define MAX77620_ONOFFCNFG1_SLPEN (1 << 2)
-#define MAX77620_ONOFFCNFG1_PWR_OFF (1 << 1)
-#define MAX20024_ONOFFCNFG1_CLRSE 0x18
-
-#define MAX77620_ONOFFCNFG2_SFT_RST_WK (1 << 7)
-#define MAX77620_ONOFFCNFG2_WD_RST_WK (1 << 6)
-#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK (1 << 5)
-#define MAX77620_ONOFFCNFG2_WK_ALARM1 (1 << 2)
-#define MAX77620_ONOFFCNFG2_WK_EN0 (1 << 0)
-
-#define MAX77620_GLBLM_MASK (1 << 0)
-
-#define MAX77620_WDTC_MASK 0x3
-#define MAX77620_WDTOFFC (1 << 4)
-#define MAX77620_WDTSLPC (1 << 3)
-#define MAX77620_WDTEN (1 << 2)
-
-#define MAX77620_TWD_MASK 0x3
-#define MAX77620_TWD_2s 0x0
-#define MAX77620_TWD_16s 0x1
-#define MAX77620_TWD_64s 0x2
-#define MAX77620_TWD_128s 0x3
-
-#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7)
-#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
-#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
-#define MAX77620_CNFGGLBL1_LBDAC 0x0E
-#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0)
-
-/* CNFG BBC registers */
-#define MAX77620_CNFGBBC_ENABLE (1 << 0)
-#define MAX77620_CNFGBBC_CURRENT_MASK 0x06
-#define MAX77620_CNFGBBC_CURRENT_SHIFT 1
-#define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18
-#define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3
-#define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE (1 << 5)
-#define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0
-#define MAX77620_CNFGBBC_RESISTOR_SHIFT 6
-
-#define MAX77620_FPS_COUNT 3
-
-/* Interrupts */
-enum {
- MAX77620_IRQ_TOP_GLBL, /* Low-Battery */
- MAX77620_IRQ_TOP_SD, /* SD power fail */
- MAX77620_IRQ_TOP_LDO, /* LDO power fail */
- MAX77620_IRQ_TOP_GPIO, /* TOP GPIO internal int to MAX77620 */
- MAX77620_IRQ_TOP_RTC, /* RTC */
- MAX77620_IRQ_TOP_32K, /* 32kHz oscillator */
- MAX77620_IRQ_TOP_ONOFF, /* ON/OFF oscillator */
- MAX77620_IRQ_LBT_MBATLOW, /* Thermal alarm status, > 120C */
- MAX77620_IRQ_LBT_TJALRM1, /* Thermal alarm status, > 120C */
- MAX77620_IRQ_LBT_TJALRM2, /* Thermal alarm status, > 140C */
-};
-
-/* GPIOs */
-enum {
- MAX77620_GPIO0,
- MAX77620_GPIO1,
- MAX77620_GPIO2,
- MAX77620_GPIO3,
- MAX77620_GPIO4,
- MAX77620_GPIO5,
- MAX77620_GPIO6,
- MAX77620_GPIO7,
- MAX77620_GPIO_NR,
-};
-
-/* FPS Source */
-enum max77620_fps_src {
- MAX77620_FPS_SRC_0,
- MAX77620_FPS_SRC_1,
- MAX77620_FPS_SRC_2,
- MAX77620_FPS_SRC_NONE,
- MAX77620_FPS_SRC_DEF,
-};
-
-enum max77620_chip_id {
- MAX77620,
- MAX20024,
-};
-
-#endif /* _MFD_MAX77620_H_ */
diff --git a/fusee/fusee-primary/src/hwinit/max7762x.c b/fusee/fusee-primary/src/hwinit/max7762x.c
deleted file mode 100755
index 67caaf230..000000000
--- a/fusee/fusee-primary/src/hwinit/max7762x.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
-* Copyright (c) 2018 naehrwert
-*
-* 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 .
-*/
-
-#include "max7762x.h"
-#include "max77620.h"
-#include "i2c.h"
-#include "util.h"
-
-#define REGULATOR_SD 0
-#define REGULATOR_LDO 1
-
-typedef struct _max77620_regulator_t
-{
- u8 type;
- const char *name;
- u8 reg_sd;
- u32 mv_step;
- u32 mv_min;
- u32 mv_default;
- u32 mv_max;
- u8 volt_addr;
- u8 cfg_addr;
- u8 volt_mask;
- u8 enable_mask;
- u8 enable_shift;
- u8 status_mask;
-
- u8 fps_addr;
- u8 fps_src;
- u8 pd_period;
- u8 pu_period;
-} max77620_regulator_t;
-
-static const max77620_regulator_t _pmic_regulators[] = {
- { REGULATOR_SD, "sd0", 0x16, 12500, 600000, 625000, 1400000, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, 0x3F, 0x30, 4, 0x80, 0x4F, 1, 7, 1 },
- { REGULATOR_SD, "sd1", 0x17, 12500, 600000, 1125000, 1125000, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, 0x3F, 0x30, 4, 0x40, 0x50, 0, 1, 5 },
- { REGULATOR_SD, "sd2", 0x18, 12500, 600000, 1325000, 1350000, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, 0xFF, 0x30, 4, 0x20, 0x51, 1, 5, 2 },
- { REGULATOR_SD, "sd3", 0x19, 12500, 600000, 1800000, 1800000, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, 0xFF, 0x30, 4, 0x10, 0x52, 0, 3, 3 },
- { REGULATOR_LDO, "ldo0", 0x00, 25000, 800000, 1200000, 1200000, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, 0x3F, 0xC0, 6, 0x00, 0x46, 3, 7, 0 },
- { REGULATOR_LDO, "ldo1", 0x00, 25000, 800000, 1050000, 1050000, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, 0x3F, 0xC0, 6, 0x00, 0x47, 3, 7, 0 },
- { REGULATOR_LDO, "ldo2", 0x00, 50000, 800000, 1800000, 3300000, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, 0x3F, 0xC0, 6, 0x00, 0x48, 3, 7, 0 },
- { REGULATOR_LDO, "ldo3", 0x00, 50000, 800000, 3100000, 3100000, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, 0x3F, 0xC0, 6, 0x00, 0x49, 3, 7, 0 },
- { REGULATOR_LDO, "ldo4", 0x00, 12500, 800000, 850000, 850000, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4A, 0, 7, 1 },
- { REGULATOR_LDO, "ldo5", 0x00, 50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4B, 3, 7, 0 },
- { REGULATOR_LDO, "ldo6", 0x00, 50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4C, 3, 7, 0 },
- { REGULATOR_LDO, "ldo7", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4D, 1, 4, 3 },
- { REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4E, 3, 7, 0 }
-};
-
-int max77620_regulator_get_status(u32 id)
-{
- if (id > REGULATOR_MAX)
- return 0;
-
- const max77620_regulator_t *reg = &_pmic_regulators[id];
-
- if (reg->type == REGULATOR_SD)
- return i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_STATSD) & reg->status_mask ? 0 : 1;
- return i2c_recv_byte(I2C_5, 0x3C, reg->cfg_addr) & 8 ? 1 : 0;
-}
-
-int max77620_regulator_config_fps(u32 id)
-{
- if (id > REGULATOR_MAX)
- return 0;
-
- const max77620_regulator_t *reg = &_pmic_regulators[id];
-
- i2c_send_byte(I2C_5, 0x3C, reg->fps_addr, (reg->fps_src << 6) | (reg->pu_period << 3) | (reg->pd_period));
-
- return 1;
-}
-
-int max77620_regulator_set_voltage(u32 id, u32 mv)
-{
- if (id > REGULATOR_MAX)
- return 0;
-
- const max77620_regulator_t *reg = &_pmic_regulators[id];
-
- if (mv < reg->mv_default || mv > reg->mv_max)
- return 0;
-
- u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
- u8 val = i2c_recv_byte(I2C_5, 0x3C, reg->volt_addr);
- val = (val & ~reg->volt_mask) | (mult & reg->volt_mask);
- i2c_send_byte(I2C_5, 0x3C, reg->volt_addr, val);
- sleep(1000);
-
- return 1;
-}
-
-int max77620_regulator_enable(u32 id, int enable)
-{
- if (id > REGULATOR_MAX)
- return 0;
-
- const max77620_regulator_t *reg = &_pmic_regulators[id];
-
- u32 addr = reg->type == REGULATOR_SD ? reg->cfg_addr : reg->volt_addr;
- u8 val = i2c_recv_byte(I2C_5, 0x3C, addr);
- if (enable)
- val = (val & ~reg->enable_mask) | ((3 << reg->enable_shift) & reg->enable_mask);
- else
- val &= ~reg->enable_mask;
- i2c_send_byte(I2C_5, 0x3C, addr, val);
- sleep(1000);
-
- return 1;
-}
-
-void max77620_config_default()
-{
- for (u32 i = 1; i <= REGULATOR_MAX; i++)
- {
- i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_CID4);
- max77620_regulator_config_fps(i);
- max77620_regulator_set_voltage(i, _pmic_regulators[i].mv_default);
- if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE)
- max77620_regulator_enable(i, 1);
- }
- i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_SD_CFG2, 4);
-}
diff --git a/fusee/fusee-primary/src/hwinit/pinmux.c b/fusee/fusee-primary/src/hwinit/pinmux.c
deleted file mode 100644
index 269c91a57..000000000
--- a/fusee/fusee-primary/src/hwinit/pinmux.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "pinmux.h"
-#include "t210.h"
-
-void pinmux_config_uart(u32 idx)
-{
- PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = 0;
- PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0x48;
- PINMUX_AUX(PINMUX_AUX_UARTX_RTS(idx)) = 0;
- PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = 0x44;
-}
-
-void pinmux_config_i2c(u32 idx)
-{
- PINMUX_AUX(PINMUX_AUX_X_I2C_SCL(idx)) = 0x40;
- PINMUX_AUX(PINMUX_AUX_X_I2C_SDA(idx)) = 0x40;
-}
diff --git a/fusee/fusee-primary/src/hwinit/pinmux.h b/fusee/fusee-primary/src/hwinit/pinmux.h
deleted file mode 100644
index 59bf506d8..000000000
--- a/fusee/fusee-primary/src/hwinit/pinmux.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _PINMUX_H_
-#define _PINMUX_H_
-
-#include "types.h"
-
-/*! Pinmux registers. */
-#define PINMUX_AUX_UART2_TX 0xF4
-#define PINMUX_AUX_UART3_TX 0x104
-#define PINMUX_AUX_GPIO_PE6 0x248
-#define PINMUX_AUX_GPIO_PH6 0x250
-/*! 0:UART-A, 1:UART-B, 3:UART-C, 3:UART-D */
-#define PINMUX_AUX_UARTX_TX(x) (0xE4 + 0x10 * (x))
-#define PINMUX_AUX_UARTX_RX(x) (0xE8 + 0x10 * (x))
-#define PINMUX_AUX_UARTX_RTS(x) (0xEC + 0x10 * (x))
-#define PINMUX_AUX_UARTX_CTS(x) (0xF0 + 0x10 * (x))
-/*! 0:GEN1, 1:GEN2, 2:GEN3, 3:CAM, 4:PWR */
-#define PINMUX_AUX_X_I2C_SCL(x) (0xBC + 8 * (x))
-#define PINMUX_AUX_X_I2C_SDA(x) (0xC0 + 8 * (x))
-
-void pinmux_config_uart(u32 idx);
-void pinmux_config_i2c(u32 idx);
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/pmc.h b/fusee/fusee-primary/src/hwinit/pmc.h
deleted file mode 100644
index 4c8677239..000000000
--- a/fusee/fusee-primary/src/hwinit/pmc.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _PMC_H_
-#define _PMC_H_
-
-/*! PMC registers. */
-#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
-#define APBDEV_PMC_PWRGATE_STATUS 0x38
-#define APBDEV_PMC_NO_IOPOWER 0x44
-#define APBDEV_PMC_SCRATCH20 0xA0
-#define APBDEV_PMC_DDR_PWR 0xE8
-#define APBDEV_PMC_CRYPTO_OP 0xF4
-#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
-#define APBDEV_PMC_IO_DPD_REQ 0x1B8
-#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
-#define APBDEV_PMC_VDDP_SEL 0x1CC
-#define APBDEV_PMC_TSC_MULT 0x2B4
-#define APBDEV_PMC_REG_SHORT 0x2CC
-#define APBDEV_PMC_WEAK_BIAS 0x2C8
-#define APBDEV_PMC_SECURE_SCRATCH21 0x334
-#define APBDEV_PMC_CNTRL2 0x440
-#define APBDEV_PMC_IO_DPD4_REQ 0x464
-#define APBDEV_PMC_DDR_CNTRL 0x4E4
-#define APBDEV_PMC_SCRATCH188 0x810
-#define APBDEV_PMC_SCRATCH190 0x818
-#define APBDEV_PMC_SCRATCH200 0x840
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/sdram.c b/fusee/fusee-primary/src/hwinit/sdram.c
deleted file mode 100644
index a64d7b886..000000000
--- a/fusee/fusee-primary/src/hwinit/sdram.c
+++ /dev/null
@@ -1,488 +0,0 @@
-#include "i2c.h"
-#include "t210.h"
-#include "mc.h"
-//#include "emc.h"
-#include "pmc.h"
-#include "util.h"
-#include "fuse.h"
-
-#include "sdram.inl"
-
-static u32 _get_sdram_id()
-{
- return (fuse_read_odm(4) & 0x38) >> 3;
-}
-
-static void _sdram_config(const u32 *_cfg)
-{
- const u32 *_cfg_120 = _cfg + 0x120;
- const u32 *_cfg_100 = _cfg + 0x100;
-
- PMC(0x45C) = (((4 * _cfg[0x12F] >> 2) + 0x80000000) ^ 0xFFFF) & 0xC000FFFF;
- sleep(_cfg[0x111]);
-
- u32 req = (4 * _cfg_120[0x10] >> 2) + 0x80000000;
- PMC(APBDEV_PMC_IO_DPD4_REQ) = (req ^ 0x3FFF0000) >> 16 << 16;
- sleep(_cfg_100[0x12]);
- PMC(APBDEV_PMC_IO_DPD4_REQ) = (req ^ 0xFFFF) & 0xC000FFFF;
- sleep(_cfg_100[0x12]);
- PMC(APBDEV_PMC_WEAK_BIAS) = 0;
- sleep(1);
-
- CLOCK(0x98) = _cfg[4];
- CLOCK(0x9C) = 0;
- CLOCK(0x90) = (_cfg[2] << 8) | (*((u16 *)_cfg + 0xA) << 20) | _cfg[1] | 0x40000000;
-
- u32 wait_end = TMR(0x10) + 300;
- while (!((CLOCK(0x90) >> 27) & 1))
- {
- if (TMR(0x10) >= wait_end)
- goto break_nosleep;
- }
- sleep(10);
-break_nosleep:
-
- CLOCK(0x19C) = _cfg[0x16] & 0xFFFEFFFF | (_cfg[0x175] >> 11) & 0x10000;
- if (_cfg[0x17])
- CLOCK(0x664) = _cfg[0x17];
- if (_cfg[0x1A])
- CLOCK(0x44C) = 0x40000000;
- CLOCK(0x328) = 0x2000001;
- CLOCK(0x284) = 0x4000;
- CLOCK(0x30C) = 0x2000001;
- EMC(0xC34) = _cfg_120[0x13];
- EMC(0xC38) = _cfg_120[0x14];
- EMC(0xCF0) = _cfg_120[0x15];
- EMC(0x28) = 1;
- sleep(1);
- EMC(0x8) = _cfg[0xA9] | 2 * _cfg[0xAA];
- if (_cfg[0xA])
- *(vu32 *)_cfg[0xA] = _cfg[0xB];
- EMC(0x584) = _cfg[0x7B];
- EMC(0x380) = _cfg[0x7D];
- EMC(0x384) = _cfg[0x7E];
- EMC(0x388) = _cfg[0x7F];
- EMC(0x38C) = _cfg[0x80];
- EMC(0x390) = _cfg[0x81];
- EMC(0x394) = _cfg[0x82];
- EMC(0x398) = _cfg[0x83];
- EMC(0x39C) = _cfg[0x84];
- EMC(0x3A0) = _cfg[0x85];
- EMC(0x3A4) = _cfg[0x86];
- EMC(0x3A8) = _cfg[0x87];
- EMC(0x3AC) = _cfg[0x88];
- EMC(0x3B0) = _cfg[0x89];
- EMC(0xC80) = _cfg[0x14A];
- EMC(0xC84) = _cfg[0x14B];
- EMC(0xC88) = _cfg[0x14C];
- EMC(0x330) = (_cfg_120[0x16] | 0xFEEDFEED) & 0x1FFF1FFF;
- EMC(0x5F0) = _cfg[0x149];
- EMC(0x5C8) = _cfg[0x7C];
- EMC(0x404) = _cfg_100[0x18];
- EMC(0x408) = _cfg_100[0x19];
- EMC(0x40C) = _cfg_100[0x1A];
- EMC(0x410) = _cfg_100[0x1B];
- EMC(0x418) = _cfg_100[0x1C];
- EMC(0x41C) = _cfg_100[0x1D];
- EMC(0x420) = _cfg_100[0x1E];
- EMC(0x424) = _cfg_100[0x1F];
- if (_cfg[0xE])
- *(vu32 *)_cfg[0xE] = _cfg[0xF];
- EMC(0x30C) = _cfg[0x31];
- EMC(0x578) = _cfg[0x32];
- EMC(0x2F4) = _cfg[0x33];
- EMC(0x458) = _cfg[0x1D];
- EMC(0x45C) = _cfg[0x1E];
- EMC(0x5B0) = _cfg[0x1F];
- EMC(0x5B4) = _cfg[0x20];
- EMC(0x5CC) = _cfg[0x21];
- EMC(0x574) = _cfg[0x22];
- EMC(0x2DC) = _cfg[0x23];
- EMC(0xC48) = _cfg[0x2A];
- EMC(0xC70) = _cfg[0x2B];
- EMC(0xC74) = _cfg[0x2C];
- EMC(0xC4C) = _cfg[0x2D];
- EMC(0xC78) = _cfg[0x2E];
- EMC(0x464) = _cfg[0x26];
- EMC(0xC44) = _cfg[0x2F];
- EMC(0x5E4) = _cfg_120[0xD];
- EMC(0x5E8) = _cfg_120[0xE];
- EMC(0x2C8) = _cfg[0xB0];
- EMC(0x588) = _cfg_120[1];
- EMC(0x58C) = _cfg_120[2];
- EMC(0x594) = _cfg_120[3];
- EMC(0x598) = _cfg_120[4];
- EMC(0x59C) = _cfg_120[5];
- EMC(0x5A0) = _cfg_120[6];
- EMC(0x5A4) = _cfg_120[7];
- EMC(0x5A8) = _cfg_120[8];
- EMC(0x5AC) = _cfg_120[9];
- EMC(0x5B8) = _cfg_120[0xA];
- EMC(0x5BC) = _cfg_120[0xB];
- EMC(0x5C4) = _cfg_120[0xC];
- EMC(0x330) = (_cfg_120[0x16] | 0xFE40FE40) & 0x1FFF1FFF;
- EMC(0xC40) = _cfg_120[0x12];
- EMC(0x318) = _cfg_120[0x17];
- EMC(0x334) = _cfg_120[0x18] & 0xFF7FFF7F;
- EMC(0x31C) = _cfg_120[0x19];
- EMC(0xC3C) = _cfg_120[0x1A];
- EMC(0xC54) = _cfg_120[0x1B];
- EMC(0xC50) = _cfg_120[0x1C];
- EMC(0xC64) = _cfg_120[0x1F];
- EMC(0xC5C) = _cfg_120[0x1D];
- EMC(0xC58) = _cfg_120[0x1E];
- EMC(0xC60) = _cfg[0x141];
- EMC(0x49C) = _cfg[0x142];
- EMC(0x720) = _cfg[0x143];
- EMC(0x724) = _cfg[0x144];
- EMC(0x728) = _cfg[0x145];
- EMC(0x72C) = _cfg[0x146];
- EMC(0x730) = _cfg[0x147];
- EMC(0x734) = _cfg[0x148];
- EMC(0x740) = _cfg[0x14D];
- EMC(0x744) = _cfg[0x14E];
- EMC(0x748) = _cfg[0x14F];
- EMC(0x74C) = _cfg[0x150];
- EMC(0x750) = _cfg[0x151];
- EMC(0x754) = _cfg[0x152];
- EMC(0x760) = _cfg[0x153];
- EMC(0x770) = _cfg[0x154];
- EMC(0x774) = _cfg[0x155];
- EMC(0x778) = _cfg[0x156];
- EMC(0x780) = _cfg[0x157];
- EMC(0x784) = _cfg[0x158];
- EMC(0x788) = _cfg[0x159];
- EMC(0xBE0) = _cfg[0xB6];
- EMC(0xBE4) = _cfg[0xB7];
- EMC(0xBF0) = _cfg[0xB8];
- EMC(0xBF4) = _cfg[0xB9];
- EMC(0xCF4) = _cfg[0xBA];
- EMC(0x600) = _cfg[0xBD];
- EMC(0x604) = _cfg[0xBE];
- EMC(0x608) = _cfg[0xBF];
- EMC(0x60C) = _cfg[0xC0];
- EMC(0x610) = _cfg[0xC1];
- EMC(0x614) = _cfg[0xC2];
- EMC(0x620) = _cfg[0xC3];
- EMC(0x624) = _cfg[0xC4];
- EMC(0x628) = _cfg[0xC5];
- EMC(0x62C) = _cfg[0xC6];
- EMC(0x630) = _cfg[0xC7];
- EMC(0x634) = _cfg[0xC8];
- EMC(0x330) = _cfg_120[0x16];
- EMC(0x640) = _cfg[0xC9];
- EMC(0x644) = _cfg[0xCA];
- EMC(0x648) = _cfg[0xCB];
- EMC(0x64C) = _cfg[0xCC];
- EMC(0x650) = _cfg[0xCD];
- EMC(0x654) = _cfg[0xCE];
- EMC(0x660) = _cfg[0xCF];
- EMC(0x664) = _cfg[0xD0];
- EMC(0x668) = _cfg[0xD1];
- EMC(0x66C) = _cfg[0xD2];
- EMC(0x670) = _cfg[0xD3];
- EMC(0x674) = _cfg[0xD4];
- EMC(0x680) = _cfg[0xD5];
- EMC(0x684) = _cfg[0xD6];
- EMC(0x688) = _cfg[0xD7];
- EMC(0x68C) = _cfg[0xD8];
- EMC(0x690) = _cfg[0xD9];
- EMC(0x694) = _cfg[0xDA];
- EMC(0x6A0) = _cfg[0xDB];
- EMC(0x6A4) = _cfg[0xDC];
- EMC(0x6A8) = _cfg[0xDD];
- EMC(0x6AC) = _cfg[0xDE];
- EMC(0x6B0) = _cfg[0xDF];
- EMC(0x6B4) = _cfg[0xE0];
- EMC(0x6C0) = _cfg[0xE1];
- EMC(0x6C4) = _cfg[0xE2];
- EMC(0x6C8) = _cfg[0xE3];
- EMC(0x6CC) = _cfg[0xE4];
- EMC(0x6E0) = _cfg[0xE5];
- EMC(0x6E4) = _cfg[0xE6];
- EMC(0x6E8) = _cfg[0xE7];
- EMC(0x6EC) = _cfg[0xE8];
- EMC(0xC00) = _cfg[0xE9];
- EMC(0xC04) = _cfg[0xEA];
- EMC(0xC08) = _cfg[0xEB];
- EMC(0xC0C) = _cfg[0xEC];
- EMC(0xC10) = _cfg[0xED];
- EMC(0xC20) = _cfg[0xEE];
- EMC(0xC24) = _cfg[0xEF];
- EMC(0xC28) = _cfg[0xF0];
- EMC(0xC68) = (*((u8 *)_cfg + 0x500) | 0xFFFFFFFE) & 0xF;
- if (_cfg[0xC])
- *(vu32 *)_cfg[0xC] = _cfg[0xD];
- EMC(0x28) = 1;
- MC(0x648) = _cfg[0x180];
- MC(0x978) = _cfg[0x181];
- MC(0x64C) = _cfg[0x182];
- MC(0x418) = _cfg[0x183];
- MC(0x590) = _cfg[0x184];
- MC(0x984) = _cfg[0x185];
- MC(0x988) = _cfg[0x186];
- MC(0x54) = _cfg[0x15A];
- MC(0x58) = _cfg[0x15B];
- MC(0x5C) = _cfg[0x15C];
- MC(0x60) = _cfg[0x15D];
- MC(0x64) = _cfg[0x15E];
- MC(0x68) = _cfg[0x15F];
- MC(0x6C) = _cfg[0x160];
- MC(0x50) = _cfg[0x161];
- MC(0x670) = _cfg[0x187];
- MC(0x9D4) = _cfg[0x188];
- MC(0x674) = _cfg[0x189];
- MC(0x9A0) = _cfg[0x1D6];
- MC(0x9A8) = _cfg[0x1D7];
- MC(0x9A4) = _cfg[0x1D8];
- MC(0x90) = _cfg[0x162];
- MC(0x94) = _cfg[0x163];
- MC(0x6F0) = _cfg[0x164];
- MC(0x6F4) = _cfg[0x165];
- MC(0x98) = _cfg[0x166];
- MC(0x9C) = _cfg[0x167];
- MC(0xA0) = _cfg[0x168];
- MC(0xA4) = _cfg[0x169];
- MC(0xA8) = _cfg[0x16A];
- MC(0xAC) = _cfg[0x16B];
- MC(0xB0) = _cfg[0x16C];
- MC(0xB4) = _cfg[0x16D];
- MC(0xB8) = _cfg[0x16E];
- MC(0xBC) = _cfg[0x16F];
- MC(0x6C4) = _cfg[0x17D];
- MC(0xC0) = _cfg[0x170];
- MC(0xC4) = _cfg[0x171];
- MC(0x6C0) = _cfg[0x172];
- MC(0xD0) = _cfg[0x173];
- MC(0xD4) = _cfg[0x174];
- MC(0xD8) = _cfg[0x175];
- MC(0xDC) = _cfg[0x176];
- MC(0xC8) = _cfg[0x177];
- MC(0xE0) = _cfg[0x178];
- MC(0xE8) = _cfg[0x179];
- MC(0x968) = _cfg[0x17A];
- MC(0xEC) = _cfg[0x17B];
- MC(0x9DC) = _cfg[0x17C];
- MC(0xFC) = 1;
- MC(0xF4) = _cfg[0x17E];
- MC(0x100) = _cfg[0x17F];
- EMC(0x10) = _cfg[0x34];
- EMC(0x140) = _cfg_100[7];
- EMC(0x700) = _cfg[0x27];
- EMC(0x704) = _cfg[0x28];
- EMC(0x708) = _cfg[0x29];
- EMC(0x2F8) = _cfg[0x24];
- EMC(0x300) = _cfg[0x25];
- EMC(0x2A8) = _cfg[0x1B];
- EMC(0x2A4) = _cfg[0x1C];
- sleep(_cfg[0x30]);
- if (_cfg[0x10])
- *(vu32 *)_cfg[0x10] = _cfg[0x11];
- EMC(0x2B8) = _cfg[0xA4];
- EMC(0x560) = _cfg[0xA5];
- EMC(0x55C) = _cfg[0xBB];
- EMC(0x554) = _cfg[0xBC];
- EMC(0xF0) = _cfg[0xAB];
- EMC(0xF4) = _cfg[0xAC];
- EMC(0xC8) = _cfg[0xA1];
- EMC(0xC4) = _cfg[0xA2];
- EMC(0x104) = _cfg[0x7A];
- EMC(0x2C) = _cfg[0x3A];
- EMC(0x30) = _cfg[0x3B];
- EMC(0x590) = _cfg[0x3C];
- EMC(0x580) = _cfg[0x3D];
- EMC(0xC0) = _cfg[0x3E];
- EMC(0x34) = _cfg[0x3F];
- EMC(0x38) = _cfg[0x40];
- EMC(0xAC) = _cfg[0x47];
- EMC(0x144) = _cfg[0x41];
- EMC(0x148) = _cfg[0x42];
- EMC(0x3C) = _cfg[0x43];
- EMC(0x40) = _cfg[0x44];
- EMC(0x44) = _cfg[0x45];
- EMC(0x48) = _cfg[0x46];
- EMC(0x5C0) = _cfg[0x48];
- EMC(0x4C) = _cfg[0x49];
- EMC(0x50) = _cfg[0x4A];
- EMC(0x54) = _cfg[0x4B];
- EMC(0x58) = _cfg[0x4C];
- EMC(0xB8) = _cfg[0x4D];
- EMC(0x5C) = _cfg[0x4E];
- EMC(0x4E0) = _cfg[0x4F];
- EMC(0x498) = _cfg[0x50];
- EMC(0x494) = _cfg[0x51];
- EMC(0x2D0) = _cfg[0x52];
- EMC(0x490) = _cfg[0x53];
- EMC(0x48C) = _cfg[0x54];
- EMC(0x60) = _cfg[0x55];
- EMC(0x568) = _cfg[0x56];
- EMC(0x468) = _cfg[0x57];
- EMC(0x46C) = _cfg[0x58];
- EMC(0x14C) = _cfg[0x59];
- EMC(0x150) = _cfg[0x5A];
- EMC(0x154) = _cfg[0x5B];
- EMC(0x56C) = _cfg[0x5C];
- EMC(0xC68) = _cfg[0x140];
- EMC(0x8) = _cfg[0xA9];
- EMC(0x64) = _cfg[0x5D];
- EMC(0x428) = 0;
- EMC(0x68) = _cfg[0x5E];
- EMC(0x6C) = _cfg[0x5F];
- EMC(0x2CC) = _cfg[0x60];
- EMC(0x2D8) = _cfg[0x61];
- EMC(0x2D4) = _cfg[0x62];
- EMC(0x564) = _cfg[0x63];
- EMC(0x70) = _cfg[0x64];
- EMC(0x74) = _cfg[0x65];
- EMC(0x3DC) = _cfg[0x66];
- EMC(0x78) = _cfg[0x67];
- EMC(0x7C) = _cfg[0x68];
- EMC(0x80) = _cfg[0x69];
- EMC(0x84) = _cfg[0x6A];
- EMC(0x88) = _cfg[0x6B];
- EMC(0x8C) = _cfg[0x6C];
- EMC(0x11C) = _cfg[0x6D];
- EMC(0x118) = _cfg[0x6E];
- EMC(0xB4) = _cfg[0x6F];
- EMC(0x90) = _cfg[0x70];
- EMC(0x3E4) = _cfg[0x71];
- EMC(0x94) = _cfg[0x72];
- EMC(0x158) = _cfg[0x73];
- EMC(0x15C) = _cfg[0x74];
- EMC(0x98) = _cfg[0x75];
- EMC(0x9C) = _cfg[0x76];
- EMC(0xA0) = _cfg[0x77];
- EMC(0xA4) = _cfg[0x78];
- EMC(0xA8) = _cfg[0x79];
- EMC(0xB0) = _cfg[0xF2];
- EMC(0x2BC) = _cfg[0xAF];
- EMC(0x2C0) = _cfg[0xB1];
- EMC(0x100) = _cfg[0x8A] & 0xFFFFFFFD;
- EMC(0x120) = _cfg[0x8B];
- EMC(0x440) = _cfg_120[0xF];
- EMC(0x444) = _cfg_120[0x10];
- EMC(0x448) = _cfg_120[0x11];
- EMC(0x124) = _cfg_100[0x17];
- EMC(0x480) = *_cfg_120;
- EMC(0xC) = ((_cfg[0xA3] & 4 | 0x3C00000) & 0xFFFFFFF7 | _cfg[0xA3] & 8) & 0xFFFFFFFD | _cfg[0xA3] & 2;
- if ((_cfg[0x1D4] & 0x80000000) != 0)
- {
- *(vu32 *)(4 * _cfg[0x1D4] + 0x70000000) = _cfg[0x1D5];
- MC(0xFC) = 1;
- }
- PMC(0x45C) = ((4 * _cfg_120[0xF] >> 2) + 0x40000000) & 0xCFFF0000;
- sleep(_cfg_100[0x11]);
- if (!_cfg[0x1B])
- EMC(0x2A4) = _cfg[0x1C] | 0x200;
- EMC(0x334) = _cfg_120[0x18];
- if (_cfg[0xFA] << 31)
- {
- if (*_cfg == 2)
- EMC(0x2E4) = 8 * _cfg[0xF4];
- if (*_cfg == 3)
- {
- EMC(0x2E4) = _cfg[0xF4];
- EMC(0x2E8) = _cfg[0xF5];
- }
- }
- EMC(0x28) = 1;
- sleep(_cfg[0x39]);
- PMC(0x4E4) &= 0xFFF8007F;
- sleep(_cfg_100[0x15]);
- if (*_cfg == 2)
- {
- EMC(0x24) = (_cfg[0x37] << 16) | (_cfg[0x38] << 12);
- sleep(_cfg[0x36] + 200);
- EMC(0x24) = ((_cfg[0x37] << 16) | (_cfg[0x38] << 12)) + 0x100;
- sleep(_cfg[0x36] + 500);
- }
- if (*_cfg == 3)
- {
- EMC(0x24) = (_cfg[0x37] << 16) | (_cfg[0x38] << 12);
- sleep(_cfg[0x36] + 200);
- EMC(0x24) = ((_cfg[0x37] << 16) | (_cfg[0x38] << 12)) + 0x100;
- sleep(_cfg[0x36] + 2000);
- }
- EMC(0x24) = ((_cfg[0x37] << 16) | (_cfg[0x38] << 12)) + 0x101;
- sleep(_cfg[0x35]);
- if (*_cfg != 3)
- EMC(0xDC) = (_cfg[0xB2] << 30) + 1;
- if (*_cfg == 1)
- sleep(_cfg[0x36] + 200);
- if (*_cfg == 3)
- {
- if (_cfg[0x12])
- *(vu32 *)_cfg[0x12] = _cfg[0x13];
- EMC(0x134) = _cfg[0x91];
- EMC(0xE8) = _cfg[0x90];
- EMC(0x138) = _cfg[0x92];
- EMC(0x13C) = _cfg[0x93];
- EMC(0x4A4) = _cfg[0x94];
- EMC(0x4C4) = _cfg[0x9A];
- EMC(0x4AC) = _cfg[0x95];
- EMC(0x4BC) = _cfg[0x98];
- EMC(0x4B0) = _cfg[0x96];
- EMC(0x4C0) = _cfg[0x99];
- if (_cfg[0xFA] << 31)
- {
- EMC(0x2EC) = _cfg[0xF7];
- sleep(_cfg[0xF9]);
- EMC(0x2EC) = _cfg[0xF7] ^ 3;
- if (!(_cfg[0xB2] & 2))
- {
- EMC(0x2EC) = _cfg[0xF8];
- sleep(_cfg[0xF9]);
- EMC(0x2EC) = _cfg[0xF8] ^ 3;
- }
- }
- }
- PMC(0x1D0) = _cfg_100[0xF];
- if (_cfg[0] == 1 || _cfg[0] == 2 || _cfg[0] == 3)
- {
- EMC(0x2E0) = _cfg[0xF3];
- EMC(0x2E4) = _cfg[0xF4];
- EMC(0x2E8) = _cfg[0xF5];
- }
- if (_cfg[0x14])
- *(vu32 *)_cfg[0x14] = _cfg[0x15];
- EMC(0x28) = 1;
- if (_cfg_100[8])
- EMC(0xD4) = ((1 << _cfg_100[8] << 8) - 0xFD) | (_cfg[0x38] << 30);
- EMC(0x20) = _cfg[0xB2] | 0x80000000;
- EMC(0x3E0) = _cfg[0xAD];
- EMC(0x5F4) = _cfg[0xA8];
- EMC(0xC) = _cfg[0xA3];
- EMC(0x310) = _cfg[0xB4];
- EMC(0x314) = _cfg[0xB5];
- EMC(0x3D8) = _cfg[0xB3];
- EMC(0x100) = _cfg[0x8A] | 2;
- EMC(0x28) = 1;
- EMC(0x558) = _cfg[0xA6];
- EMC(0x4D8) = _cfg[0xA7];
- SYSREG(AHB_ARBITRATION_XBAR_CTRL) = SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF | (*((u16 *)_cfg + 0x15C) << 16);
- MC(0x650) = _cfg[0x18A];
- MC(0x678) = _cfg[0x18B];
- MC(0x9AC) = _cfg[0x1D9];
- MC(MC_EMEM_CFG_ACCESS_CTRL) = 1; //Disable write access to a bunch of MC registers.
-}
-
-void sdram_init()
-{
- u32 sdram_id = _get_sdram_id();
- const u32 *cfg = _dram_cfgs[sdram_id]; //TODO: sdram_id should be in [0,4].
-
- i2c_send_byte(I2C_5, 0x3C, 0x22, 0x05);
- i2c_send_byte(I2C_5, 0x3C, 0x17, 40); //40 = (1000 * 1100 - 600000) / 12500
-
- PMC(APBDEV_PMC_VDDP_SEL) = cfg[0x10C];
- sleep(cfg[0x10D]);
- PMC(APBDEV_PMC_DDR_PWR) = PMC(0xE8);
- PMC(APBDEV_PMC_NO_IOPOWER) = cfg[0x114];
- PMC(APBDEV_PMC_REG_SHORT) = cfg[0x113];
- PMC(APBDEV_PMC_DDR_CNTRL) = cfg[0x116];
-
- if (cfg[8])
- *(vu32 *)cfg[8] = cfg[9];
-
- _sdram_config(cfg);
-}
diff --git a/fusee/fusee-primary/src/hwinit/sdram.h b/fusee/fusee-primary/src/hwinit/sdram.h
deleted file mode 100644
index 19db6da9b..000000000
--- a/fusee/fusee-primary/src/hwinit/sdram.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _SDRAM_H_
-#define _SDRAM_H_
-
-void sdram_init();
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/sdram.inl b/fusee/fusee-primary/src/hwinit/sdram.inl
deleted file mode 100644
index 788dcc8aa..000000000
--- a/fusee/fusee-primary/src/hwinit/sdram.inl
+++ /dev/null
@@ -1,812 +0,0 @@
-static const u8 _dram_cfg_0[1896] = {
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
- 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
- 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
- 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
- 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
- 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
- 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
- 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
- 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
- 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
- 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
- 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
- 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
- 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
- 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
- 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
- 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
- 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
- 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
- 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
- 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
- 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
- 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
- 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
- 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
- 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
- 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00,
- 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
- 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
- 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
- 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
- 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
- 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
- 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
- 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
- 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
- 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
- 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
- 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
- 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
- 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
- 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
- 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static const u8 _dram_cfg_1[1896] = {
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
- 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
- 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
- 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
- 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
- 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
- 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
- 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
- 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
- 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
- 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
- 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
- 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
- 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
- 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
- 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
- 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
- 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
- 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
- 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
- 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
- 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
- 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
- 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
- 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
- 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
- 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00,
- 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
- 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
- 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
- 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
- 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
- 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
- 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
- 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
- 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00,
- 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
- 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
- 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
- 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
- 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
- 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
- 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
- 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static const u8 _dram_cfg_2[1896] = {
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
- 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
- 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
- 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
- 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
- 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
- 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
- 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
- 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
- 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
- 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
- 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
- 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
- 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
- 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
- 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
- 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
- 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
- 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
- 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
- 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
- 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
- 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
- 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
- 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
- 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
- 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00,
- 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
- 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
- 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
- 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
- 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
- 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
- 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
- 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
- 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
- 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
- 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
- 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
- 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
- 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
- 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
- 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static const u8 _dram_cfg_3[1896] = {
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
- 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
- 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
- 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
- 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
- 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
- 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
- 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
- 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
- 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x12, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
- 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
- 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
- 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
- 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
- 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
- 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
- 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
- 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
- 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
- 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
- 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
- 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
- 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
- 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
- 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
- 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
- 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00,
- 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
- 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
- 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
- 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
- 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
- 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
- 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
- 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
- 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
- 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
- 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
- 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
- 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
- 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
- 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
- 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static const u8 _dram_cfg_4[1896] = {
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
- 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
- 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
- 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
- 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
- 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
- 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
- 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
- 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
- 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
- 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
- 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
- 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
- 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
- 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
- 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
- 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
- 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
- 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
- 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
- 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
- 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
- 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
- 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
- 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
- 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
- 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
- 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
- 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00,
- 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
- 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
- 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
- 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
- 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
- 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
- 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
- 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
- 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
- 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
- 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
- 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x0C, 0x00,
- 0x02, 0x03, 0x0C, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
- 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x18, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
- 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
- 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static const u32 *_dram_cfgs[5] = {
- (const u32 *)_dram_cfg_0,
- (const u32 *)_dram_cfg_1,
- (const u32 *)_dram_cfg_2,
- (const u32 *)_dram_cfg_3,
- (const u32 *)_dram_cfg_4
-};
diff --git a/fusee/fusee-primary/src/hwinit/t210.h b/fusee/fusee-primary/src/hwinit/t210.h
deleted file mode 100644
index 578d6282b..000000000
--- a/fusee/fusee-primary/src/hwinit/t210.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef _T210_H_
-#define _T210_H_
-
-#include "types.h"
-
-#define HOST1X_BASE 0x50000000
-#define DISPLAY_A_BASE 0x54200000
-#define DSI_BASE 0x54300000
-#define VIC_BASE 0x54340000
-#define TSEC_BASE 0x54500000
-#define SOR1_BASE 0x54580000
-#define TMR_BASE 0x60005000
-#define CLOCK_BASE 0x60006000
-#define FLOW_CTLR_BASE 0x60007000
-#define SYSREG_BASE 0x6000C000
-#define SB_BASE (SYSREG_BASE + 0x200)
-#define GPIO_BASE 0x6000D000
-#define GPIO_1_BASE (GPIO_BASE)
-#define GPIO_2_BASE (GPIO_BASE + 0x100)
-#define GPIO_3_BASE (GPIO_BASE + 0x200)
-#define GPIO_6_BASE (GPIO_BASE + 0x500)
-#define EXCP_VEC_BASE 0x6000F000
-#define PINMUX_AUX_BASE 0x70003000
-#define UART_BASE 0x70006000
-#define PMC_BASE 0x7000E400
-#define SYSCTR0_BASE 0x7000F000
-#define FUSE_BASE 0x7000F800
-#define MC_BASE 0x70019000
-#define EMC_BASE 0x7001B000
-#define MIPI_CAL_BASE 0x700E3000
-#define I2S_BASE 0x702D1000
-
-#define _REG(base, off) *(vu32 *)((base) + (off))
-
-#define HOST1X(off) _REG(HOST1X_BASE, off)
-#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off)
-#define DSI(off) _REG(DSI_BASE, off)
-#define VIC(off) _REG(VIC_BASE, off)
-#define TSEC(off) _REG(TSEC_BASE, off)
-#define SOR1(off) _REG(SOR1_BASE, off)
-#define TMR(off) _REG(TMR_BASE, off)
-#define CLOCK(off) _REG(CLOCK_BASE, off)
-#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off)
-#define SYSREG(off) _REG(SYSREG_BASE, off)
-#define SB(off) _REG(SB_BASE, off)
-#define GPIO_1(off) _REG(GPIO_1_BASE, off)
-#define GPIO_2(off) _REG(GPIO_2_BASE, off)
-#define GPIO_3(off) _REG(GPIO_3_BASE, off)
-#define GPIO_6(off) _REG(GPIO_6_BASE, off)
-#define EXCP_VEC(off) _REG(EXCP_VEC_BASE, off)
-#define PINMUX_AUX(off) _REG(PINMUX_AUX_BASE, off)
-#define PMC(off) _REG(PMC_BASE, off)
-#define SYSCTR0(off) _REG(SYSCTR0_BASE, off)
-#define FUSE(off) _REG(FUSE_BASE, off)
-#define MC(off) _REG(MC_BASE, off)
-#define EMC(off) _REG(EMC_BASE, off)
-#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off)
-#define I2S(off) _REG(I2S_BASE, off)
-
-/*! System registers. */
-#define AHB_ARBITRATION_XBAR_CTRL 0xE0
-
-/*! Secure boot registers. */
-#define SB_CSR_0 0x0
-#define SB_AA64_RESET_LOW 0x30
-#define SB_AA64_RESET_HIGH 0x34
-
-/*! SYSCTR0 registers. */
-#define SYSCTR0_CNTFID0 0x20
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/tsec.c b/fusee/fusee-primary/src/hwinit/tsec.c
deleted file mode 100644
index 3b229fc52..000000000
--- a/fusee/fusee-primary/src/hwinit/tsec.c
+++ /dev/null
@@ -1,113 +0,0 @@
-#include
-#include "tsec.h"
-#include "clock.h"
-#include "t210.h"
-
-static int _tsec_dma_wait_idle()
-{
- u32 timeout = TMR(0x10) + 10000000;
-
- while (!(TSEC(0x1118) & 2))
- if (TMR(0x10) > timeout)
- return 0;
-
- return 1;
-}
-
-static int _tsec_dma_pa_to_internal_100(int not_imem, int i_offset, int pa_offset)
-{
- u32 cmd;
-
- if (not_imem)
- cmd = 0x600; // DMA 0x100 bytes
- else
- cmd = 0x10; // dma imem
-
- TSEC(0x1114) = i_offset; // tsec_dmatrfmoffs_r
- TSEC(0x111C) = pa_offset; // tsec_dmatrffboffs_r
- TSEC(0x1118) = cmd; // tsec_dmatrfcmd_r
-
- return _tsec_dma_wait_idle();
-}
-
-int tsec_query(u32 carveout, u8 *dst, u32 rev)
-{
- int res = 0;
-
- //Enable clocks.
- clock_enable_host1x();
- clock_enable_tsec();
- clock_enable_sor_safe();
- clock_enable_sor0();
- clock_enable_sor1();
- clock_enable_kfuse();
-
- //Configure Falcon.
- TSEC(0x110C) = 0; // tsec_dmactl_r
- TSEC(0x1010) = 0xFFF2; // tsec_irqmset_r
- TSEC(0x101C) = 0xFFF0; // tsec_irqdest_r
- TSEC(0x1048) = 3; // tsec_itfen_r
- if (!_tsec_dma_wait_idle())
- {
- res = -1;
- goto out;
- }
-
- //Load firmware.
- TSEC(0x1110) = carveout >> 8;// tsec_dmatrfbase_r
- for (u32 addr = 0; addr < 0xF00; addr += 0x100)
- if (!_tsec_dma_pa_to_internal_100(0, addr, addr))
- {
- res = -2;
- goto out;
- }
-
- //Execute firmware.
- HOST1X(0x3300) = 0x34C2E1DA;
- TSEC(0x1044) = 0;
- TSEC(0x1040) = rev;
- TSEC(0x1104) = 0; // tsec_bootvec_r
- TSEC(0x1100) = 2; // tsec_cpuctl_r
- if (!_tsec_dma_wait_idle())
- {
- res = -3;
- goto out;
- }
- u32 timeout = TMR(0x10) + 2000000;
- while (!TSEC(0x1044))
- if (TMR(0x10) > timeout)
- {
- res = -4;
- goto out;
- }
- if (TSEC(0x1044) != 0xB0B0B0B0)
- {
- res = -5;
- goto out;
- }
-
- //Fetch result.
- HOST1X(0x3300) = 0;
- u32 buf[4];
- buf[0] = SOR1(0x1E8);
- buf[1] = SOR1(0x21C);
- buf[2] = SOR1(0x208);
- buf[3] = SOR1(0x20C);
- SOR1(0x1E8) = 0;
- SOR1(0x21C) = 0;
- SOR1(0x208) = 0;
- SOR1(0x20C) = 0;
- memcpy(dst, &buf, 0x10);
-
-out:;
-
- //Disable clocks.
- clock_disable_kfuse();
- clock_disable_sor1();
- clock_disable_sor0();
- clock_disable_sor_safe();
- clock_disable_tsec();
- clock_disable_host1x();
-
- return res;
-}
diff --git a/fusee/fusee-primary/src/hwinit/tsec.h b/fusee/fusee-primary/src/hwinit/tsec.h
deleted file mode 100644
index 03fb503d2..000000000
--- a/fusee/fusee-primary/src/hwinit/tsec.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _TSEC_H_
-#define _TSEC_H_
-
-#include "types.h"
-
-int tsec_query(u32 carveout, u8 *dst, u32 rev);
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/types.h b/fusee/fusee-primary/src/hwinit/types.h
deleted file mode 100644
index dff2978da..000000000
--- a/fusee/fusee-primary/src/hwinit/types.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _TYPES_H_
-#define _TYPES_H_
-
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef volatile unsigned int vu32;
-typedef unsigned long long int u64;
-typedef volatile unsigned long long int vu64;
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/uart.c b/fusee/fusee-primary/src/hwinit/uart.c
deleted file mode 100644
index b9b35aa8c..000000000
--- a/fusee/fusee-primary/src/hwinit/uart.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "uart.h"
-#include "t210.h"
-#include "util.h"
-
-/* UART A, B, C, D and E. */
-static const u32 uart_baseoff[5] = { 0, 0x40, 0x200, 0x300, 0x400 };
-
-void uart_init(u32 idx, u32 baud)
-{
- volatile uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
-
- //Set baud rate.
- u32 rate = (8 * baud + 408000000) / (16 * baud);
- uart->UART_LCR = 0x80; //Enable DLAB.
- uart->UART_THR_DLAB = (u8)rate; //Divisor latch LSB.
- uart->UART_IER_DLAB = (u8)(rate >> 8); //Divisor latch MSB.
- uart->UART_LCR = 0; //Diable DLAB.
-
- //Setup UART in fifo mode.
- uart->UART_IER_DLAB = 0;
- uart->UART_IIR_FCR = 7; //Enable and clear TX and RX FIFOs.
- volatile u32 tmp = uart->UART_LSR;
- sleep(3 * ((baud + 999999) / baud));
- uart->UART_LCR = 3; //Set word length 8.
- uart->UART_MCR = 0;
- uart->UART_MSR = 0;
- uart->UART_IRDA_CSR = 0;
- uart->UART_RX_FIFO_CFG = 1;
- uart->UART_MIE = 0;
- uart->UART_ASR = 0;
-}
-
-void uart_wait_idle(u32 idx, u32 which)
-{
- volatile uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
- while (!(uart->UART_VENDOR_STATUS & which))
- ;
-}
-
-void uart_send(u32 idx, u8 *buf, u32 len)
-{
- volatile uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
-
- for (u32 i = 0; i != len; i++)
- {
- while (uart->UART_LSR & UART_TX_FIFO_FULL)
- ;
- uart->UART_THR_DLAB = buf[i];
- };
-}
-
-void uart_recv(u32 idx, u8 *buf, u32 len)
-{
- volatile uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]);
-
- for (u32 i = 0; i != len; i++)
- {
- while (uart->UART_LSR & UART_RX_FIFO_EMPTY)
- ;
- buf[i] = uart->UART_THR_DLAB;
- };
-}
diff --git a/fusee/fusee-primary/src/hwinit/uart.h b/fusee/fusee-primary/src/hwinit/uart.h
deleted file mode 100644
index ac8222215..000000000
--- a/fusee/fusee-primary/src/hwinit/uart.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef _UART_H_
-#define _UART_H_
-
-#include "types.h"
-
-#define UART_A 0
-#define UART_B 1
-#define UART_C 2
-//TODO: define clock inits for those.
-/*#define UART_D 3
-#define UART_E 4*/
-
-#define BAUD_115200 115200
-
-#define UART_TX_IDLE 0x00000001
-#define UART_RX_IDLE 0x00000002
-#define UART_TX_FIFO_FULL 0x100
-#define UART_RX_FIFO_EMPTY 0x200
-
-typedef struct _uart_t
-{
- /* 0x00 */ u32 UART_THR_DLAB;
- /* 0x04 */ u32 UART_IER_DLAB;
- /* 0x08 */ u32 UART_IIR_FCR;
- /* 0x0C */ u32 UART_LCR;
- /* 0x10 */ u32 UART_MCR;
- /* 0x14 */ u32 UART_LSR;
- /* 0x18 */ u32 UART_MSR;
- /* 0x1C */ u32 UART_SPR;
- /* 0x20 */ u32 UART_IRDA_CSR;
- /* 0x24 */ u32 UART_RX_FIFO_CFG;
- /* 0x28 */ u32 UART_MIE;
- /* 0x2C */ u32 UART_VENDOR_STATUS;
- /* 0x30 */ u8 _pad_30[0x0C];
- /* 0x3C */ u32 UART_ASR;
-} uart_t;
-
-void uart_init(u32 idx, u32 baud);
-void uart_wait_idle(u32 idx, u32 which);
-void uart_send(u32 idx, u8 *buf, u32 len);
-void uart_recv(u32 idx, u8 *buf, u32 len);
-
-#endif
diff --git a/fusee/fusee-primary/src/hwinit/util.c b/fusee/fusee-primary/src/hwinit/util.c
deleted file mode 100644
index 780b31177..000000000
--- a/fusee/fusee-primary/src/hwinit/util.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "util.h"
-#include "t210.h"
-
-void sleep(u32 ticks)
-{
- u32 start = TMR(0x10);
- while (TMR(0x10) - start <= ticks)
- ;
-}
-
-void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops)
-{
- for(u32 i = 0; i < num_ops; i++)
- base[ops[i].off] = ops[i].val;
-}
-
diff --git a/fusee/fusee-primary/src/hwinit/util.h b/fusee/fusee-primary/src/hwinit/util.h
deleted file mode 100644
index 13bc8024f..000000000
--- a/fusee/fusee-primary/src/hwinit/util.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _UTIL_H_
-#define _UTIL_H_
-
-#include "types.h"
-#pragma GCC diagnostic ignored "-Wparentheses"
-#pragma GCC diagnostic ignored "-Wunused-variable"
-
-typedef struct _cfg_op_t
-{
- u32 off;
- u32 val;
-} cfg_op_t;
-
-void sleep(u32 ticks);
-void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
-
-#endif
diff --git a/fusee/fusee-primary/src/i2c.c b/fusee/fusee-primary/src/i2c.c
new file mode 100644
index 000000000..aec946cf2
--- /dev/null
+++ b/fusee/fusee-primary/src/i2c.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "i2c.h"
+#include "utils.h"
+#include "timers.h"
+
+/* Prototypes for internal commands. */
+volatile tegra_i2c_t *i2c_get_registers_from_id(unsigned int id);
+void i2c_load_config(volatile tegra_i2c_t *regs);
+
+bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
+bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size);
+
+bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size);
+bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size);
+
+/* Initialize I2C based on registers. */
+void i2c_init(unsigned int id) {
+ volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
+
+ /* Setup divisor, and clear the bus. */
+ regs->I2C_I2C_CLK_DIVISOR_REGISTER_0 = 0x50001;
+ regs->I2C_I2C_BUS_CLEAR_CONFIG_0 = 0x90003;
+
+ /* Load hardware configuration. */
+ i2c_load_config(regs);
+
+ /* Wait a while until BUS_CLEAR_DONE is set. */
+ for (unsigned int i = 0; i < 10; i++) {
+ udelay(20000);
+ if (regs->I2C_INTERRUPT_STATUS_REGISTER_0 & 0x800) {
+ break;
+ }
+ }
+
+ /* Read the BUS_CLEAR_STATUS. Result doesn't matter. */
+ regs->I2C_I2C_BUS_CLEAR_STATUS_0;
+
+ /* Read and set the Interrupt Status. */
+ uint32_t int_status = regs->I2C_INTERRUPT_STATUS_REGISTER_0;
+ regs->I2C_INTERRUPT_STATUS_REGISTER_0 = int_status;
+}
+
+/* Sets a bit in a PMIC register over I2C during CPU shutdown. */
+void i2c_send_pmic_cpu_shutdown_cmd(void) {
+ uint32_t val = 0;
+ /* PMIC == Device 4:3C. */
+ i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
+ val |= 4;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
+}
+
+/* Queries the value of TI charger bit over I2C. */
+bool i2c_query_ti_charger_bit_7(void) {
+ uint32_t val = 0;
+ /* TI Charger = Device 0:6B. */
+ i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
+ return (val & 0x80) != 0;
+}
+
+/* Clears TI charger bit over I2C. */
+void i2c_clear_ti_charger_bit_7(void) {
+ uint32_t val = 0;
+ /* TI Charger = Device 0:6B. */
+ i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
+ val &= 0x7F;
+ i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
+}
+
+/* Sets TI charger bit over I2C. */
+void i2c_set_ti_charger_bit_7(void) {
+ uint32_t val = 0;
+ /* TI Charger = Device 0:6B. */
+ i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
+ val |= 0x80;
+ i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
+}
+
+/* Get registers pointer based on I2C ID. */
+volatile tegra_i2c_t *i2c_get_registers_from_id(unsigned int id) {
+ switch (id) {
+ case I2C_1:
+ return I2C1_REGS;
+ case I2C_2:
+ return I2C2_REGS;
+ case I2C_3:
+ return I2C3_REGS;
+ case I2C_4:
+ return I2C4_REGS;
+ case I2C_5:
+ return I2C5_REGS;
+ case I2C_6:
+ return I2C6_REGS;
+ default:
+ generic_panic();
+ }
+ return NULL;
+}
+
+/* Load hardware config for I2C4. */
+void i2c_load_config(volatile tegra_i2c_t *regs) {
+ /* Set MSTR_CONFIG_LOAD, TIMEOUT_CONFIG_LOAD, undocumented bit. */
+ regs->I2C_I2C_CONFIG_LOAD_0 = 0x25;
+
+ /* Wait a bit for master config to be loaded. */
+ for (unsigned int i = 0; i < 20; i++) {
+ udelay(1);
+ if (!(regs->I2C_I2C_CONFIG_LOAD_0 & 1)) {
+ break;
+ }
+ }
+}
+
+/* Reads a register from a device over I2C, writes result to output. */
+bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
+ volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
+ uint32_t val = r;
+
+ /* Write single byte register ID to device. */
+ if (!i2c_write(regs, device, &val, 1)) {
+ return false;
+ }
+ /* Limit output size to 32-bits. */
+ if (dst_size > 4) {
+ return false;
+ }
+
+ return i2c_read(regs, device, dst, dst_size);
+}
+
+/* Writes a value to a register over I2C. */
+bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size) {
+ uint32_t val = r;
+ if (src_size == 0) {
+ return true;
+ } else if (src_size <= 3) {
+ memcpy(((uint8_t *)&val) + 1, src, src_size);
+ return i2c_write(i2c_get_registers_from_id(id), device, &val, src_size + 1);
+ } else {
+ return false;
+ }
+}
+
+/* Writes bytes to device over I2C. */
+bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size) {
+ if (src_size > 4) {
+ return false;
+ } else if (src_size == 0) {
+ return true;
+ }
+
+ /* Set device for 7-bit write mode. */
+ regs->I2C_I2C_CMD_ADDR0_0 = device << 1;
+
+ /* Load in data to write. */
+ regs->I2C_I2C_CMD_DATA1_0 = read32le(src, 0);
+
+ /* Set config with LENGTH = src_size, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
+ regs->I2C_I2C_CNFG_0 = ((src_size << 1) - 2) | 0x2800;
+
+ i2c_load_config(regs);
+
+ /* Config |= SEND; */
+ regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
+
+ while (regs->I2C_I2C_STATUS_0 & 0x100) {
+ /* Wait until not busy. */
+ }
+
+ /* Return CMD1_STAT == SL1_XFER_SUCCESSFUL. */
+ return (regs->I2C_I2C_STATUS_0 & 0xF) == 0;
+}
+
+/* Reads bytes from device over I2C. */
+bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size) {
+ if (dst_size > 4) {
+ return false;
+ } else if (dst_size == 0) {
+ return true;
+ }
+
+ /* Set device for 7-bit read mode. */
+ regs->I2C_I2C_CMD_ADDR0_0 = (device << 1) | 1;
+
+ /* Set config with LENGTH = dst_size, NEW_MASTER_FSM, DEBOUNCE_CNT = 4T. */
+ regs->I2C_I2C_CNFG_0 = ((dst_size << 1) - 2) | 0x2840;
+
+ i2c_load_config(regs);
+
+ /* Config |= SEND; */
+ regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
+
+ while (regs->I2C_I2C_STATUS_0 & 0x100) {
+ /* Wait until not busy. */
+ }
+
+ /* Ensure success. */
+ if ((regs->I2C_I2C_STATUS_0 & 0xF) != 0) {
+ return false;
+ }
+
+ uint32_t val = regs->I2C_I2C_CMD_DATA1_0;
+ memcpy(dst, &val, dst_size);
+ return true;
+}
diff --git a/fusee/fusee-primary/src/i2c.h b/fusee/fusee-primary/src/i2c.h
new file mode 100644
index 000000000..9399b0024
--- /dev/null
+++ b/fusee/fusee-primary/src/i2c.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_I2C_H
+#define FUSEE_I2C_H
+
+#include
+#include
+#include
+
+#define I2C1234_BASE 0x7000C000
+#define I2C56_BASE 0x7000D000
+
+#define I2C_1 0
+#define I2C_2 1
+#define I2C_3 2
+#define I2C_4 3
+#define I2C_5 4
+#define I2C_6 5
+
+#define MAX77621_CPU_I2C_ADDR 0x1B
+#define MAX77621_GPU_I2C_ADDR 0x1C
+#define MAX17050_I2C_ADDR 0x36
+#define MAX77620_PWR_I2C_ADDR 0x3C
+#define MAX77620_RTC_I2C_ADDR 0x68
+#define BQ24193_I2C_ADDR 0x6B
+
+typedef struct {
+ uint32_t I2C_I2C_CNFG_0;
+ uint32_t I2C_I2C_CMD_ADDR0_0;
+ uint32_t I2C_I2C_CMD_ADDR1_0;
+ uint32_t I2C_I2C_CMD_DATA1_0;
+ uint32_t I2C_I2C_CMD_DATA2_0;
+ uint32_t _0x14;
+ uint32_t _0x18;
+ uint32_t I2C_I2C_STATUS_0;
+ uint32_t I2C_I2C_SL_CNFG_0;
+ uint32_t I2C_I2C_SL_RCVD_0;
+ uint32_t I2C_I2C_SL_STATUS_0;
+ uint32_t I2C_I2C_SL_ADDR1_0;
+ uint32_t I2C_I2C_SL_ADDR2_0;
+ uint32_t I2C_I2C_TLOW_SEXT_0;
+ uint32_t _0x38;
+ uint32_t I2C_I2C_SL_DELAY_COUNT_0;
+ uint32_t I2C_I2C_SL_INT_MASK_0;
+ uint32_t I2C_I2C_SL_INT_SOURCE_0;
+ uint32_t I2C_I2C_SL_INT_SET_0;
+ uint32_t _0x4C;
+ uint32_t I2C_I2C_TX_PACKET_FIFO_0;
+ uint32_t I2C_I2C_RX_FIFO_0;
+ uint32_t I2C_PACKET_TRANSFER_STATUS_0;
+ uint32_t I2C_FIFO_CONTROL_0;
+ uint32_t I2C_FIFO_STATUS_0;
+ uint32_t I2C_INTERRUPT_MASK_REGISTER_0;
+ uint32_t I2C_INTERRUPT_STATUS_REGISTER_0;
+ uint32_t I2C_I2C_CLK_DIVISOR_REGISTER_0;
+ uint32_t I2C_I2C_INTERRUPT_SOURCE_REGISTER_0;
+ uint32_t I2C_I2C_INTERRUPT_SET_REGISTER_0;
+ uint32_t I2C_I2C_SLV_TX_PACKET_FIFO_0;
+ uint32_t I2C_I2C_SLV_RX_FIFO_0;
+ uint32_t I2C_I2C_SLV_PACKET_STATUS_0;
+ uint32_t I2C_I2C_BUS_CLEAR_CONFIG_0;
+ uint32_t I2C_I2C_BUS_CLEAR_STATUS_0;
+ uint32_t I2C_I2C_CONFIG_LOAD_0;
+ uint32_t _0x90;
+ uint32_t I2C_I2C_INTERFACE_TIMING_0_0;
+ uint32_t I2C_I2C_INTERFACE_TIMING_1_0;
+ uint32_t I2C_I2C_HS_INTERFACE_TIMING_0_0;
+ uint32_t I2C_I2C_HS_INTERFACE_TIMING_1_0;
+} tegra_i2c_t;
+
+#define I2C1_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x000))
+#define I2C2_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x400))
+#define I2C3_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x500))
+#define I2C4_REGS ((volatile tegra_i2c_t *)(I2C1234_BASE + 0x700))
+#define I2C5_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x000))
+#define I2C6_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x100))
+
+void i2c_init(unsigned int id);
+bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
+bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size);
+
+void i2c_send_pmic_cpu_shutdown_cmd(void);
+bool i2c_query_ti_charger_bit_7(void);
+void i2c_clear_ti_charger_bit_7(void);
+void i2c_set_ti_charger_bit_7(void);
+
+#endif
diff --git a/fusee/fusee-primary/src/init.c b/fusee/fusee-primary/src/init.c
index a121310e4..c061fc00c 100644
--- a/fusee/fusee-primary/src/init.c
+++ b/fusee/fusee-primary/src/init.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include
diff --git a/fusee/fusee-primary/src/lib/driver_utils.h b/fusee/fusee-primary/src/lib/driver_utils.h
deleted file mode 100644
index b33df1686..000000000
--- a/fusee/fusee-primary/src/lib/driver_utils.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef FUSEE_DRIVER_UTILS_H
-#define FUSEE_DRIVER_UTILS_H
-
-#include "vsprintf.h"
-#include "printk.h"
-
-#endif
diff --git a/fusee/fusee-primary/src/lib/log.c b/fusee/fusee-primary/src/lib/log.c
new file mode 100644
index 000000000..37006b166
--- /dev/null
+++ b/fusee/fusee-primary/src/lib/log.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "log.h"
+
+#include "../display/video_fb.h"
+#include "vsprintf.h"
+
+/* default log level for screen output */
+ScreenLogLevel g_screen_log_level = SCREEN_LOG_LEVEL_NONE;
+
+void log_set_log_level(ScreenLogLevel log_level) {
+ g_screen_log_level = log_level;
+}
+
+ScreenLogLevel log_get_log_level() {
+ return g_screen_log_level;
+}
+
+void log_to_uart(const char *message) {
+ /* TODO: add UART logging */
+}
+
+static void print_to_screen(ScreenLogLevel screen_log_level, char *message) {
+ /* don't print to screen if below log level */
+ if(screen_log_level > g_screen_log_level) return;
+
+ video_puts(message);
+}
+
+/**
+ * vprintk - logs a message and prints it to screen based on its screen_log_level
+ *
+ * If the level is below g_screen_log_level it will not be shown but logged to UART
+ * This text will not be colored or prefixed
+ * UART is TODO
+ */
+void vprint(ScreenLogLevel screen_log_level, const char *fmt, va_list args)
+{
+ char buf[PRINT_MESSAGE_MAX_LENGTH];
+ vsnprintf(buf, PRINT_MESSAGE_MAX_LENGTH, fmt, args);
+
+ /* we don't need that flag here, but if it gets used, strip it so we print correctly */
+ screen_log_level &= ~SCREEN_LOG_LEVEL_NO_PREFIX;
+
+ /* log to UART */
+ log_to_uart(buf);
+
+ print_to_screen(screen_log_level, buf);
+}
+
+static void add_prefix(ScreenLogLevel screen_log_level, const char *fmt, char *buf) {
+ char typebuf[] = "[%s] %s";
+
+ /* apply prefix and append message format */
+ /* TODO: add coloring to the output */
+ switch(screen_log_level)
+ {
+ case SCREEN_LOG_LEVEL_ERROR:
+ snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "ERROR", fmt);
+ break;
+ case SCREEN_LOG_LEVEL_WARNING:
+ snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "WARNING", fmt);
+ break;
+ case SCREEN_LOG_LEVEL_MANDATORY:
+ snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, "%s", fmt);
+ break;
+ case SCREEN_LOG_LEVEL_INFO:
+ snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "INFO", fmt);
+ break;
+ case SCREEN_LOG_LEVEL_DEBUG:
+ snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "DEBUG", fmt);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * print - logs a message and prints it to screen based on its screen_log_level
+ *
+ * If the level is below g_screen_log_level it will not be shown but logged to UART
+ * Use SCREEN_LOG_LEVEL_NO_PREFIX if you don't want a prefix to be added
+ * UART is TODO
+ */
+void print(ScreenLogLevel screen_log_level, const char * fmt, ...)
+{
+ char buf[PRINT_MESSAGE_MAX_LENGTH] = {};
+ char message[PRINT_MESSAGE_MAX_LENGTH] = {};
+
+ /* TODO: make splash disappear if level > MANDATORY */
+
+ /* make prefix free messages with log_level possible */
+ if(screen_log_level & SCREEN_LOG_LEVEL_NO_PREFIX) {
+ /* remove the NO_PREFIX flag so the enum can be recognized later on */
+ screen_log_level &= ~SCREEN_LOG_LEVEL_NO_PREFIX;
+
+ snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, "%s", fmt);
+ }
+ else {
+ add_prefix(screen_log_level, fmt, buf);
+ }
+
+ /* input arguments */
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(message, PRINT_MESSAGE_MAX_LENGTH, buf, args);
+ va_end(args);
+
+ /* log to UART */
+ log_to_uart(message);
+
+ print_to_screen(screen_log_level, message);
+}
\ No newline at end of file
diff --git a/fusee/fusee-primary/src/lib/log.h b/fusee/fusee-primary/src/lib/log.h
new file mode 100644
index 000000000..32703a318
--- /dev/null
+++ b/fusee/fusee-primary/src/lib/log.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_LOG_H
+#define FUSEE_LOG_H
+
+#define PRINT_MESSAGE_MAX_LENGTH 512
+
+#include
+
+typedef enum {
+ SCREEN_LOG_LEVEL_NONE = 0,
+ SCREEN_LOG_LEVEL_ERROR = 1,
+ SCREEN_LOG_LEVEL_WARNING = 2,
+ SCREEN_LOG_LEVEL_MANDATORY = 3, /* no log prefix */
+ SCREEN_LOG_LEVEL_INFO = 4,
+ SCREEN_LOG_LEVEL_DEBUG = 5,
+
+ SCREEN_LOG_LEVEL_NO_PREFIX = 0x100 /* OR this to your LOG_LEVEL to prevent prefix creation */
+} ScreenLogLevel;
+
+extern ScreenLogLevel g_screen_log_level;
+
+void log_set_log_level(ScreenLogLevel screen_log_level);
+ScreenLogLevel log_get_log_level();
+void log_to_uart(const char *message);
+void vprint(ScreenLogLevel screen_log_level, const char *fmt, va_list args);
+void print(ScreenLogLevel screen_log_level, const char* fmt, ...);
+
+#endif
\ No newline at end of file
diff --git a/fusee/fusee-primary/src/lib/lz.c b/fusee/fusee-primary/src/lib/lz.c
new file mode 100644
index 000000000..e62e02d15
--- /dev/null
+++ b/fusee/fusee-primary/src/lib/lz.c
@@ -0,0 +1,377 @@
+/*************************************************************************
+* Name: lz.c
+* Author: Marcus Geelnard
+* Description: LZ77 coder/decoder implementation.
+* Reentrant: Yes
+*
+* The LZ77 compression scheme is a substitutional compression scheme
+* proposed by Abraham Lempel and Jakob Ziv in 1977. It is very simple in
+* its design, and uses no fancy bit level compression.
+*
+* This is my first attempt at an implementation of a LZ77 code/decoder.
+*
+* The principle of the LZ77 compression algorithm is to store repeated
+* occurrences of strings as references to previous occurrences of the same
+* string. The point is that the reference consumes less space than the
+* string itself, provided that the string is long enough (in this
+* implementation, the string has to be at least 4 bytes long, since the
+* minimum coded reference is 3 bytes long). Also note that the term
+* "string" refers to any kind of byte sequence (it does not have to be
+* an ASCII string, for instance).
+*
+* The coder uses a brute force approach to finding string matches in the
+* history buffer (or "sliding window", if you wish), which is very, very
+* slow. I recon the complexity is somewhere between O(n^2) and O(n^3),
+* depending on the input data.
+*
+* There is also a faster implementation that uses a large working buffer
+* in which a "jump table" is stored, which is used to quickly find
+* possible string matches (see the source code for LZ_CompressFast() for
+* more information). The faster method is an order of magnitude faster,
+* but still quite slow compared to other compression methods.
+*
+* The upside is that decompression is very fast, and the compression ratio
+* is often very good.
+*
+* The reference to a string is coded as a (length,offset) pair, where the
+* length indicates the length of the string, and the offset gives the
+* offset from the current data position. To distinguish between string
+* references and literal strings (uncompressed bytes), a string reference
+* is preceded by a marker byte, which is chosen as the least common byte
+* symbol in the input data stream (this marker byte is stored in the
+* output stream as the first byte).
+*
+* Occurrences of the marker byte in the stream are encoded as the marker
+* byte followed by a zero byte, which means that occurrences of the marker
+* byte have to be coded with two bytes.
+*
+* The lengths and offsets are coded in a variable length fashion, allowing
+* values of any magnitude (up to 4294967295 in this implementation).
+*
+* With this compression scheme, the worst case compression result is
+* (257/256)*insize + 1.
+*
+*-------------------------------------------------------------------------
+* Copyright (c) 2003-2006 Marcus Geelnard
+*
+* This software is provided 'as-is', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would
+* be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not
+* be misrepresented as being the original software.
+*
+* 3. This notice may not be removed or altered from any source
+* distribution.
+*
+* Marcus Geelnard
+* marcus.geelnard at home.se
+*************************************************************************/
+
+
+/*************************************************************************
+* Constants used for LZ77 coding
+*************************************************************************/
+
+/* Maximum offset (can be any size < 2^31). Lower values give faster
+ compression, while higher values gives better compression. The default
+ value of 100000 is quite high. Experiment to see what works best for
+ you. */
+#define LZ_MAX_OFFSET 100000
+
+
+
+/*************************************************************************
+* INTERNAL FUNCTIONS *
+*************************************************************************/
+
+
+/*************************************************************************
+* _LZ_StringCompare() - Return maximum length string match.
+*************************************************************************/
+
+static unsigned int _LZ_StringCompare( const unsigned char * str1,
+ const unsigned char * str2, unsigned int minlen, unsigned int maxlen )
+{
+ unsigned int len;
+
+ for( len = minlen; (len < maxlen) && (str1[len] == str2[len]); ++ len );
+
+ return len;
+}
+
+
+/*************************************************************************
+* _LZ_WriteVarSize() - Write unsigned integer with variable number of
+* bytes depending on value.
+*************************************************************************/
+
+static int _LZ_WriteVarSize( unsigned int x, unsigned char * buf )
+{
+ unsigned int y;
+ int num_bytes, i, b;
+
+ /* Determine number of bytes needed to store the number x */
+ y = x >> 3;
+ for( num_bytes = 5; num_bytes >= 2; -- num_bytes )
+ {
+ if( y & 0xfe000000 ) break;
+ y <<= 7;
+ }
+
+ /* Write all bytes, seven bits in each, with 8:th bit set for all */
+ /* but the last byte. */
+ for( i = num_bytes-1; i >= 0; -- i )
+ {
+ b = (x >> (i*7)) & 0x0000007f;
+ if( i > 0 )
+ {
+ b |= 0x00000080;
+ }
+ *buf ++ = (unsigned char) b;
+ }
+
+ /* Return number of bytes written */
+ return num_bytes;
+}
+
+
+/*************************************************************************
+* _LZ_ReadVarSize() - Read unsigned integer with variable number of
+* bytes depending on value.
+*************************************************************************/
+
+static int _LZ_ReadVarSize( unsigned int * x, const unsigned char * buf )
+{
+ unsigned int y, b, num_bytes;
+
+ /* Read complete value (stop when byte contains zero in 8:th bit) */
+ y = 0;
+ num_bytes = 0;
+ do
+ {
+ b = (unsigned int) (*buf ++);
+ y = (y << 7) | (b & 0x0000007f);
+ ++ num_bytes;
+ }
+ while( b & 0x00000080 );
+
+ /* Store value in x */
+ *x = y;
+
+ /* Return number of bytes read */
+ return num_bytes;
+}
+
+
+
+/*************************************************************************
+* PUBLIC FUNCTIONS *
+*************************************************************************/
+
+
+/*************************************************************************
+* LZ_Compress() - Compress a block of data using an LZ77 coder.
+* in - Input (uncompressed) buffer.
+* out - Output (compressed) buffer. This buffer must be 0.4% larger
+* than the input buffer, plus one byte.
+* insize - Number of input bytes.
+* The function returns the size of the compressed data.
+*************************************************************************/
+
+int LZ_Compress( const unsigned char *in, unsigned char *out, unsigned int insize )
+{
+ unsigned char marker, symbol;
+ unsigned int inpos, outpos, bytesleft, i;
+ unsigned int maxoffset, offset, bestoffset;
+ unsigned int maxlength, length, bestlength;
+ unsigned int histogram[ 256 ];
+ const unsigned char *ptr1, *ptr2;
+
+ /* Do we have anything to compress? */
+ if( insize < 1 )
+ {
+ return 0;
+ }
+
+ /* Create histogram */
+ for( i = 0; i < 256; ++ i )
+ {
+ histogram[ i ] = 0;
+ }
+ for( i = 0; i < insize; ++ i )
+ {
+ ++ histogram[ in[ i ] ];
+ }
+
+ /* Find the least common byte, and use it as the marker symbol */
+ marker = 0;
+ for( i = 1; i < 256; ++ i )
+ {
+ if( histogram[ i ] < histogram[ marker ] )
+ {
+ marker = (unsigned char) i;
+ }
+ }
+
+ /* Remember the marker symbol for the decoder */
+ out[ 0 ] = marker;
+
+ /* Start of compression */
+ inpos = 0;
+ outpos = 1;
+
+ /* Main compression loop */
+ bytesleft = insize;
+ do
+ {
+ /* Determine most distant position */
+ if( inpos > LZ_MAX_OFFSET ) maxoffset = LZ_MAX_OFFSET;
+ else maxoffset = inpos;
+
+ /* Get pointer to current position */
+ ptr1 = &in[ inpos ];
+
+ /* Search history window for maximum length string match */
+ bestlength = 3;
+ bestoffset = 0;
+ for( offset = 3; offset <= maxoffset; ++ offset )
+ {
+ /* Get pointer to candidate string */
+ ptr2 = &ptr1[ -(int)offset ];
+
+ /* Quickly determine if this is a candidate (for speed) */
+ if( (ptr1[ 0 ] == ptr2[ 0 ]) &&
+ (ptr1[ bestlength ] == ptr2[ bestlength ]) )
+ {
+ /* Determine maximum length for this offset */
+ maxlength = (bytesleft < offset ? bytesleft : offset);
+
+ /* Count maximum length match at this offset */
+ length = _LZ_StringCompare( ptr1, ptr2, 0, maxlength );
+
+ /* Better match than any previous match? */
+ if( length > bestlength )
+ {
+ bestlength = length;
+ bestoffset = offset;
+ }
+ }
+ }
+
+ /* Was there a good enough match? */
+ if( (bestlength >= 8) ||
+ ((bestlength == 4) && (bestoffset <= 0x0000007f)) ||
+ ((bestlength == 5) && (bestoffset <= 0x00003fff)) ||
+ ((bestlength == 6) && (bestoffset <= 0x001fffff)) ||
+ ((bestlength == 7) && (bestoffset <= 0x0fffffff)) )
+ {
+ out[ outpos ++ ] = (unsigned char) marker;
+ outpos += _LZ_WriteVarSize( bestlength, &out[ outpos ] );
+ outpos += _LZ_WriteVarSize( bestoffset, &out[ outpos ] );
+ inpos += bestlength;
+ bytesleft -= bestlength;
+ }
+ else
+ {
+ /* Output single byte (or two bytes if marker byte) */
+ symbol = in[ inpos ++ ];
+ out[ outpos ++ ] = symbol;
+ if( symbol == marker )
+ {
+ out[ outpos ++ ] = 0;
+ }
+ -- bytesleft;
+ }
+ }
+ while( bytesleft > 3 );
+
+ /* Dump remaining bytes, if any */
+ while( inpos < insize )
+ {
+ if( in[ inpos ] == marker )
+ {
+ out[ outpos ++ ] = marker;
+ out[ outpos ++ ] = 0;
+ }
+ else
+ {
+ out[ outpos ++ ] = in[ inpos ];
+ }
+ ++ inpos;
+ }
+
+ return outpos;
+}
+
+
+/*************************************************************************
+* LZ_Uncompress() - Uncompress a block of data using an LZ77 decoder.
+* in - Input (compressed) buffer.
+* out - Output (uncompressed) buffer. This buffer must be large
+* enough to hold the uncompressed data.
+* insize - Number of input bytes.
+*************************************************************************/
+
+int LZ_Uncompress( const unsigned char *in, unsigned char *out, unsigned int insize )
+{
+ unsigned char marker, symbol;
+ unsigned int i, inpos, outpos, length, offset;
+
+ /* Do we have anything to uncompress? */
+ if( insize < 1 )
+ {
+ return 0;
+ }
+
+ /* Get marker symbol from input stream */
+ marker = in[ 0 ];
+ inpos = 1;
+
+ /* Main decompression loop */
+ outpos = 0;
+ do
+ {
+ symbol = in[ inpos ++ ];
+ if( symbol == marker )
+ {
+ /* We had a marker byte */
+ if( in[ inpos ] == 0 )
+ {
+ /* It was a single occurrence of the marker byte */
+ out[ outpos ++ ] = marker;
+ ++ inpos;
+ }
+ else
+ {
+ /* Extract true length and offset */
+ inpos += _LZ_ReadVarSize( &length, &in[ inpos ] );
+ inpos += _LZ_ReadVarSize( &offset, &in[ inpos ] );
+
+ /* Copy corresponding data from history window */
+ for( i = 0; i < length; ++ i )
+ {
+ out[ outpos ] = out[ outpos - offset ];
+ ++ outpos;
+ }
+ }
+ }
+ else
+ {
+ /* No marker, plain copy */
+ out[ outpos ++ ] = symbol;
+ }
+ }
+ while( inpos < insize );
+
+ return outpos;
+}
diff --git a/fusee/fusee-primary/src/lib/lz.h b/fusee/fusee-primary/src/lib/lz.h
new file mode 100644
index 000000000..bc40b6c63
--- /dev/null
+++ b/fusee/fusee-primary/src/lib/lz.h
@@ -0,0 +1,51 @@
+/*************************************************************************
+* Name: lz.h
+* Author: Marcus Geelnard
+* Description: LZ77 coder/decoder interface.
+* Reentrant: Yes
+*-------------------------------------------------------------------------
+* Copyright (c) 2003-2006 Marcus Geelnard
+*
+* This software is provided 'as-is', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would
+* be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not
+* be misrepresented as being the original software.
+*
+* 3. This notice may not be removed or altered from any source
+* distribution.
+*
+* Marcus Geelnard
+* marcus.geelnard at home.se
+*************************************************************************/
+
+#ifndef _lz_h_
+#define _lz_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*************************************************************************
+* Function prototypes
+*************************************************************************/
+
+int LZ_Compress(const unsigned char *in, unsigned char *out, unsigned int insize);
+int LZ_Uncompress(const unsigned char *in, unsigned char *out, unsigned int insize);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _lz_h_ */
diff --git a/fusee/fusee-primary/src/lib/printk.c b/fusee/fusee-primary/src/lib/printk.c
deleted file mode 100644
index 33c368dee..000000000
--- a/fusee/fusee-primary/src/lib/printk.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Kernel print functions.
- */
-
-#include "printk.h"
-
-#include "vsprintf.h"
-#include "../display/video_fb.h"
-
-/**
- * Temporary stand-in main printk.
- *
- * TODO: This should print via UART, console framebuffer, and to a ring for
- * consumption by Horizon
- */
-void printk(const char *fmt, ...)
-{
- va_list list;
- va_start(list, fmt);
- vprintk(fmt, list);
- va_end(list);
-}
-
-
-void vprintk(const char *fmt, va_list args)
-{
- char buf[512];
- vsnprintf(buf, sizeof(buf), fmt, args);
- video_puts(buf);
-}
diff --git a/fusee/fusee-primary/src/lib/printk.h b/fusee/fusee-primary/src/lib/printk.h
deleted file mode 100644
index 9b0c3d710..000000000
--- a/fusee/fusee-primary/src/lib/printk.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __PRINTK_H__
-#define __PRINTK_H__
-
-#include
-
-void printk(const char *fmt, ...);
-void vprintk(const char *fmt, va_list args);
-
-#endif
diff --git a/fusee/fusee-primary/src/main.c b/fusee/fusee-primary/src/main.c
index 42b1c7255..8299c70e8 100644
--- a/fusee/fusee-primary/src/main.c
+++ b/fusee/fusee-primary/src/main.c
@@ -1,15 +1,33 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include "utils.h"
#include "exception_handlers.h"
#include "panic.h"
#include "hwinit.h"
-#include "fuse.h"
-#include "se.h"
+#include "di.h"
+#include "timers.h"
#include "fs_utils.h"
#include "stage2.h"
#include "chainloader.h"
#include "sdmmc/sdmmc.h"
#include "lib/fatfs/ff.h"
-#include "lib/printk.h"
+#include "lib/log.h"
+#include "lib/vsprintf.h"
+#include "lib/ini.h"
#include "display/video_fb.h"
extern void (*__program_exit_callback)(int rc);
@@ -17,63 +35,64 @@ extern void (*__program_exit_callback)(int rc);
static void *g_framebuffer;
static char g_bct0_buffer[BCTO_MAX_SIZE];
+#define CONFIG_LOG_LEVEL_KEY "log_level"
+
#define DEFAULT_BCT0_FOR_DEBUG \
"BCT0\n"\
"[stage1]\n"\
-"stage2_path = fusee-secondary.bin\n"\
+"stage2_path = atmosphere/fusee-secondary.bin\n"\
"stage2_addr = 0xF0000000\n"\
"stage2_entrypoint = 0xF0000000\n"
static const char *load_config(void) {
- if (!read_from_file(g_bct0_buffer, BCTO_MAX_SIZE, "BCT.ini")) {
- printk("Failed to read BCT0 from SD!\n");
- printk("[DEBUG] Using default BCT0!\n");
+ if (!read_from_file(g_bct0_buffer, BCTO_MAX_SIZE, "atmosphere/BCT.ini")) {
+ print(SCREEN_LOG_LEVEL_DEBUG, "Failed to read BCT0 from SD!\n");
+ print(SCREEN_LOG_LEVEL_DEBUG, "Using default BCT0!\n");
memcpy(g_bct0_buffer, DEFAULT_BCT0_FOR_DEBUG, sizeof(DEFAULT_BCT0_FOR_DEBUG));
- /* TODO: Stop using default. */
- /* printk("Error: Failed to load BCT.ini!\n");
- * generic_panic(); */
}
if (memcmp(g_bct0_buffer, "BCT0", 4) != 0) {
fatal_error("Unexpected magic in BCT.ini!\n");
}
+
/* Return pointer to first line of the ini. */
const char *bct0 = g_bct0_buffer;
while (*bct0 && *bct0 != '\n') {
bct0++;
}
+
if (!bct0) {
fatal_error("BCT.ini has no newline!\n");
}
+
return bct0;
}
-static void load_sbk(void) {
- uint32_t sbk[0x4];
- /* Load the SBK into the security engine, if relevant. */
- memcpy(sbk, (void *)get_fuse_chip_regs()->FUSE_PRIVATE_KEY, 0x10);
- for (unsigned int i = 0; i < 4; i++) {
- if (sbk[i] != 0xFFFFFFFF) {
- set_aes_keyslot(0xE, sbk, 0x10);
- break;
+static int config_ini_handler(void *user, const char *section, const char *name, const char *value) {
+ if (strcmp(section, "config") == 0) {
+ if (strcmp(name, CONFIG_LOG_LEVEL_KEY) == 0) {
+ ScreenLogLevel *config_log_level = (ScreenLogLevel *)user;
+ int log_level = 0;
+ sscanf(value, "%d", &log_level);
+ *config_log_level = (ScreenLogLevel)log_level;
+ } else {
+ return 0;
}
+ } else {
+ return 0;
}
+ return 1;
}
static void setup_env(void) {
g_framebuffer = (void *)0xC0000000;
- /* Initialize DRAM. */
- /* TODO: What can be stripped out to make this minimal? */
+ /* Initialize hardware. */
nx_hwinit();
/* Check for panics. */
check_and_display_panic();
- /* Try to load the SBK into the security engine, if possible. */
- /* TODO: Should this be done later? */
- load_sbk();
-
/* Zero-fill the framebuffer and register it as printk provider. */
video_init(g_framebuffer);
@@ -85,11 +104,11 @@ static void setup_env(void) {
/* Turn on the backlight after initializing the lfb */
/* to avoid flickering. */
- display_enable_backlight(true);
+ display_backlight(true);
/* Set up the exception handlers. */
setup_exception_handlers();
-
+
/* Mount the SD card. */
mount_sd();
}
@@ -98,7 +117,7 @@ static void cleanup_env(void) {
/* Unmount the SD card. */
unmount_sd();
- display_enable_backlight(false);
+ display_backlight(false);
display_end();
}
@@ -112,27 +131,26 @@ int main(void) {
const char *stage2_path;
stage2_args_t *stage2_args;
uint32_t stage2_version = 0;
-
- /* Set the SDMMC's driver logging level. */
- sdmmc_set_log_level(SDMMC_LOG_INFO);
+ ScreenLogLevel log_level = SCREEN_LOG_LEVEL_MANDATORY;
+
+ /* Override the global logging level. */
+ log_set_log_level(log_level);
/* Initialize the display, console, etc. */
setup_env();
- /* Say hello. */
- printk("Welcome to Atmosph\xe8re Fus\xe9" "e!\n");
- printk("Using color linear framebuffer at 0x%p!\n", g_framebuffer);
-
-#ifndef I_KNOW_WHAT_I_AM_DOING
-#error "Fusee is a work-in-progress bootloader, and is not ready for usage yet. If you want to play with it anyway, please #define I_KNOW_WHAT_I_AM_DOING -- and recognize that we will be unable to provide support until it is ready for general usage :)"
-
- printk("Warning: Fus\xe9" "e is not yet completed, and not ready for general testing!\n");
- fatal_error("Please do not seek support for it until it is done.\n");
-#endif
-
/* Load the BCT0 configuration ini off of the SD. */
bct0 = load_config();
+ /* Extract the logging level from the BCT.ini file. */
+ if (ini_parse_string(bct0, config_ini_handler, &log_level) < 0) {
+ fatal_error("Failed to parse BCT.ini!\n");
+ }
+
+ /* Say hello. */
+ print(SCREEN_LOG_LEVEL_MANDATORY, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n");
+ print(SCREEN_LOG_LEVEL_DEBUG, "Using color linear framebuffer at 0x%p!\n", g_framebuffer);
+
/* Load the loader payload into DRAM. */
load_stage2(bct0);
@@ -141,11 +159,14 @@ int main(void) {
strcpy(g_chainloader_arg_data, stage2_path);
stage2_args = (stage2_args_t *)(g_chainloader_arg_data + strlen(stage2_path) + 1); /* May be unaligned. */
memcpy(&stage2_args->version, &stage2_version, 4);
+ memcpy(&stage2_args->log_level, &log_level, sizeof(log_level));
stage2_args->display_initialized = false;
- memcpy(&stage2_args->sd_sdmmc, &g_sd_sdmmc, sizeof(g_sd_sdmmc));
strcpy(stage2_args->bct0, bct0);
g_chainloader_argc = 2;
-
+
+ /* Wait a while. */
+ mdelay(1000);
+
/* Deinitialize the display, console, etc. */
cleanup_env();
diff --git a/fusee/fusee-primary/src/max77620.h b/fusee/fusee-primary/src/max77620.h
new file mode 100644
index 000000000..8e1e4627e
--- /dev/null
+++ b/fusee/fusee-primary/src/max77620.h
@@ -0,0 +1,357 @@
+/*
+ * Defining registers address and its bit definitions of MAX77620 and MAX20024
+ *
+ * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef _MFD_MAX77620_H_
+#define _MFD_MAX77620_H_
+
+/* RTC Registers */
+#define MAX77620_REG_RTCINT 0x00
+#define MAX77620_REG_RTCINTM 0x01
+#define MAX77620_REG_RTCCNTLM 0x02
+#define MAX77620_REG_RTCCNTL 0x03
+#define MAX77620_REG_RTCUPDATE0 0x04
+#define MAX77620_REG_RTCUPDATE1 0x05
+#define MAX77620_REG_RTCSMPL 0x06
+#define MAX77620_REG_RTCSEC 0x07
+#define MAX77620_REG_RTCMIN 0x08
+#define MAX77620_REG_RTCHOUR 0x09
+#define MAX77620_REG_RTCDOW 0x0A
+#define MAX77620_REG_RTCMONTH 0x0B
+#define MAX77620_REG_RTCYEAR 0x0C
+#define MAX77620_REG_RTCDOM 0x0D
+#define MAX77620_REG_RTCSECA1 0x0E
+#define MAX77620_REG_RTCMINA1 0x0F
+#define MAX77620_REG_RTCHOURA1 0x10
+#define MAX77620_REG_RTCDOWA1 0x11
+#define MAX77620_REG_RTCMONTHA1 0x12
+#define MAX77620_REG_RTCYEARA1 0x13
+#define MAX77620_REG_RTCDOMA1 0x14
+#define MAX77620_REG_RTCSECA2 0x15
+#define MAX77620_REG_RTCMINA2 0x16
+#define MAX77620_REG_RTCHOURA2 0x17
+#define MAX77620_REG_RTCDOWA2 0x18
+#define MAX77620_REG_RTCMONTHA2 0x19
+#define MAX77620_REG_RTCYEARA2 0x1A
+#define MAX77620_REG_RTCDOMA2 0x1B
+
+/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */
+#define MAX77620_REG_CNFGGLBL1 0x00
+#define MAX77620_REG_CNFGGLBL2 0x01
+#define MAX77620_REG_CNFGGLBL3 0x02
+#define MAX77620_REG_CNFG1_32K 0x03
+#define MAX77620_REG_CNFGBBC 0x04
+#define MAX77620_REG_IRQTOP 0x05
+#define MAX77620_REG_INTLBT 0x06
+#define MAX77620_REG_IRQSD 0x07
+#define MAX77620_REG_IRQ_LVL2_L0_7 0x08
+#define MAX77620_REG_IRQ_LVL2_L8 0x09
+#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A
+#define MAX77620_REG_ONOFFIRQ 0x0B
+#define MAX77620_REG_NVERC 0x0C
+#define MAX77620_REG_IRQTOPM 0x0D
+#define MAX77620_REG_INTENLBT 0x0E
+#define MAX77620_REG_IRQMASKSD 0x0F
+#define MAX77620_REG_IRQ_MSK_L0_7 0x10
+#define MAX77620_REG_IRQ_MSK_L8 0x11
+#define MAX77620_REG_ONOFFIRQM 0x12
+#define MAX77620_REG_STATLBT 0x13
+#define MAX77620_REG_STATSD 0x14
+#define MAX77620_REG_ONOFFSTAT 0x15
+
+/* SD and LDO Registers */
+#define MAX77620_REG_SD0 0x16
+#define MAX77620_REG_SD1 0x17
+#define MAX77620_REG_SD2 0x18
+#define MAX77620_REG_SD3 0x19
+#define MAX77620_REG_SD4 0x1A
+#define MAX77620_REG_DVSSD0 0x1B
+#define MAX77620_REG_DVSSD1 0x1C
+#define MAX77620_REG_SD0_CFG 0x1D
+#define MAX77620_REG_SD1_CFG 0x1E
+#define MAX77620_REG_SD2_CFG 0x1F
+#define MAX77620_REG_SD3_CFG 0x20
+#define MAX77620_REG_SD4_CFG 0x21
+#define MAX77620_REG_SD_CFG2 0x22
+#define MAX77620_REG_LDO0_CFG 0x23
+#define MAX77620_REG_LDO0_CFG2 0x24
+#define MAX77620_REG_LDO1_CFG 0x25
+#define MAX77620_REG_LDO1_CFG2 0x26
+#define MAX77620_REG_LDO2_CFG 0x27
+#define MAX77620_REG_LDO2_CFG2 0x28
+#define MAX77620_REG_LDO3_CFG 0x29
+#define MAX77620_REG_LDO3_CFG2 0x2A
+#define MAX77620_REG_LDO4_CFG 0x2B
+#define MAX77620_REG_LDO4_CFG2 0x2C
+#define MAX77620_REG_LDO5_CFG 0x2D
+#define MAX77620_REG_LDO5_CFG2 0x2E
+#define MAX77620_REG_LDO6_CFG 0x2F
+#define MAX77620_REG_LDO6_CFG2 0x30
+#define MAX77620_REG_LDO7_CFG 0x31
+#define MAX77620_REG_LDO7_CFG2 0x32
+#define MAX77620_REG_LDO8_CFG 0x33
+#define MAX77620_REG_LDO8_CFG2 0x34
+#define MAX77620_REG_LDO_CFG3 0x35
+
+#define MAX77620_LDO_SLEW_RATE_MASK 0x1
+
+/* LDO Configuration 3 */
+#define MAX77620_TRACK4_MASK (1 << 5)
+#define MAX77620_TRACK4_SHIFT 5
+
+/* Voltage */
+#define MAX77620_SDX_VOLT_MASK 0xFF
+#define MAX77620_SD0_VOLT_MASK 0x3F
+#define MAX77620_SD1_VOLT_MASK 0x7F
+#define MAX77620_LDO_VOLT_MASK 0x3F
+
+#define MAX77620_REG_GPIO0 0x36
+#define MAX77620_REG_GPIO1 0x37
+#define MAX77620_REG_GPIO2 0x38
+#define MAX77620_REG_GPIO3 0x39
+#define MAX77620_REG_GPIO4 0x3A
+#define MAX77620_REG_GPIO5 0x3B
+#define MAX77620_REG_GPIO6 0x3C
+#define MAX77620_REG_GPIO7 0x3D
+#define MAX77620_REG_PUE_GPIO 0x3E
+#define MAX77620_REG_PDE_GPIO 0x3F
+#define MAX77620_REG_AME_GPIO 0x40
+#define MAX77620_REG_ONOFFCNFG1 0x41
+#define MAX77620_REG_ONOFFCNFG2 0x42
+
+/* FPS Registers */
+#define MAX77620_REG_FPS_CFG0 0x43
+#define MAX77620_REG_FPS_CFG1 0x44
+#define MAX77620_REG_FPS_CFG2 0x45
+#define MAX77620_REG_FPS_LDO0 0x46
+#define MAX77620_REG_FPS_LDO1 0x47
+#define MAX77620_REG_FPS_LDO2 0x48
+#define MAX77620_REG_FPS_LDO3 0x49
+#define MAX77620_REG_FPS_LDO4 0x4A
+#define MAX77620_REG_FPS_LDO5 0x4B
+#define MAX77620_REG_FPS_LDO6 0x4C
+#define MAX77620_REG_FPS_LDO7 0x4D
+#define MAX77620_REG_FPS_LDO8 0x4E
+#define MAX77620_REG_FPS_SD0 0x4F
+#define MAX77620_REG_FPS_SD1 0x50
+#define MAX77620_REG_FPS_SD2 0x51
+#define MAX77620_REG_FPS_SD3 0x52
+#define MAX77620_REG_FPS_SD4 0x53
+#define MAX77620_REG_FPS_NONE 0
+
+#define MAX77620_FPS_SRC_MASK 0xC0
+#define MAX77620_FPS_SRC_SHIFT 6
+#define MAX77620_FPS_PU_PERIOD_MASK 0x38
+#define MAX77620_FPS_PU_PERIOD_SHIFT 3
+#define MAX77620_FPS_PD_PERIOD_MASK 0x07
+#define MAX77620_FPS_PD_PERIOD_SHIFT 0
+#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
+#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
+#define MAX77620_FPS_EN_SRC_MASK 0x06
+#define MAX77620_FPS_EN_SRC_SHIFT 1
+#define MAX77620_FPS_ENFPS_SW_MASK 0x01
+#define MAX77620_FPS_ENFPS_SW 0x01
+
+/* Minimum and maximum FPS period time (in microseconds) are
+ * different for MAX77620 and Max20024.
+ */
+#define MAX77620_FPS_PERIOD_MIN_US 40
+#define MAX20024_FPS_PERIOD_MIN_US 20
+
+#define MAX77620_FPS_PERIOD_MAX_US 2560
+#define MAX20024_FPS_PERIOD_MAX_US 5120
+
+#define MAX77620_REG_FPS_GPIO1 0x54
+#define MAX77620_REG_FPS_GPIO2 0x55
+#define MAX77620_REG_FPS_GPIO3 0x56
+#define MAX77620_REG_FPS_RSO 0x57
+#define MAX77620_REG_CID0 0x58
+#define MAX77620_REG_CID1 0x59
+#define MAX77620_REG_CID2 0x5A
+#define MAX77620_REG_CID3 0x5B
+#define MAX77620_REG_CID4 0x5C
+#define MAX77620_REG_CID5 0x5D
+
+#define MAX77620_REG_DVSSD4 0x5E
+#define MAX20024_REG_MAX_ADD 0x70
+
+#define MAX77620_CID_DIDM_MASK 0xF0
+#define MAX77620_CID_DIDM_SHIFT 4
+
+/* CNCG2SD */
+#define MAX77620_SD_CNF2_ROVS_EN_SD1 (1 << 1)
+#define MAX77620_SD_CNF2_ROVS_EN_SD0 (1 << 2)
+
+/* Device Identification Metal */
+#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
+/* Device Indentification OTP */
+#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
+
+/* SD CNFG1 */
+#define MAX77620_SD_SR_MASK 0xC0
+#define MAX77620_SD_SR_SHIFT 6
+#define MAX77620_SD_POWER_MODE_MASK 0x30
+#define MAX77620_SD_POWER_MODE_SHIFT 4
+#define MAX77620_SD_CFG1_ADE_MASK (1 << 3)
+#define MAX77620_SD_CFG1_ADE_DISABLE 0
+#define MAX77620_SD_CFG1_ADE_ENABLE (1 << 3)
+#define MAX77620_SD_FPWM_MASK 0x04
+#define MAX77620_SD_FPWM_SHIFT 2
+#define MAX77620_SD_FSRADE_MASK 0x01
+#define MAX77620_SD_FSRADE_SHIFT 0
+#define MAX77620_SD_CFG1_FPWM_SD_MASK (1 << 2)
+#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
+#define MAX77620_SD_CFG1_FPWM_SD_FPWM (1 << 2)
+#define MAX20024_SD_CFG1_MPOK_MASK (1 << 1)
+#define MAX77620_SD_CFG1_FSRADE_SD_MASK (1 << 0)
+#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
+#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE (1 << 0)
+
+/* LDO_CNFG2 */
+#define MAX77620_LDO_POWER_MODE_MASK 0xC0
+#define MAX77620_LDO_POWER_MODE_SHIFT 6
+#define MAX20024_LDO_CFG2_MPOK_MASK (1 << 2)
+#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
+#define MAX77620_LDO_CFG2_ADE_DISABLE 0
+#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
+#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
+#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
+#define MAX77620_LDO_CFG2_SS_SLOW 0
+
+#define MAX77620_IRQ_TOP_GLBL_MASK (1 << 7)
+#define MAX77620_IRQ_TOP_SD_MASK (1 << 6)
+#define MAX77620_IRQ_TOP_LDO_MASK (1 << 5)
+#define MAX77620_IRQ_TOP_GPIO_MASK (1 << 4)
+#define MAX77620_IRQ_TOP_RTC_MASK (1 << 3)
+#define MAX77620_IRQ_TOP_32K_MASK (1 << 2)
+#define MAX77620_IRQ_TOP_ONOFF_MASK (1 << 1)
+
+#define MAX77620_IRQ_LBM_MASK (1 << 3)
+#define MAX77620_IRQ_TJALRM1_MASK (1 << 2)
+#define MAX77620_IRQ_TJALRM2_MASK (1 << 1)
+
+#define MAX77620_CNFG_GPIO_DRV_MASK (1 << 0)
+#define MAX77620_CNFG_GPIO_DRV_PUSHPULL (1 << 0)
+#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN 0
+#define MAX77620_CNFG_GPIO_DIR_MASK (1 << 1)
+#define MAX77620_CNFG_GPIO_DIR_INPUT (1 << 1)
+#define MAX77620_CNFG_GPIO_DIR_OUTPUT 0
+#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK (1 << 2)
+#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK (1 << 3)
+#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH (1 << 3)
+#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW 0
+#define MAX77620_CNFG_GPIO_INT_MASK (0x3 << 4)
+#define MAX77620_CNFG_GPIO_INT_FALLING (1 << 4)
+#define MAX77620_CNFG_GPIO_INT_RISING (1 << 5)
+#define MAX77620_CNFG_GPIO_DBNC_MASK (0x3 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_None (0x0 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
+#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
+
+#define MAX77620_IRQ_LVL2_GPIO_EDGE0 (1 << 0)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE1 (1 << 1)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE2 (1 << 2)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE3 (1 << 3)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE4 (1 << 4)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE5 (1 << 5)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE6 (1 << 6)
+#define MAX77620_IRQ_LVL2_GPIO_EDGE7 (1 << 7)
+
+#define MAX77620_CNFG1_32K_OUT0_EN (1 << 2)
+
+#define MAX77620_ONOFFCNFG1_SFT_RST (1 << 7)
+#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
+#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
+#define MAX77620_ONOFFCNFG1_SLPEN (1 << 2)
+#define MAX77620_ONOFFCNFG1_PWR_OFF (1 << 1)
+#define MAX20024_ONOFFCNFG1_CLRSE 0x18
+
+#define MAX77620_ONOFFCNFG2_SFT_RST_WK (1 << 7)
+#define MAX77620_ONOFFCNFG2_WD_RST_WK (1 << 6)
+#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK (1 << 5)
+#define MAX77620_ONOFFCNFG2_WK_ALARM1 (1 << 2)
+#define MAX77620_ONOFFCNFG2_WK_EN0 (1 << 0)
+
+#define MAX77620_GLBLM_MASK (1 << 0)
+
+#define MAX77620_WDTC_MASK 0x3
+#define MAX77620_WDTOFFC (1 << 4)
+#define MAX77620_WDTSLPC (1 << 3)
+#define MAX77620_WDTEN (1 << 2)
+
+#define MAX77620_TWD_MASK 0x3
+#define MAX77620_TWD_2s 0x0
+#define MAX77620_TWD_16s 0x1
+#define MAX77620_TWD_64s 0x2
+#define MAX77620_TWD_128s 0x3
+
+#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7)
+#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
+#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
+#define MAX77620_CNFGGLBL1_LBHYST_N (1 << 4)
+#define MAX77620_CNFGGLBL1_LBDAC 0x0E
+#define MAX77620_CNFGGLBL1_LBDAC_N (1 << 1)
+#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0)
+
+/* CNFG BBC registers */
+#define MAX77620_CNFGBBC_ENABLE (1 << 0)
+#define MAX77620_CNFGBBC_CURRENT_MASK 0x06
+#define MAX77620_CNFGBBC_CURRENT_SHIFT 1
+#define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18
+#define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3
+#define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE (1 << 5)
+#define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0
+#define MAX77620_CNFGBBC_RESISTOR_SHIFT 6
+
+#define MAX77620_FPS_COUNT 3
+
+/* Interrupts */
+enum {
+ MAX77620_IRQ_TOP_GLBL, /* Low-Battery */
+ MAX77620_IRQ_TOP_SD, /* SD power fail */
+ MAX77620_IRQ_TOP_LDO, /* LDO power fail */
+ MAX77620_IRQ_TOP_GPIO, /* TOP GPIO internal int to MAX77620 */
+ MAX77620_IRQ_TOP_RTC, /* RTC */
+ MAX77620_IRQ_TOP_32K, /* 32kHz oscillator */
+ MAX77620_IRQ_TOP_ONOFF, /* ON/OFF oscillator */
+ MAX77620_IRQ_LBT_MBATLOW, /* Thermal alarm status, > 120C */
+ MAX77620_IRQ_LBT_TJALRM1, /* Thermal alarm status, > 120C */
+ MAX77620_IRQ_LBT_TJALRM2, /* Thermal alarm status, > 140C */
+};
+
+/* GPIOs */
+enum {
+ MAX77620_GPIO0,
+ MAX77620_GPIO1,
+ MAX77620_GPIO2,
+ MAX77620_GPIO3,
+ MAX77620_GPIO4,
+ MAX77620_GPIO5,
+ MAX77620_GPIO6,
+ MAX77620_GPIO7,
+ MAX77620_GPIO_NR,
+};
+
+/* FPS Source */
+enum max77620_fps_src {
+ MAX77620_FPS_SRC_0,
+ MAX77620_FPS_SRC_1,
+ MAX77620_FPS_SRC_2,
+ MAX77620_FPS_SRC_NONE,
+ MAX77620_FPS_SRC_DEF,
+};
+
+enum max77620_chip_id {
+ MAX77620,
+ MAX20024,
+};
+
+#endif /* _MFD_MAX77620_H_ */
diff --git a/fusee/fusee-primary/src/max7762x.c b/fusee/fusee-primary/src/max7762x.c
new file mode 100644
index 000000000..2987917e5
--- /dev/null
+++ b/fusee/fusee-primary/src/max7762x.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "max7762x.h"
+#include "max77620.h"
+#include "i2c.h"
+#include "timers.h"
+
+#define REGULATOR_SD 0
+#define REGULATOR_LDO 1
+
+typedef struct _max77620_regulator_t
+{
+ uint8_t type;
+ const char *name;
+ uint8_t reg_sd;
+ uint32_t mv_step;
+ uint32_t mv_min;
+ uint32_t mv_default;
+ uint32_t mv_max;
+ uint8_t volt_addr;
+ uint8_t cfg_addr;
+ uint8_t volt_mask;
+ uint8_t enable_mask;
+ uint8_t enable_shift;
+ uint8_t status_mask;
+
+ uint8_t fps_addr;
+ uint8_t fps_src;
+ uint8_t pd_period;
+ uint8_t pu_period;
+} max77620_regulator_t;
+
+static const max77620_regulator_t _pmic_regulators[] = {
+ { REGULATOR_SD, "sd0", 0x16, 12500, 600000, 625000, 1400000, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, 0x3F, 0x30, 4, 0x80, 0x4F, 1, 7, 1 },
+ { REGULATOR_SD, "sd1", 0x17, 12500, 600000, 1125000, 1125000, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, 0x3F, 0x30, 4, 0x40, 0x50, 0, 1, 5 },
+ { REGULATOR_SD, "sd2", 0x18, 12500, 600000, 1325000, 1350000, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, 0xFF, 0x30, 4, 0x20, 0x51, 1, 5, 2 },
+ { REGULATOR_SD, "sd3", 0x19, 12500, 600000, 1800000, 1800000, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, 0xFF, 0x30, 4, 0x10, 0x52, 0, 3, 3 },
+ { REGULATOR_LDO, "ldo0", 0x00, 25000, 800000, 1200000, 1200000, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, 0x3F, 0xC0, 6, 0x00, 0x46, 3, 7, 0 },
+ { REGULATOR_LDO, "ldo1", 0x00, 25000, 800000, 1050000, 1050000, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, 0x3F, 0xC0, 6, 0x00, 0x47, 3, 7, 0 },
+ { REGULATOR_LDO, "ldo2", 0x00, 50000, 800000, 1800000, 3300000, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, 0x3F, 0xC0, 6, 0x00, 0x48, 3, 7, 0 },
+ { REGULATOR_LDO, "ldo3", 0x00, 50000, 800000, 3100000, 3100000, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, 0x3F, 0xC0, 6, 0x00, 0x49, 3, 7, 0 },
+ { REGULATOR_LDO, "ldo4", 0x00, 12500, 800000, 850000, 850000, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4A, 0, 7, 1 },
+ { REGULATOR_LDO, "ldo5", 0x00, 50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4B, 3, 7, 0 },
+ { REGULATOR_LDO, "ldo6", 0x00, 50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4C, 3, 7, 0 },
+ { REGULATOR_LDO, "ldo7", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4D, 1, 4, 3 },
+ { REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, 0x3F, 0xC0, 6, 0x00, 0x4E, 3, 7, 0 }
+};
+
+int max77620_regulator_get_status(uint32_t id)
+{
+ if (id > REGULATOR_MAX)
+ return 0;
+
+ const max77620_regulator_t *reg = &_pmic_regulators[id];
+ uint8_t val = 0;
+
+ if (reg->type == REGULATOR_SD) {
+ if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_STATSD, &val, 1))
+ return (val & reg->status_mask) ? 0 : 1;
+ }
+
+ if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, reg->cfg_addr, &val, 1))
+ return (val & 8) ? 1 : 0;
+
+ return 0;
+}
+
+int max77620_regulator_config_fps(uint32_t id)
+{
+ if (id > REGULATOR_MAX)
+ return 0;
+
+ const max77620_regulator_t *reg = &_pmic_regulators[id];
+ uint8_t val = ((reg->fps_src << 6) | (reg->pu_period << 3) | (reg->pd_period));
+
+ if (i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, reg->fps_addr, &val, 1)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+int max77620_regulator_set_voltage(uint32_t id, uint32_t mv)
+{
+ if (id > REGULATOR_MAX)
+ return 0;
+
+ const max77620_regulator_t *reg = &_pmic_regulators[id];
+
+ if ((mv < reg->mv_default) || (mv > reg->mv_max))
+ return 0;
+
+ uint32_t mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
+ uint8_t val = 0;
+
+ if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, reg->volt_addr, &val, 1))
+ {
+ val = ((val & ~reg->volt_mask) | (mult & reg->volt_mask));
+
+ if (i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, reg->volt_addr, &val, 1))
+ {
+ udelay(1000);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int max77620_regulator_enable(uint32_t id, int enable)
+{
+ if (id > REGULATOR_MAX)
+ return 0;
+
+ const max77620_regulator_t *reg = &_pmic_regulators[id];
+
+ uint32_t addr = (reg->type == REGULATOR_SD) ? reg->cfg_addr : reg->volt_addr;
+ uint8_t val = 0;
+
+ if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, addr, &val, 1))
+ {
+ if (enable)
+ val = ((val & ~reg->enable_mask) | ((3 << reg->enable_shift) & reg->enable_mask));
+ else
+ val &= ~reg->enable_mask;
+
+ if (i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, addr, &val, 1))
+ {
+ udelay(1000);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void max77620_config_default()
+{
+ for (uint32_t i = 1; i <= REGULATOR_MAX; i++)
+ {
+ uint8_t val = 0;
+ if (i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CID4, &val, 1))
+ {
+ max77620_regulator_config_fps(i);
+ max77620_regulator_set_voltage(i, _pmic_regulators[i].mv_default);
+
+ if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE) {
+ max77620_regulator_enable(i, 1);
+ }
+ }
+ }
+
+ uint8_t val = 4;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD_CFG2, &val, 1);
+}
+
+void max77620_low_battery_monitor_config()
+{
+ uint8_t val = (MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_LBHYST_N | MAX77620_CNFGGLBL1_LBDAC_N);
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
+}
diff --git a/fusee/fusee-secondary/src/hwinit/max7762x.h b/fusee/fusee-primary/src/max7762x.h
similarity index 59%
rename from fusee/fusee-secondary/src/hwinit/max7762x.h
rename to fusee/fusee-primary/src/max7762x.h
index 05434956e..8149c03f4 100644
--- a/fusee/fusee-secondary/src/hwinit/max7762x.h
+++ b/fusee/fusee-primary/src/max7762x.h
@@ -1,34 +1,33 @@
/*
-* Copyright (c) 2018 naehrwert
-*
-* 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 .
-*/
-
-#ifndef _MAX7762X_H_
-#define _MAX7762X_H_
-
-#include "types.h"
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_MAX7762X_H_
+#define FUSEE_MAX7762X_H_
/*
* Switch Power domains (max77620):
* Name | Usage | uV step | uV min | uV default | uV max | Init
*-------+---------------+---------+--------+------------+---------+------------------
* sd0 | core | 12500 | 600000 | 625000 | 1400000 | 1.125V (pkg1.1)
-* sd1 | SDRAM | 12500 | 600000 | 1125000 | 1125000 | 1.1V (pkg1.1)
+* sd1 | SDRAM | 12500 | 600000 | 1125000 | 1125000 | 1.1V (pkg1.1)
* sd2 | ldo{0-1, 7-8} | 12500 | 600000 | 1325000 | 1350000 | 1.325V (pcv)
* sd3 | 1.8V general | 12500 | 600000 | 1800000 | 1800000 |
-* ldo0 | Display Panel | 25000 | 800000 | 1200000 | 1200000 | 1.2V (pkg1.1)
-* ldo1 | XUSB | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
+* ldo0 | Display Panel | 25000 | 800000 | 1200000 | 1200000 | 1.2V (pkg1.1)
+* ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
* ldo3 | | 50000 | 800000 | 3100000 | 3100000 |
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 |
@@ -59,10 +58,11 @@
#define REGULATOR_LDO8 12
#define REGULATOR_MAX 12
-int max77620_regulator_get_status(u32 id);
-int max77620_regulator_config_fps(u32 id);
-int max77620_regulator_set_voltage(u32 id, u32 mv);
-int max77620_regulator_enable(u32 id, int enable);
+int max77620_regulator_get_status(uint32_t id);
+int max77620_regulator_config_fps(uint32_t id);
+int max77620_regulator_set_voltage(uint32_t id, uint32_t mv);
+int max77620_regulator_enable(uint32_t id, int enable);
void max77620_config_default();
+void max77620_low_battery_monitor_config();
#endif
diff --git a/fusee/fusee-primary/src/mc.c b/fusee/fusee-primary/src/mc.c
new file mode 100644
index 000000000..e803d7a7c
--- /dev/null
+++ b/fusee/fusee-primary/src/mc.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "mc.h"
+#include "car.h"
+#include "timers.h"
+
+void mc_config_tsec_carveout(uint32_t bom, uint32_t size1mb, bool lock)
+{
+ MAKE_MC_REG(MC_SEC_CARVEOUT_BOM) = bom;
+ MAKE_MC_REG(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
+
+ if (lock)
+ MAKE_MC_REG(MC_SEC_CARVEOUT_REG_CTRL) = 1;
+}
+
+void mc_config_carveout()
+{
+ *(volatile uint32_t *)0x8005FFFC = 0xC0EDBBCC;
+
+ MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_BOM) = 0;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_SIZE_MB) = 0;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_REG_CTRL) = 1;
+
+ mc_config_tsec_carveout(0, 0, true);
+
+ MAKE_MC_REG(MC_MTS_CARVEOUT_BOM) = 0;
+ MAKE_MC_REG(MC_MTS_CARVEOUT_SIZE_MB) = 0;
+ MAKE_MC_REG(MC_MTS_CARVEOUT_ADR_HI) = 0;
+ MAKE_MC_REG(MC_MTS_CARVEOUT_REG_CTRL) = 1;
+
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_BOM) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;
+
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_BOM) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;
+
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_BOM) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;
+
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_BOM) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
+}
+
+void mc_config_carveout_finalize()
+{
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
+ MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
+}
+
+void mc_enable_ahb_redirect()
+{
+ volatile tegra_car_t *car = car_get_regs();
+ car->lvl2_clk_gate_ovrd = ((car->lvl2_clk_gate_ovrd & 0xFFF7FFFF) | 0x80000);
+
+ MAKE_MC_REG(MC_IRAM_BOM) = 0x40000000;
+ MAKE_MC_REG(MC_IRAM_TOM) = 0x4003F000;
+}
+
+void mc_disable_ahb_redirect()
+{
+ volatile tegra_car_t *car = car_get_regs();
+
+ MAKE_MC_REG(MC_IRAM_BOM) = 0xFFFFF000;
+ MAKE_MC_REG(MC_IRAM_TOM) = 0;
+
+ car->lvl2_clk_gate_ovrd &= 0xFFF7FFFF;
+}
+
+void mc_enable()
+{
+ volatile tegra_car_t *car = car_get_regs();
+
+ /* Set EMC clock source. */
+ car->clk_source_emc = ((car->clk_source_emc & 0x1FFFFFFF) | 0x40000000);
+
+ /* Enable MIPI CAL clock. */
+ car->clk_enb_h_set = ((car->clk_enb_h_set & 0xFDFFFFFF) | 0x2000000);
+
+ /* Enable MC clock. */
+ car->clk_enb_h_set = ((car->clk_enb_h_set & 0xFFFFFFFE) | 1);
+
+ /* Enable EMC DLL clock. */
+ car->clk_enb_x_set = ((car->clk_enb_x_set & 0xFFFFBFFF) | 0x4000);
+
+ /* Clear EMC and MC reset. */
+ /* NOTE: [4.0.0+] This was changed to use the right register. */
+ /* car->rst_dev_h_set = 0x2000001; */
+ car->rst_dev_h_clr = 0x2000001;
+ udelay(5);
+
+ mc_disable_ahb_redirect();
+}
\ No newline at end of file
diff --git a/fusee/fusee-secondary/src/hwinit/mc.h b/fusee/fusee-primary/src/mc.h
similarity index 80%
rename from fusee/fusee-secondary/src/hwinit/mc.h
rename to fusee/fusee-primary/src/mc.h
index 7eebdf4e0..dfba6052c 100644
--- a/fusee/fusee-secondary/src/hwinit/mc.h
+++ b/fusee/fusee-primary/src/mc.h
@@ -1,23 +1,51 @@
/*
-* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
-*
-* This software is licensed under the terms of the GNU General Public
-* License version 2, as published by the Free Software Foundation, and
-* may be copied, distributed, and modified under those terms.
-*
-* This program is distributed in the hope that 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.
-*/
+ * Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_MC_H_
+#define FUSEE_MC_H_
-#ifndef _MC_H_
-#define _MC_
+#include
+#include
+
+#define MC_BASE 0x70019000
+#define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n)
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4
#define MC_ERR_STATUS 0x8
#define MC_ERR_ADR 0xc
+#define MC_SMMU_CONFIG 0x10
+#define MC_SMMU_TLB_CONFIG 0x14
+#define MC_SMMU_PTC_CONFIG 0x18
+#define MC_SMMU_PTB_ASID 0x1c
+#define MC_SMMU_PTB_DATA 0x20
+#define MC_SMMU_TLB_FLUSH 0x30
+#define MC_SMMU_PTC_FLUSH 0x34
+#define MC_SMMU_ASID_SECURITY 0x38
+#define MC_SMMU_AFI_ASID 0x238
+#define MC_SMMU_AVPC_ASID 0x23c
+#define MC_SMMU_TSEC_ASID 0x294
+#define MC_SMMU_PPCS1_ASID 0x298
+#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
+#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
+#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
+#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
+#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0
#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
@@ -463,4 +491,108 @@
#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
#define MC_DA_CONFIG0 0x9dc
-#endif
+/* Memory Controller clients */
+#define CLIENT_ACCESS_NUM_CLIENTS 32
+typedef enum {
+ /* _ACCESS0 */
+ CSR_PTCR = (0 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0A = (1 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0AB = (2 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0B = (3 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0BB = (4 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0C = (5 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAY0CB = (6 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_AFIR = (14 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_AVPCARM7R = (15 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAYHC = (16 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_DISPLAYHCB = (17 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_HDAR = (21 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_HOST1XDMAR = (22 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_HOST1XR = (23 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_NVENCSRD = (28 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_PPCSAHBDMAR = (29 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_PPCSAHBSLVR = (30 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+ CSR_SATAR = (31 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
+
+ /* _ACCESS1 */
+ CSR_VDEBSEVR = (34 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_VDEMBER = (35 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_VDEMCER = (36 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_VDETPER = (37 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_MPCORELPR = (38 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSR_MPCORER = (39 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_NVENCSWR = (43 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_AFIW = (49 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_AVPCARM7W = (50 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_HDAW = (53 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_HOST1XW = (54 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_MPCORELPW = (56 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_MPCOREW = (57 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_PPCSAHBDMAW = (59 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_PPCSAHBSLVW = (60 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_SATAW = (61 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_VDEBSEVW = (62 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+ CSW_VDEDBGW = (63 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
+
+ /* _ACCESS2 */
+ CSW_VDEMBEW = (64 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_VDETPMW = (65 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_ISPRA = (68 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWA = (70 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWB = (71 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_XUSB_HOSTR = (74 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_XUSB_HOSTW = (75 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_XUSB_DEVR = (76 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_XUSB_DEVW = (77 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_ISPRAB = (78 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWAB = (80 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_ISPWBB = (81 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_TSECSRD = (84 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_TSECSWR = (85 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_A9AVPSCR = (86 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_A9AVPSCW = (87 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_GPUSRD = (88 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSW_GPUSWR = (89 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+ CSR_DISPLAYT = (90 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
+
+ /* _ACCESS3 */
+ CSR_SDMMCRA = (96 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_SDMMCRAA = (97 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_SDMMCR = (98 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_SDMMCRAB = (99 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCWA = (100 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCWAA = (101 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCW = (102 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_SDMMCWAB = (103 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_VICSRD = (108 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_VICSWR = (109 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_VIW = (114 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_DISPLAYD = (115 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_NVDECSRD = (120 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_NVDECSWR = (121 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_APER = (122 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_APEW = (123 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSR_NVJPGSRD = (126 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+ CSW_NVJPGSWR = (127 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
+
+ /* _ACCESS4 */
+ CSR_SESRD = (128 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_SESWR = (129 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_AXIAPR = (130 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_AXIAPW = (131 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_ETRR = (132 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_ETRW = (133 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_TSECSRDB = (134 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_TSECSWRB = (135 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSR_GPUSRD2 = (136 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
+ CSW_GPUSWR2 = (137 - (CLIENT_ACCESS_NUM_CLIENTS * 4))
+} McClient;
+
+void mc_config_tsec_carveout(uint32_t bom, uint32_t size1mb, bool lock);
+void mc_config_carveout();
+void mc_config_carveout_finalize();
+void mc_enable_ahb_redirect();
+void mc_disable_ahb_redirect();
+void mc_enable();
+
+#endif
\ No newline at end of file
diff --git a/fusee/fusee-primary/src/panic.c b/fusee/fusee-primary/src/panic.c
index b5c4591b6..d8f298470 100644
--- a/fusee/fusee-primary/src/panic.c
+++ b/fusee/fusee-primary/src/panic.c
@@ -1,8 +1,24 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include "panic.h"
+#include "di.h"
#include "pmc.h"
#include "fuse.h"
#include "utils.h"
-#include "hwinit.h"
static uint32_t g_panic_code = 0;
diff --git a/fusee/fusee-primary/src/panic.h b/fusee/fusee-primary/src/panic.h
index 0b29f7070..78ea67fb6 100644
--- a/fusee/fusee-primary/src/panic.h
+++ b/fusee/fusee-primary/src/panic.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_PANIC_H
#define FUSEE_PANIC_H
diff --git a/fusee/fusee-primary/src/panic_color.h b/fusee/fusee-primary/src/panic_color.h
index a87cfdeb6..68b00bf19 100644
--- a/fusee/fusee-primary/src/panic_color.h
+++ b/fusee/fusee-primary/src/panic_color.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_PANIC_COLOR_H
#define FUSEE_PANIC_COLOR_H
diff --git a/fusee/fusee-primary/src/pinmux.h b/fusee/fusee-primary/src/pinmux.h
index d7131d1d5..3912143eb 100644
--- a/fusee/fusee-primary/src/pinmux.h
+++ b/fusee/fusee-primary/src/pinmux.h
@@ -1,6 +1,25 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_PINMUX_H
#define FUSEE_PINMUX_H
+#define PINMUX_BASE 0x70003000
+#define MAKE_PINMUX_REG(n) MAKE_REG32(PINMUX_BASE + n)
+
#define PINMUX_TRISTATE (1 << 4)
#define PINMUX_PARKED (1 << 5)
#define PINMUX_INPUT (1 << 6)
@@ -186,7 +205,7 @@ typedef struct {
static inline volatile tegra_pinmux_t *pinmux_get_regs(void)
{
- return (volatile tegra_pinmux_t *)0x70003000;
+ return (volatile tegra_pinmux_t *)PINMUX_BASE;
}
#endif
diff --git a/fusee/fusee-primary/src/pmc.h b/fusee/fusee-primary/src/pmc.h
index 4c10d1a0e..80c36da7f 100644
--- a/fusee/fusee-primary/src/pmc.h
+++ b/fusee/fusee-primary/src/pmc.h
@@ -1,25 +1,70 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_PMC_H
#define FUSEE_PMC_H
-/* TODO: get rid of these defines; use the struct instead */
+#include
+
#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_REG32(PMC_BASE + 0x00)
-#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_STATUS_0 MAKE_REG32(PMC_BASE + 0x38)
-#define APBDEV_PMC_SCRATCH0_0 MAKE_REG32(PMC_BASE + 0x50)
-#define APBDEV_PMC_CRYPTO_OP_0 MAKE_REG32(PMC_BASE + 0xF4)
-#define APBDEV_PM_0 MAKE_REG32(PMC_BASE + 0x14)
-#define APBDEV_PMC_WAKE2_STATUS_0 MAKE_REG32(PMC_BASE + 0x168)
-#define APBDEV_PMC_RST_STATUS_0 MAKE_REG32(PMC_BASE + 0x1B4)
-#define APBDEV_PMC_CNTRL2_0 MAKE_REG32(PMC_BASE + 0x440)
-#define APBDEV_PMC_SCRATCH43_0 MAKE_REG32(PMC_BASE + 0x22C)
-#define APBDEV_PMC_SCRATCH200_0 MAKE_REG32(PMC_BASE + 0x840)
+#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;
@@ -42,7 +87,6 @@ typedef struct {
uint32_t no_iopower;
uint32_t pwr_det;
uint32_t pwr_det_latch;
-
uint32_t scratch0;
uint32_t scratch1;
uint32_t scratch2;
@@ -67,14 +111,12 @@ typedef struct {
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;
@@ -88,7 +130,6 @@ typedef struct {
uint32_t usb_ao;
uint32_t crypto_op;
uint32_t pllp_wb0_override;
-
uint32_t scratch24;
uint32_t scratch25;
uint32_t scratch26;
@@ -108,7 +149,6 @@ typedef struct {
uint32_t scratch40;
uint32_t scratch41;
uint32_t scratch42;
-
uint32_t bo_mirror0;
uint32_t bo_mirror1;
uint32_t bo_mirror2;
@@ -143,10 +183,9 @@ typedef struct {
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 _reserved0;
uint32_t pllm_wb0_ovrride_frq;
uint32_t test_pwrgate;
uint32_t pwrgate_timer_mult;
@@ -156,8 +195,12 @@ typedef struct {
uint32_t utmip_pad_cfg;
uint32_t utmip_term_pad_cfg;
uint32_t utmip_uhsic_sleep_cfg;
-
- uint32_t todo_0[9];
+ 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;
@@ -176,7 +219,22 @@ typedef struct {
uint32_t scratch0_eco;
uint32_t por_dpd_ctrl;
uint32_t scratch2_eco;
- uint32_t todo_1[17];
+ 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;
@@ -184,7 +242,9 @@ typedef struct {
uint32_t sticky_bits;
uint32_t sec_disable2;
uint32_t weak_bias;
- uint32_t todo_3[13];
+ 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;
@@ -213,15 +273,64 @@ typedef struct {
uint32_t secure_scratch33;
uint32_t secure_scratch34;
uint32_t secure_scratch35;
-
- uint32_t reserved1[52];
+ 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 reserved2[6];
+ 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_stat;
- uint32_t strap_opt_a;
- uint32_t reserved3[102];
-
+ 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;
@@ -286,12 +395,232 @@ typedef struct {
uint32_t scratch117;
uint32_t scratch118;
uint32_t scratch119;
- uint32_t scratch1_eco;
+ 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 *)0x7000E400;
+ return (volatile tegra_pmc_t *)PMC_BASE;
}
#endif
diff --git a/fusee/fusee-primary/src/sdmmc/mmc.h b/fusee/fusee-primary/src/sdmmc/mmc.h
index e357d00a4..6f7126c01 100644
--- a/fusee/fusee-primary/src/sdmmc/mmc.h
+++ b/fusee/fusee-primary/src/sdmmc/mmc.h
@@ -2,6 +2,7 @@
* Header for MultiMediaCard (MMC)
*
* Copyright 2002 Hewlett-Packard Company
+ * Copyright (c) 2018 Atmosphère-NX
*
* Use consistent with the GNU GPL is permitted,
* provided that this copyright notice is
diff --git a/fusee/fusee-primary/src/sdmmc/sd.h b/fusee/fusee-primary/src/sdmmc/sd.h
index e5707f55f..c30e8647e 100644
--- a/fusee/fusee-primary/src/sdmmc/sd.h
+++ b/fusee/fusee-primary/src/sdmmc/sd.h
@@ -2,6 +2,8 @@
* include/linux/mmc/sd.h
*
* Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
+ * Copyright (C) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/fusee/fusee-primary/src/sdmmc/sdmmc.c b/fusee/fusee-primary/src/sdmmc/sdmmc.c
index f4243d9c7..3aeb59f90 100644
--- a/fusee/fusee-primary/src/sdmmc/sdmmc.c
+++ b/fusee/fusee-primary/src/sdmmc/sdmmc.c
@@ -1,3 +1,21 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include
@@ -8,7 +26,6 @@
#include "mmc.h"
#include "sd.h"
#include "../timers.h"
-#include "../lib/driver_utils.h"
#define UNSTUFF_BITS(resp,start,size) \
({ \
@@ -189,7 +206,7 @@ static int sdmmc_device_rw(sdmmc_device_t *device, uint32_t sector, uint32_t num
sdmmc_device_send_status(device);
/* Wait for a while. */
- udelay(100000);
+ mdelay(100);
}
else
break;
@@ -487,12 +504,12 @@ static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool i
return 0;
/* Delay a bit before asking for the voltage switch. */
- udelay(1000);
+ mdelay(100);
/* Tell the driver to switch the voltage. */
if (!sdmmc_switch_voltage(device->sdmmc))
return 0;
-
+
/* We are now running at 1.8V. */
device->is_180v = true;
}
@@ -504,8 +521,8 @@ static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool i
/* Keep checking if timeout expired. */
is_timeout = (get_time_since(timebase) > 2000000);
- /* Delay for an appropriate period. */
- udelay(10000);
+ /* Delay for a minimum of 10 milliseconds. */
+ mdelay(10);
}
return 0;
@@ -643,7 +660,7 @@ static int sdmmc_sd_switch(sdmmc_device_t *device, uint32_t mode, uint32_t group
static int sdmmc_sd_set_current_limit(sdmmc_device_t *device, uint8_t *status)
{
/* Start with the highest possible limit. */
- uint32_t current_limit = SD_SET_CURRENT_LIMIT_800;
+ int32_t current_limit = SD_SET_CURRENT_LIMIT_800;
/* Try each limit. */
while (current_limit > SD_SET_CURRENT_NO_CHANGE)
@@ -693,15 +710,15 @@ static int sdmmc_sd_switch_hs_low(sdmmc_device_t *device, uint8_t *status)
/* Adjust the current limit. */
if (!sdmmc_sd_set_current_limit(device, status))
return 0;
-
+
/* Invalid bus width. */
if (device->sdmmc->bus_width != SDMMC_BUS_WIDTH_4BIT)
return 0;
-
+
/* Get the supported high-speed type. */
if (!sdmmc_sd_switch(device, 0, 0, 0xF, status))
return 0;
-
+
/* High-speed SDR104 is supported. */
if (status[13] & SD_MODE_UHS_SDR104)
{
@@ -748,6 +765,7 @@ static int sdmmc_sd_switch_hs_low(sdmmc_device_t *device, uint8_t *status)
else
return 0;
+
/* Peek the SD card's status. */
return sdmmc_device_send_status(device);
}
@@ -974,22 +992,22 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
/* Switch to high-speed from low voltage (if possible). */
if (!sdmmc_sd_switch_hs_low(device, switch_status))
{
- sdmmc_error(sdmmc, "Failed to switch to high-speed!");
+ sdmmc_error(sdmmc, "Failed to switch to high-speed from low voltage!");
return 0;
}
- sdmmc_info(sdmmc, "Switched to high-speed!");
+ sdmmc_info(sdmmc, "Switched to high-speed from low voltage!");
}
else if ((device->scr.sda_vsn & (SD_SCR_SPEC_VER_1 | SD_SCR_SPEC_VER_2)) && ((bus_speed != SDMMC_SPEED_UNK6)))
{
/* Switch to high-speed from high voltage (if possible). */
if (!sdmmc_sd_switch_hs_high(device, switch_status))
{
- sdmmc_error(sdmmc, "Failed to switch to high-speed!");
+ sdmmc_error(sdmmc, "Failed to switch to high-speed from high voltage!");
return 0;
}
- sdmmc_info(sdmmc, "Switched to high-speed!");
+ sdmmc_info(sdmmc, "Switched to high-speed from high voltage!");
}
/* Correct any inconsistent states. */
@@ -1161,8 +1179,8 @@ static int sdmmc_mmc_send_op_cond(sdmmc_device_t *device, SdmmcBusVoltage bus_vo
/* Keep checking if timeout expired. */
is_timeout = (get_time_since(timebase) > 2000000);
- /* Delay for an appropriate period. */
- udelay(10000);
+ /* Delay for a minimum of 10 milliseconds. */
+ mdelay(10);
}
return 0;
@@ -1357,6 +1375,18 @@ static int sdmmc_mmc_select_bkops(sdmmc_device_t *device)
return sdmmc_device_send_status(device);
}
+int sdmmc_mmc_select_partition(sdmmc_device_t *device, SdmmcPartitionNum partition)
+{
+ uint32_t arg = (((MMC_SWITCH_MODE_WRITE_BYTE) << 24) | ((EXT_CSD_PART_CONFIG) << 16) | ((partition) << 8));
+
+ /* Try to change the active partition. */
+ if (!sdmmc_mmc_switch(device, arg))
+ return 0;
+
+ /* Peek the current status. */
+ return sdmmc_device_send_status(device);
+}
+
int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth bus_width, SdmmcBusSpeed bus_speed)
{
uint32_t cid[4] = {0};
@@ -1376,6 +1406,9 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
/* Bind the underlying driver. */
device->sdmmc = sdmmc;
+ /* Set RCA. */
+ device->rca = 0x01;
+
sdmmc_info(sdmmc, "SDMMC driver was successfully initialized for eMMC!");
/* Apply at least 74 clock cycles. eMMC should be ready afterwards. */
@@ -1408,14 +1441,14 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
sdmmc_info(sdmmc, "Got CID from eMMC!");
- /* Get the eMMC's RCA. */
+ /* Set the eMMC's RCA. */
if (!sdmmc_mmc_set_relative_addr(device))
{
- sdmmc_error(sdmmc, "Failed to get RCA!");
+ sdmmc_error(sdmmc, "Failed to set RCA!");
return 0;
}
- sdmmc_info(sdmmc, "Got RCA (0x%08x) from eMMC!", device->rca);
+ sdmmc_info(sdmmc, "RCA is now set in eMMC!");
/* Get the eMMC card's CSD. */
if (!sdmmc_device_send_csd(device, csd))
@@ -1484,7 +1517,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
/* Decode and save the CID. */
sdmmc_mmc_decode_cid(device, cid);
-
+
/* TODO: Handle automatic BKOPS properly. Leave it disabled for now. */
if (false && device->ext_csd.bkops && !(device->ext_csd.auto_bkops_en & EXT_CSD_AUTO_BKOPS_MASK))
{
@@ -1507,4 +1540,4 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
sdmmc_adjust_sd_clock(sdmmc);
return 1;
-}
+}
\ No newline at end of file
diff --git a/fusee/fusee-primary/src/sdmmc/sdmmc.h b/fusee/fusee-primary/src/sdmmc/sdmmc.h
index 6e955644b..a40fe60d1 100644
--- a/fusee/fusee-primary/src/sdmmc/sdmmc.h
+++ b/fusee/fusee-primary/src/sdmmc/sdmmc.h
@@ -1,3 +1,21 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_SDMMC_H
#define FUSEE_SDMMC_H
@@ -156,5 +174,6 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
int sdmmc_device_read(sdmmc_device_t *device, uint32_t sector, uint32_t num_sectors, void *data);
int sdmmc_device_write(sdmmc_device_t *device, uint32_t sector, uint32_t num_sectors, void *data);
int sdmmc_device_finish(sdmmc_device_t *device);
+int sdmmc_mmc_select_partition(sdmmc_device_t *device, SdmmcPartitionNum partition);
#endif
\ No newline at end of file
diff --git a/fusee/fusee-primary/src/sdmmc/sdmmc_core.c b/fusee/fusee-primary/src/sdmmc/sdmmc_core.c
index 4637d5fc5..ded10a7ab 100644
--- a/fusee/fusee-primary/src/sdmmc/sdmmc_core.c
+++ b/fusee/fusee-primary/src/sdmmc/sdmmc_core.c
@@ -1,3 +1,21 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include
@@ -11,42 +29,17 @@
#include "../apb_misc.h"
#include "../gpio.h"
#include "../pmc.h"
-#include "../lib/driver_utils.h"
-#include "../hwinit/max7762x.h"
+#include "../max7762x.h"
+#include "../lib/log.h"
-#define SDMMC_BOUNCE_BUFFER_ADDRESS 0x90000000
-
-static SdmmcLogLevel g_sdmmc_log_level = SDMMC_LOG_NONE;
-
-void sdmmc_set_log_level(SdmmcLogLevel log_level)
+static void sdmmc_print(sdmmc_t *sdmmc, ScreenLogLevel screen_log_level, char *fmt, va_list list)
{
- g_sdmmc_log_level = log_level;
-}
-
-static void sdmmc_print(sdmmc_t *sdmmc, SdmmcLogLevel log_level, char *fmt, va_list list)
-{
- if (log_level > g_sdmmc_log_level)
+ if (screen_log_level > log_get_log_level())
return;
- switch (log_level) {
- case SDMMC_LOG_ERROR:
- printk("%s [ERROR]: ", sdmmc->name);
- break;
- case SDMMC_LOG_WARN:
- printk("%s [WARN]: ", sdmmc->name);
- break;
- case SDMMC_LOG_INFO:
- printk("%s [INFO]: ", sdmmc->name);
- break;
- case SDMMC_LOG_DEBUG:
- printk("%s [DEBUG]: ", sdmmc->name);
- break;
- default:
- break;
- }
-
- vprintk(fmt, list);
- printk("\n");
+ print(screen_log_level, "%s: ", sdmmc->name);
+ vprint(screen_log_level, fmt, list);
+ print(screen_log_level | SCREEN_LOG_LEVEL_NO_PREFIX, "\n");
}
void sdmmc_error(sdmmc_t *sdmmc, char *fmt, ...)
@@ -54,7 +47,7 @@ void sdmmc_error(sdmmc_t *sdmmc, char *fmt, ...)
va_list list;
va_start(list, fmt);
- sdmmc_print(sdmmc, SDMMC_LOG_ERROR, fmt, list);
+ sdmmc_print(sdmmc, SCREEN_LOG_LEVEL_ERROR, fmt, list);
va_end(list);
}
@@ -63,7 +56,7 @@ void sdmmc_warn(sdmmc_t *sdmmc, char *fmt, ...)
va_list list;
va_start(list, fmt);
- sdmmc_print(sdmmc, SDMMC_LOG_WARN, fmt, list);
+ sdmmc_print(sdmmc, SCREEN_LOG_LEVEL_WARNING, fmt, list);
va_end(list);
}
@@ -72,7 +65,7 @@ void sdmmc_info(sdmmc_t *sdmmc, char *fmt, ...)
va_list list;
va_start(list, fmt);
- sdmmc_print(sdmmc, SDMMC_LOG_INFO, fmt, list);
+ sdmmc_print(sdmmc, SCREEN_LOG_LEVEL_INFO, fmt, list);
va_end(list);
}
@@ -81,7 +74,7 @@ void sdmmc_debug(sdmmc_t *sdmmc, char *fmt, ...)
va_list list;
va_start(list, fmt);
- sdmmc_print(sdmmc, SDMMC_LOG_DEBUG, fmt, list);
+ sdmmc_print(sdmmc, SCREEN_LOG_LEVEL_DEBUG, fmt, list);
va_end(list);
}
@@ -116,7 +109,7 @@ void sdmmc_dump_regs(sdmmc_t *sdmmc)
sdmmc_debug(sdmmc, "max_current: 0x%08" PRIX32, sdmmc->regs->max_current);
sdmmc_debug(sdmmc, "set_acmd12_error: 0x%04" PRIX16, sdmmc->regs->set_acmd12_error);
sdmmc_debug(sdmmc, "set_int_error: 0x%04" PRIX16, sdmmc->regs->set_int_error);
- sdmmc_debug(sdmmc, "adma_error: 0x%02" PRIX16, sdmmc->regs->adma_error);
+ sdmmc_debug(sdmmc, "adma_error: 0x%02" PRIX8, sdmmc->regs->adma_error);
sdmmc_debug(sdmmc, "adma_address: 0x%08" PRIX32, sdmmc->regs->adma_address);
sdmmc_debug(sdmmc, "upper_adma_address: 0x%08" PRIX32, sdmmc->regs->upper_adma_address);
sdmmc_debug(sdmmc, "preset_for_init: 0x%04" PRIX16, sdmmc->regs->preset_for_init);
@@ -401,16 +394,16 @@ static int sdmmc_clk_set_source(SdmmcControllerNum controller, uint32_t clk_freq
switch (controller)
{
case SDMMC_1:
- car->clk_src[CLK_SOURCE_SDMMC1] = (CLK_SOURCE_FIRST | car_div);
+ car->clk_source_sdmmc1 = (CLK_SOURCE_FIRST | car_div);
break;
case SDMMC_2:
- car->clk_src[CLK_SOURCE_SDMMC2] = (CLK_SOURCE_FIRST | car_div);
+ car->clk_source_sdmmc2 = (CLK_SOURCE_FIRST | car_div);
break;
case SDMMC_3:
- car->clk_src[CLK_SOURCE_SDMMC3] = (CLK_SOURCE_FIRST | car_div);
+ car->clk_source_sdmmc3 = (CLK_SOURCE_FIRST | car_div);
break;
case SDMMC_4:
- car->clk_src[CLK_SOURCE_SDMMC4] = (CLK_SOURCE_FIRST | car_div);
+ car->clk_source_sdmmc4 = (CLK_SOURCE_FIRST | car_div);
break;
}
@@ -551,28 +544,26 @@ static int sdmmc_autocal_config(sdmmc_t *sdmmc, SdmmcBusVoltage voltage)
case SDMMC_3:
switch (voltage) {
case SDMMC_VOLTAGE_1V8:
- sdmmc->regs->auto_cal_config &= ~SDMMC_AUTOCAL_PDPU_CONFIG_MASK;
+ sdmmc->regs->auto_cal_config &= ~(SDMMC_AUTOCAL_PDPU_CONFIG_MASK);
sdmmc->regs->auto_cal_config |= SDMMC_AUTOCAL_PDPU_SDMMC1_1V8;
break;
case SDMMC_VOLTAGE_3V3:
- sdmmc->regs->auto_cal_config &= ~SDMMC_AUTOCAL_PDPU_CONFIG_MASK;
+ sdmmc->regs->auto_cal_config &= ~(SDMMC_AUTOCAL_PDPU_CONFIG_MASK);
sdmmc->regs->auto_cal_config |= SDMMC_AUTOCAL_PDPU_SDMMC1_3V3;
break;
default:
- sdmmc_error(sdmmc, "microsd does not support voltage %d", voltage);
+ sdmmc_error(sdmmc, "uSD does not support requested voltage!");
return 0;
}
break;
-
case SDMMC_2:
case SDMMC_4:
if (voltage != SDMMC_VOLTAGE_1V8) {
- sdmmc_error(sdmmc, "eMMC can only run at 1V8, but sdmmc struct claims voltage %d", voltage);
+ sdmmc_error(sdmmc, "eMMC can only run at 1V8!");
return 0;
}
-
- sdmmc->regs->auto_cal_config &= ~SDMMC_AUTOCAL_PDPU_CONFIG_MASK;
+ sdmmc->regs->auto_cal_config &= ~(SDMMC_AUTOCAL_PDPU_CONFIG_MASK);
sdmmc->regs->auto_cal_config |= SDMMC_AUTOCAL_PDPU_SDMMC4_1V8;
break;
}
@@ -583,8 +574,8 @@ static int sdmmc_autocal_config(sdmmc_t *sdmmc, SdmmcBusVoltage voltage)
/* Run automatic calibration. */
static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage)
{
- bool restart_sd_clock = false;
volatile tegra_padctl_t *padctl = padctl_get_regs();
+ bool restart_sd_clock = false;
/* SD clock is enabled. Disable it and restart later. */
if (sdmmc->is_sd_clk_enabled)
@@ -621,7 +612,7 @@ static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage)
while ((sdmmc->regs->auto_cal_status & SDMMC_AUTOCAL_ACTIVE)) {
/* Ensure we haven't timed out. */
if (get_time_since(timebase) > SDMMC_AUTOCAL_TIMEOUT) {
- sdmmc_error(sdmmc, "autocal timed out!");
+ sdmmc_error(sdmmc, "Auto-calibration timed out!");
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
@@ -644,7 +635,7 @@ static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage)
}
/* Manually clear the autocal enable bit. */
- sdmmc->regs->auto_cal_config &= ~SDMMC_AUTOCAL_ENABLE;
+ sdmmc->regs->auto_cal_config &= ~(SDMMC_AUTOCAL_ENABLE);
break;
}
}
@@ -698,13 +689,9 @@ static int sdmmc_int_clk_enable(sdmmc_t *sdmmc)
/* Use SDMA by default. */
sdmmc->regs->host_control &= ~SDHCI_CTRL_DMA_MASK;
- /* Change to ADMA if requested. */
- if (sdmmc->use_adma && (sdmmc->regs->capabilities & SDHCI_CAN_DO_ADMA2)) {
- if (sdmmc->regs->capabilities & SDHCI_CAN_64BIT)
- sdmmc->regs->host_control |= SDHCI_CTRL_ADMA64;
- else
- sdmmc->regs->host_control |= SDHCI_CTRL_ADMA32;
- }
+ /* Change to ADMA if possible. */
+ if (sdmmc->regs->capabilities & SDHCI_CAN_DO_ADMA2)
+ sdmmc->use_adma = true;
/* Set the timeout to be the maximum value. */
sdmmc->regs->timeout_control &= 0xF0;
@@ -846,9 +833,9 @@ static int sdmmc_dllcal_run(sdmmc_t *sdmmc)
is_timeout = (get_time_since(timebase) > 10000);
}
- /* Clock failed to stabilize. */
+ /* Calibration failed. */
if (is_timeout) {
- sdmmc_error(sdmmc, "ERROR: DLLCAL failed!");
+ sdmmc_error(sdmmc, "DLLCAL failed!");
return 0;
}
@@ -897,20 +884,23 @@ int sdmmc_select_speed(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed)
case SDMMC_SPEED_DDR50:
case SDMMC_SPEED_SDR50:
case SDMMC_SPEED_UNK14:
- sdmmc->regs->host_control2 &= SDHCI_CTRL_UHS_MASK;
- sdmmc->regs->host_control2 |= (SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180);
+ sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_UHS_MASK);
+ sdmmc->regs->host_control2 |= SDHCI_CTRL_UHS_SDR104;
+ sdmmc->regs->host_control2 |= SDHCI_CTRL_VDD_180;
break;
/* 200MHz single-data rate (MMC). */
case SDMMC_SPEED_HS400:
- sdmmc->regs->host_control2 &= SDHCI_CTRL_UHS_MASK;
- sdmmc->regs->host_control2 |= (SDHCI_CTRL_HS400 | SDHCI_CTRL_VDD_180);
+ sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_UHS_MASK);
+ sdmmc->regs->host_control2 |= SDHCI_CTRL_HS400;
+ sdmmc->regs->host_control2 |= SDHCI_CTRL_VDD_180;
break;
/* 25MHz default speed (SD). */
case SDMMC_SPEED_SDR12:
- sdmmc->regs->host_control2 &= SDHCI_CTRL_UHS_MASK;
- sdmmc->regs->host_control2 |= (SDHCI_CTRL_UHS_SDR12 | SDHCI_CTRL_VDD_180);
+ sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_UHS_MASK);
+ sdmmc->regs->host_control2 |= SDHCI_CTRL_UHS_SDR12;
+ sdmmc->regs->host_control2 |= SDHCI_CTRL_VDD_180;
break;
default:
@@ -1201,13 +1191,23 @@ void sdmmc_finish(sdmmc_t *sdmmc)
/* Disable the SD clock. */
sdmmc_disable_sd_clock(sdmmc);
- /* Disable SD power. */
+ /* Disable SDMMC power. */
sdmmc_select_voltage(sdmmc, SDMMC_VOLTAGE_NONE);
+ /* Disable the SD card power. */
+ if (sdmmc->controller == SDMMC_1)
+ {
+ /* Disable GPIO output. */
+ gpio_configure_direction(GPIO_MICROSD_SUPPLY_ENABLE, GPIO_DIRECTION_INPUT);
+
+ /* Power cycle for 100ms without power. */
+ mdelay(100);
+ }
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
- /* Stop the SD clock. */
+ /* Stop the SDMMC clock. */
sdmmc_clk_stop(sdmmc->controller);
/* Clock is no longer running by now. */
@@ -1307,7 +1307,8 @@ static int sdmmc_wait_busy(sdmmc_t *sdmmc)
static void sdmmc_intr_enable(sdmmc_t *sdmmc)
{
/* Set all error bits and enable the relevant interrupts. */
- sdmmc->regs->int_enable |= (0x017F0000 | (TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE | TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE | TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT));
+ sdmmc->regs->int_enable |= 0x017F0000;
+ sdmmc->regs->int_enable |= (TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE | TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE | TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT);
/* Refresh status. */
sdmmc->regs->int_status = sdmmc->regs->int_status;
@@ -1315,11 +1316,15 @@ static void sdmmc_intr_enable(sdmmc_t *sdmmc)
static void sdmmc_intr_disable(sdmmc_t *sdmmc)
{
- /* Clear the interrupt bits. */
- sdmmc->regs->int_enable &= ~(0x017F0000 | (TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE | TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE | TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT));
+ /* Clear all error bits and the interrupts. */
+ sdmmc->regs->int_enable &= ~(0x017F0000);
+ sdmmc->regs->int_enable &= ~(TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE | TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE | TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT);
+
+ /* Refresh status. */
+ sdmmc->regs->int_status = sdmmc->regs->int_status;
}
-static bool sdmmc_intr_check_status(sdmmc_t *sdmmc, u16 status_mask)
+static bool sdmmc_intr_check_status(sdmmc_t *sdmmc, uint16_t status_mask)
{
bool is_masked = (sdmmc->regs->int_status & status_mask);
@@ -1353,8 +1358,8 @@ static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req)
if (blkcnt >= 0xFFFF)
blkcnt = 0xFFFF;
- /* Point to our bounce buffer. */
- uint32_t dma_base_addr = (uint32_t)sdmmc->dma_bounce_buf;
+ /* Use our bounce buffer for SDMA or the request data buffer for ADMA. */
+ uint32_t dma_base_addr = sdmmc->use_adma ? (uint32_t)req->data : (uint32_t)sdmmc->dma_bounce_buf;
/* DMA buffer address must be aligned to 4 bytes. */
if ((4 - (dma_base_addr & 0x03)) & 0x03)
@@ -1408,7 +1413,7 @@ static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req)
static int sdmmc_dma_update(sdmmc_t *sdmmc)
{
- u16 blkcnt = 0;
+ uint16_t blkcnt = 0;
/* Loop until all blocks have been consumed. */
do
@@ -1464,7 +1469,7 @@ static int sdmmc_dma_update(sdmmc_t *sdmmc)
static void sdmmc_set_cmd_flags(sdmmc_t *sdmmc, sdmmc_command_t *cmd, bool is_dma)
{
- u16 cmd_reg_flags = 0;
+ uint16_t cmd_reg_flags = 0;
/* Select length flags based on response type. */
if (!(cmd->flags & SDMMC_RSP_PRESENT))
@@ -1629,8 +1634,8 @@ int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, u
return 0;
}
- /* If this is a write operation, copy the data into our bounce buffer. */
- if (!req->is_read)
+ /* If this is a SDMA write operation, copy the data into our bounce buffer. */
+ if (!sdmmc->use_adma && !req->is_read)
memcpy((void *)sdmmc->dma_bounce_buf, (void *)req->data, req->blksz * req->num_blocks);
}
@@ -1659,8 +1664,8 @@ int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, u
return 0;
}
- /* If this is a read operation, copy the data from our bounce buffer. */
- if (req->is_read)
+ /* If this is a SDMA read operation, copy the data from our bounce buffer. */
+ if (!sdmmc->use_adma && req->is_read)
{
uint32_t dma_data_size = (sdmmc->regs->dma_address - (uint32_t)sdmmc->dma_bounce_buf);
memcpy((void *)req->data, (void *)sdmmc->dma_bounce_buf, dma_data_size);
@@ -1702,6 +1707,9 @@ int sdmmc_switch_voltage(sdmmc_t *sdmmc)
{
volatile tegra_pmc_t *pmc = pmc_get_regs();
+ /* Disable the SD clock. */
+ sdmmc_disable_sd_clock(sdmmc);
+
/* Reconfigure the internal clock. */
if (!sdmmc_select_speed(sdmmc, SDMMC_SPEED_SDR12))
{
@@ -1733,7 +1741,7 @@ int sdmmc_switch_voltage(sdmmc_t *sdmmc)
sdmmc_get_sd_clock_control(sdmmc);
/* Wait a while. */
- udelay(5000);
+ mdelay(5);
/* Host control 2 flag should be set by now. */
if (sdmmc->regs->host_control2 & SDHCI_CTRL_VDD_180)
@@ -1745,7 +1753,7 @@ int sdmmc_switch_voltage(sdmmc_t *sdmmc)
sdmmc_get_sd_clock_control(sdmmc);
/* Wait a while. */
- udelay(1000);
+ mdelay(1);
/* Data level is up. Voltage switching is done.*/
if (sdmmc->regs->present_state & SDHCI_DATA_LVL_MASK)
@@ -1853,7 +1861,7 @@ static int sdmmc_send_tuning(sdmmc_t *sdmmc, uint32_t opcode)
void sdmmc_set_tuning_tap_val(sdmmc_t *sdmmc)
{
- sdmmc->tap_val = ((sdmmc->regs->vendor_clock_cntrl & 0xFF0000) >> 16);
+ sdmmc->tap_val = (sdmmc->regs->vendor_clock_cntrl >> 16);
sdmmc->is_tuning_tap_val_set = true;
}
@@ -1968,4 +1976,4 @@ int sdmmc_abort(sdmmc_t *sdmmc, uint32_t opcode)
sdmmc_disable_sd_clock(sdmmc);
return result;
-}
\ No newline at end of file
+}
diff --git a/fusee/fusee-primary/src/sdmmc/sdmmc_core.h b/fusee/fusee-primary/src/sdmmc/sdmmc_core.h
index 038b80455..ccfab130b 100644
--- a/fusee/fusee-primary/src/sdmmc/sdmmc_core.h
+++ b/fusee/fusee-primary/src/sdmmc/sdmmc_core.h
@@ -1,8 +1,29 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_SDMMC_CORE_H
#define FUSEE_SDMMC_CORE_H
#include "sdmmc_tegra.h"
+/* Bounce buffer */
+#define SDMMC_BOUNCE_BUFFER_ADDRESS 0x90000000
+
/* Present state */
#define SDHCI_CMD_INHIBIT 0x00000001
#define SDHCI_DATA_INHIBIT 0x00000002
@@ -160,15 +181,6 @@
#define SDMMC_RSP_SPI_R5 (SDMMC_RSP_SPI_S1|SDMMC_RSP_SPI_S2)
#define SDMMC_RSP_SPI_R7 (SDMMC_RSP_SPI_S1|SDMMC_RSP_SPI_B4)
-/* Internal logging */
-typedef enum {
- SDMMC_LOG_NONE = 0,
- SDMMC_LOG_ERROR = 1,
- SDMMC_LOG_WARN = 2,
- SDMMC_LOG_INFO = 3,
- SDMMC_LOG_DEBUG = 4
-} SdmmcLogLevel;
-
/* SDMMC controllers */
typedef enum {
SDMMC_1 = 0,
@@ -177,6 +189,14 @@ typedef enum {
SDMMC_4 = 3
} SdmmcControllerNum;
+typedef enum {
+ SDMMC_PARTITION_INVALID = -1,
+ SDMMC_PARTITION_USER = 0,
+ SDMMC_PARTITION_BOOT0 = 1,
+ SDMMC_PARTITION_BOOT1 = 2,
+ SDMMC_PARTITION_RPMB = 3
+} SdmmcPartitionNum;
+
typedef enum {
SDMMC_VOLTAGE_NONE = 0,
SDMMC_VOLTAGE_1V8 = 1,
@@ -277,7 +297,6 @@ int sdmmc_execute_tuning(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed, uint32_t opcod
int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, uint32_t *num_blocks_out);
int sdmmc_load_response(sdmmc_t *sdmmc, uint32_t flags, uint32_t *resp);
int sdmmc_abort(sdmmc_t *sdmmc, uint32_t opcode);
-void sdmmc_set_log_level(SdmmcLogLevel log_level);
void sdmmc_error(sdmmc_t *sdmmc, char *fmt, ...);
void sdmmc_warn(sdmmc_t *sdmmc, char *fmt, ...);
void sdmmc_info(sdmmc_t *sdmmc, char *fmt, ...);
diff --git a/fusee/fusee-primary/src/sdmmc/sdmmc_tegra.h b/fusee/fusee-primary/src/sdmmc/sdmmc_tegra.h
index 7a6c141f7..3b6b4adb0 100644
--- a/fusee/fusee-primary/src/sdmmc/sdmmc_tegra.h
+++ b/fusee/fusee-primary/src/sdmmc/sdmmc_tegra.h
@@ -1,3 +1,21 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_SDMMC_TEGRA_H
#define FUSEE_SDMMC_TEGRA_H
@@ -106,7 +124,7 @@ typedef struct {
uint16_t slot_int_status;
uint16_t host_version;
- /* vendor specific registers */
+ /* Vendor specific registers */
uint32_t vendor_clock_cntrl;
uint32_t vendor_sys_sw_cntrl;
uint32_t vendor_err_intr_status;
@@ -121,12 +139,12 @@ typedef struct {
uint32_t _0x12c[0x20];
uint32_t vendor_io_trim_cntrl;
- /* start of sdmmc2/sdmmc4 only */
+ /* Start of sdmmc2/sdmmc4 only */
uint32_t vendor_dllcal_cfg;
uint32_t vendor_dll_ctrl0;
uint32_t vendor_dll_ctrl1;
uint32_t vendor_dllcal_cfg_sta;
- /* end of sdmmc2/sdmmc4 only */
+ /* End of sdmmc2/sdmmc4 only */
uint32_t vendor_tuning_cntrl0;
uint32_t vendor_tuning_cntrl1;
diff --git a/fusee/fusee-primary/src/sdram.c b/fusee/fusee-primary/src/sdram.c
new file mode 100644
index 000000000..c8e5b9502
--- /dev/null
+++ b/fusee/fusee-primary/src/sdram.c
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "i2c.h"
+#include "mc.h"
+#include "emc.h"
+#include "pmc.h"
+#include "timers.h"
+#include "sysreg.h"
+#include "fuse.h"
+#include "max77620.h"
+#include "sdram_param_t210.h"
+#include "car.h"
+
+#define CONFIG_SDRAM_COMPRESS_CFG
+
+#ifdef CONFIG_SDRAM_COMPRESS_CFG
+#include "lib/lz.h"
+#include "sdram_lz.inl"
+#else
+#include "sdram.inl"
+#endif
+
+static uint32_t _get_sdram_id()
+{
+ return ((fuse_get_reserved_odm(4) & 0x38) >> 3);
+}
+
+static void _sdram_config(const sdram_params_t *params)
+{
+ volatile tegra_car_t *car = car_get_regs();
+ volatile tegra_pmc_t *pmc = pmc_get_regs();
+
+ pmc->io_dpd3_req = (((4 * params->emc_pmc_scratch1 >> 2) + 0x80000000) ^ 0xFFFF) & 0xC000FFFF;
+ udelay(params->pmc_io_dpd3_req_wait);
+
+ uint32_t req = (4 * params->emc_pmc_scratch2 >> 2) + 0x80000000;
+ pmc->io_dpd4_req = (req >> 16 << 16) ^ 0x3FFF0000;
+
+ udelay(params->pmc_io_dpd4_req_wait);
+ pmc->io_dpd4_req = (req ^ 0xFFFF) & 0xC000FFFF;
+ udelay(params->pmc_io_dpd4_req_wait);
+
+ pmc->weak_bias = 0;
+ udelay(1);
+
+ car->pllm_misc1 = params->pllm_setup_control;
+ car->pllm_misc2 = 0;
+ car->pllm_base = ((params->pllm_feedback_divider << 8) | params->pllm_input_divider | 0x40000000 | ((params->pllm_post_divider & 0xFFFF) << 20));
+
+ bool timeout = false;
+ uint32_t wait_end = get_time_us() + 300;
+
+ while (!(car->pllm_base & 0x8000000) && !timeout)
+ {
+ if (get_time_us() >= wait_end)
+ timeout = true;
+ }
+
+ if (!timeout) {
+ udelay(10);
+ }
+
+ car->clk_source_emc = (((params->mc_emem_arb_misc0 >> 11) & 0x10000) | (params->emc_clock_source & 0xFFFEFFFF));
+
+ if (params->emc_clock_source_dll)
+ car->clk_source_emc_dll = params->emc_clock_source_dll;
+
+ if (params->clear_clock2_mc1)
+ car->clk_enb_w_clr = 0x40000000;
+
+ car->clk_enb_h_set = 0x2000001;
+ car->clk_enb_x_set = 0x4000;
+ car->rst_dev_h_clr = 0x2000001;
+
+ MAKE_EMC_REG(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;
+ MAKE_EMC_REG(EMC_PMACRO_VTTGEN_CTRL_1) = params->emc_pmacro_vttgen_ctrl1;
+ MAKE_EMC_REG(EMC_PMACRO_VTTGEN_CTRL_2) = params->emc_pmacro_vttgen_ctrl2;
+ MAKE_EMC_REG(EMC_TIMING_CONTROL) = 1;
+ udelay(1);
+
+ MAKE_EMC_REG(EMC_DBG) = (params->emc_dbg_write_mux << 1) | params->emc_dbg;
+
+ if (params->emc_bct_spare2)
+ *(volatile uint32_t *)params->emc_bct_spare2 = params->emc_bct_spare3;
+
+ MAKE_EMC_REG(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD1_0) = params->emc_cmd_mapping_cmd1_0;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD1_1) = params->emc_cmd_mapping_cmd1_1;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD1_2) = params->emc_cmd_mapping_cmd1_2;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD2_0) = params->emc_cmd_mapping_cmd2_0;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD2_1) = params->emc_cmd_mapping_cmd2_1;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD2_2) = params->emc_cmd_mapping_cmd2_2;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
+ MAKE_EMC_REG(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
+ MAKE_EMC_REG(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
+ MAKE_EMC_REG(EMC_PMACRO_BRICK_MAPPING_1) = params->emc_pmacro_brick_mapping1;
+ MAKE_EMC_REG(EMC_PMACRO_BRICK_MAPPING_2) = params->emc_pmacro_brick_mapping2;
+ MAKE_EMC_REG(EMC_PMACRO_BRICK_CTRL_RFU1) = ((params->emc_pmacro_brick_ctrl_rfu1 & 0x1120112) | 0x1EED1EED);
+ MAKE_EMC_REG(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
+ MAKE_EMC_REG(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
+ MAKE_EMC_REG(EMC_SWIZZLE_RANK0_BYTE0) = params->emc_swizzle_rank0_byte0;
+ MAKE_EMC_REG(EMC_SWIZZLE_RANK0_BYTE1) = params->emc_swizzle_rank0_byte1;
+ MAKE_EMC_REG(EMC_SWIZZLE_RANK0_BYTE2) = params->emc_swizzle_rank0_byte2;
+ MAKE_EMC_REG(EMC_SWIZZLE_RANK0_BYTE3) = params->emc_swizzle_rank0_byte3;
+ MAKE_EMC_REG(EMC_SWIZZLE_RANK1_BYTE0) = params->emc_swizzle_rank1_byte0;
+ MAKE_EMC_REG(EMC_SWIZZLE_RANK1_BYTE1) = params->emc_swizzle_rank1_byte1;
+ MAKE_EMC_REG(EMC_SWIZZLE_RANK1_BYTE2) = params->emc_swizzle_rank1_byte2;
+ MAKE_EMC_REG(EMC_SWIZZLE_RANK1_BYTE3) = params->emc_swizzle_rank1_byte3;
+
+ if (params->emc_bct_spare6)
+ *(volatile uint32_t *)params->emc_bct_spare6 = params->emc_bct_spare7;
+
+ MAKE_EMC_REG(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
+ MAKE_EMC_REG(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;
+ MAKE_EMC_REG(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;
+ MAKE_EMC_REG(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
+ MAKE_EMC_REG(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
+ MAKE_EMC_REG(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
+ MAKE_EMC_REG(EMC_AUTO_CAL_CONFIG5) = params->emc_auto_cal_config5;
+ MAKE_EMC_REG(EMC_AUTO_CAL_CONFIG6) = params->emc_auto_cal_config6;
+ MAKE_EMC_REG(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
+ MAKE_EMC_REG(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
+ MAKE_EMC_REG(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
+ MAKE_EMC_REG(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
+ MAKE_EMC_REG(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
+ MAKE_EMC_REG(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive;
+ MAKE_EMC_REG(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
+ MAKE_EMC_REG(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
+ MAKE_EMC_REG(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
+ MAKE_EMC_REG(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
+ MAKE_EMC_REG(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
+ MAKE_EMC_REG(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;
+ MAKE_EMC_REG(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;
+ MAKE_EMC_REG(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;
+ MAKE_EMC_REG(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
+ MAKE_EMC_REG(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1;
+ MAKE_EMC_REG(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0;
+ MAKE_EMC_REG(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1;
+ MAKE_EMC_REG(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2;
+ MAKE_EMC_REG(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3;
+ MAKE_EMC_REG(EMC_QUSE_BRLSHFT_0) = params->emc_quse_brlshft0;
+ MAKE_EMC_REG(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1;
+ MAKE_EMC_REG(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
+ MAKE_EMC_REG(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
+ MAKE_EMC_REG(EMC_PMACRO_BRICK_CTRL_RFU1) = ((params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF) | 0x1E401E40);
+ MAKE_EMC_REG(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
+ MAKE_EMC_REG(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;
+ MAKE_EMC_REG(EMC_PMACRO_BRICK_CTRL_RFU2) = (params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F);
+ MAKE_EMC_REG(EMC_PMACRO_DATA_BRICK_CTRL_FDPD) = params->emc_pmacro_data_brick_ctrl_fdpd;
+ MAKE_EMC_REG(EMC_PMACRO_BG_BIAS_CTRL_0) = params->emc_pmacro_bg_bias_ctrl0;
+ MAKE_EMC_REG(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl;
+ MAKE_EMC_REG(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl;
+ MAKE_EMC_REG(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl;
+ MAKE_EMC_REG(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode;
+ MAKE_EMC_REG(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
+ MAKE_EMC_REG(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
+ MAKE_EMC_REG(EMC_CFG_3) = params->emc_cfg3;
+ MAKE_EMC_REG(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
+ MAKE_EMC_REG(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
+ MAKE_EMC_REG(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2;
+ MAKE_EMC_REG(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3;
+ MAKE_EMC_REG(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4;
+ MAKE_EMC_REG(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5;
+ MAKE_EMC_REG(EMC_PMACRO_TX_SEL_CLK_SRC_0) = params->emc_pmacro_tx_sel_clk_src0;
+ MAKE_EMC_REG(EMC_PMACRO_TX_SEL_CLK_SRC_1) = params->emc_pmacro_tx_sel_clk_src1;
+ MAKE_EMC_REG(EMC_PMACRO_TX_SEL_CLK_SRC_2) = params->emc_pmacro_tx_sel_clk_src2;
+ MAKE_EMC_REG(EMC_PMACRO_TX_SEL_CLK_SRC_3) = params->emc_pmacro_tx_sel_clk_src3;
+ MAKE_EMC_REG(EMC_PMACRO_TX_SEL_CLK_SRC_4) = params->emc_pmacro_tx_sel_clk_src4;
+ MAKE_EMC_REG(EMC_PMACRO_TX_SEL_CLK_SRC_5) = params->emc_pmacro_tx_sel_clk_src5;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2;
+ MAKE_EMC_REG(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0;
+ MAKE_EMC_REG(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1;
+ MAKE_EMC_REG(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2;
+ MAKE_EMC_REG(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0;
+ MAKE_EMC_REG(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1;
+ MAKE_EMC_REG(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
+ MAKE_EMC_REG(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
+ MAKE_EMC_REG(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK0_3) = params->emc_pmacro_quse_ddll_rank0_3;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK0_4) = params->emc_pmacro_quse_ddll_rank0_4;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK0_5) = params->emc_pmacro_quse_ddll_rank0_5;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK1_0) = params->emc_pmacro_quse_ddll_rank1_0;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK1_1) = params->emc_pmacro_quse_ddll_rank1_1;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK1_2) = params->emc_pmacro_quse_ddll_rank1_2;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK1_3) = params->emc_pmacro_quse_ddll_rank1_3;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4;
+ MAKE_EMC_REG(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;
+ MAKE_EMC_REG(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3) = params->emc_pmacro_ob_ddll_long_dq_rank0_3;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4) = params->emc_pmacro_ob_ddll_long_dq_rank0_4;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5) = params->emc_pmacro_ob_ddll_long_dq_rank0_5;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0) = params->emc_pmacro_ob_ddll_long_dq_rank1_0;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1) = params->emc_pmacro_ob_ddll_long_dq_rank1_1;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2) = params->emc_pmacro_ob_ddll_long_dq_rank1_2;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3) = params->emc_pmacro_ob_ddll_long_dq_rank1_3;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4) = params->emc_pmacro_ob_ddll_long_dq_rank1_4;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5) = params->emc_pmacro_ob_ddll_long_dq_rank1_5;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ob_ddll_long_dqs_rank0_0;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ob_ddll_long_dqs_rank0_1;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ob_ddll_long_dqs_rank0_2;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3) = params->emc_pmacro_ob_ddll_long_dqs_rank0_3;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4) = params->emc_pmacro_ob_ddll_long_dqs_rank0_4;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5) = params->emc_pmacro_ob_ddll_long_dqs_rank0_5;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0) = params->emc_pmacro_ob_ddll_long_dqs_rank1_0;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ob_ddll_long_dqs_rank1_1;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ob_ddll_long_dqs_rank1_2;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ob_ddll_long_dqs_rank1_3;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4) = params->emc_pmacro_ob_ddll_long_dqs_rank1_4;
+ MAKE_EMC_REG(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5) = params->emc_pmacro_ob_ddll_long_dqs_rank1_5;
+ MAKE_EMC_REG(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ib_ddll_long_dqs_rank0_0;
+ MAKE_EMC_REG(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ib_ddll_long_dqs_rank0_1;
+ MAKE_EMC_REG(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ib_ddll_long_dqs_rank0_2;
+ MAKE_EMC_REG(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3) = params->emc_pmacro_ib_ddll_long_dqs_rank0_3;
+ MAKE_EMC_REG(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0) = params->emc_pmacro_ib_ddll_long_dqs_rank1_0;
+ MAKE_EMC_REG(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ib_ddll_long_dqs_rank1_1;
+ MAKE_EMC_REG(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;
+ MAKE_EMC_REG(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1;
+ MAKE_EMC_REG(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2;
+ MAKE_EMC_REG(EMC_PMACRO_COMMON_PAD_TX_CTRL) = ((params->emc_pmacro_common_pad_tx_ctrl & 1) | 0xE);
+
+ if (params->emc_bct_spare4)
+ *(volatile uint32_t *)params->emc_bct_spare4 = params->emc_bct_spare5;
+
+ MAKE_EMC_REG(EMC_TIMING_CONTROL) = 1;
+
+ MAKE_MC_REG(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = params->mc_video_protect_gpu_override0;
+ MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = params->mc_video_protect_gpu_override1;
+ MAKE_MC_REG(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg;
+ MAKE_MC_REG(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0;
+ MAKE_MC_REG(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1;
+ MAKE_MC_REG(MC_EMEM_ADR_CFG_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask;
+ MAKE_MC_REG(MC_EMEM_ADR_CFG_BANK_MASK_0) = params->mc_emem_adr_cfg_bank_mask0;
+ MAKE_MC_REG(MC_EMEM_ADR_CFG_BANK_MASK_1) = params->mc_emem_adr_cfg_bank_mask1;
+ MAKE_MC_REG(MC_EMEM_ADR_CFG_BANK_MASK_2) = params->mc_emem_adr_cfg_bank_mask2;
+ MAKE_MC_REG(MC_EMEM_CFG) = params->mc_emem_cfg;
+ MAKE_MC_REG(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom;
+ MAKE_MC_REG(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi;
+ MAKE_MC_REG(MC_SEC_CARVEOUT_SIZE_MB) = params->mc_sec_carveout_size_mb;
+ MAKE_MC_REG(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom;
+ MAKE_MC_REG(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi;
+ MAKE_MC_REG(MC_MTS_CARVEOUT_SIZE_MB) = params->mc_mts_carveout_size_mb;
+ MAKE_MC_REG(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg;
+ MAKE_MC_REG(MC_EMEM_ARB_OUTSTANDING_REQ) = params->mc_emem_arb_outstanding_req;
+ MAKE_MC_REG(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl;
+ MAKE_MC_REG(MC_EMEM_ARB_REFPB_BANK_CTRL) = params->emc_emem_arb_refpb_bank_ctrl;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r;
+ MAKE_MC_REG(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb;
+ MAKE_MC_REG(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns;
+ MAKE_MC_REG(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers;
+ MAKE_MC_REG(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0;
+ MAKE_MC_REG(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1;
+ MAKE_MC_REG(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2;
+ MAKE_MC_REG(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle;
+ MAKE_MC_REG(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override;
+ MAKE_MC_REG(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1;
+ MAKE_MC_REG(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
+ MAKE_MC_REG(MC_DA_CONFIG0) = params->mc_da_cfg0;
+ MAKE_MC_REG(MC_TIMING_CONTROL) = 1;
+ MAKE_MC_REG(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
+ MAKE_MC_REG(MC_STAT_CONTROL) = params->mc_stat_control;
+
+ MAKE_EMC_REG(EMC_ADR_CFG) = params->emc_adr_cfg;
+ MAKE_EMC_REG(EMC_CLKEN_OVERRIDE) = params->emc_clken_override;
+ MAKE_EMC_REG(EMC_PMACRO_AUTOCAL_CFG_0) = params->emc_pmacro_auto_cal_cfg0;
+ MAKE_EMC_REG(EMC_PMACRO_AUTOCAL_CFG_1) = params->emc_pmacro_auto_cal_cfg1;
+ MAKE_EMC_REG(EMC_PMACRO_AUTOCAL_CFG_2) = params->emc_pmacro_auto_cal_cfg2;
+ MAKE_EMC_REG(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
+ MAKE_EMC_REG(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;
+ MAKE_EMC_REG(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;
+ MAKE_EMC_REG(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
+ udelay(params->emc_auto_cal_wait);
+
+ if (params->emc_bct_spare8)
+ *(volatile uint32_t *)params->emc_bct_spare8 = params->emc_bct_spare9;
+
+ MAKE_EMC_REG(EMC_CFG_2) = params->emc_cfg2;
+ MAKE_EMC_REG(EMC_CFG_PIPE) = params->emc_cfg_pipe;
+ MAKE_EMC_REG(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1;
+ MAKE_EMC_REG(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2;
+ MAKE_EMC_REG(EMC_CMDQ) = params->emc_cmd_q;
+ MAKE_EMC_REG(EMC_MC2EMCQ) = params->emc_mc2emc_q;
+ MAKE_EMC_REG(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt;
+ MAKE_EMC_REG(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2;
+ MAKE_EMC_REG(EMC_FBIO_CFG5) = params->emc_fbio_cfg5;
+ MAKE_EMC_REG(EMC_RC) = params->emc_rc;
+ MAKE_EMC_REG(EMC_RFC) = params->emc_rfc;
+ MAKE_EMC_REG(EMC_RFCPB) = params->emc_rfc_pb;
+ MAKE_EMC_REG(EMC_REFCTRL2) = params->emc_ref_ctrl2;
+ MAKE_EMC_REG(EMC_RFC_SLR) = params->emc_rfc_slr;
+ MAKE_EMC_REG(EMC_RAS) = params->emc_ras;
+ MAKE_EMC_REG(EMC_RP) = params->emc_rp;
+ MAKE_EMC_REG(EMC_TPPD) = params->emc_tppd;
+ MAKE_EMC_REG(EMC_R2R) = params->emc_r2r;
+ MAKE_EMC_REG(EMC_W2W) = params->emc_w2w;
+ MAKE_EMC_REG(EMC_R2W) = params->emc_r2w;
+ MAKE_EMC_REG(EMC_W2R) = params->emc_w2r;
+ MAKE_EMC_REG(EMC_R2P) = params->emc_r2p;
+ MAKE_EMC_REG(EMC_W2P) = params->emc_w2p;
+ MAKE_EMC_REG(EMC_CCDMW) = params->emc_ccdmw;
+ MAKE_EMC_REG(EMC_RD_RCD) = params->emc_rd_rcd;
+ MAKE_EMC_REG(EMC_WR_RCD) = params->emc_wr_rcd;
+ MAKE_EMC_REG(EMC_RRD) = params->emc_rrd;
+ MAKE_EMC_REG(EMC_REXT) = params->emc_rext;
+ MAKE_EMC_REG(EMC_WEXT) = params->emc_wext;
+ MAKE_EMC_REG(EMC_WDV) = params->emc_wdv;
+ MAKE_EMC_REG(EMC_WDV_CHK) = params->emc_wdv_chk;
+ MAKE_EMC_REG(EMC_WSV) = params->emc_wsv;
+ MAKE_EMC_REG(EMC_WEV) = params->emc_wev;
+ MAKE_EMC_REG(EMC_WDV_MASK) = params->emc_wdv_mask;
+ MAKE_EMC_REG(EMC_WS_DURATION) = params->emc_ws_duration;
+ MAKE_EMC_REG(EMC_WE_DURATION) = params->emc_we_duration;
+ MAKE_EMC_REG(EMC_QUSE) = params->emc_quse;
+ MAKE_EMC_REG(EMC_QUSE_WIDTH) = params->emc_quse_width;
+ MAKE_EMC_REG(EMC_IBDLY) = params->emc_ibdly;
+ MAKE_EMC_REG(EMC_OBDLY) = params->emc_obdly;
+ MAKE_EMC_REG(EMC_EINPUT) = params->emc_einput;
+ MAKE_EMC_REG(EMC_EINPUT_DURATION) = params->emc_einput_duration;
+ MAKE_EMC_REG(EMC_PUTERM_EXTRA) = params->emc_puterm_extra;
+ MAKE_EMC_REG(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
+ MAKE_EMC_REG(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;
+ MAKE_EMC_REG(EMC_DBG) = params->emc_dbg;
+ MAKE_EMC_REG(EMC_QRST) = params->emc_qrst;
+ MAKE_EMC_REG(EMC_ISSUE_QRST) = 0;
+ MAKE_EMC_REG(EMC_QSAFE) = params->emc_qsafe;
+ MAKE_EMC_REG(EMC_RDV) = params->emc_rdv;
+ MAKE_EMC_REG(EMC_RDV_MASK) = params->emc_rdv_mask;
+ MAKE_EMC_REG(EMC_RDV_EARLY) = params->emc_rdv_early;
+ MAKE_EMC_REG(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask;
+ MAKE_EMC_REG(EMC_QPOP) = params->emc_qpop;
+ MAKE_EMC_REG(EMC_REFRESH) = params->emc_refresh;
+ MAKE_EMC_REG(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num;
+ MAKE_EMC_REG(EMC_PRE_REFRESH_REQ_CNT) = params->emc_prerefresh_req_cnt;
+ MAKE_EMC_REG(EMC_PDEX2WR) = params->emc_pdex2wr;
+ MAKE_EMC_REG(EMC_PDEX2RD) = params->emc_pdex2rd;
+ MAKE_EMC_REG(EMC_PCHG2PDEN) = params->emc_pchg2pden;
+ MAKE_EMC_REG(EMC_ACT2PDEN) = params->emc_act2pden;
+ MAKE_EMC_REG(EMC_AR2PDEN) = params->emc_ar2pden;
+ MAKE_EMC_REG(EMC_RW2PDEN) = params->emc_rw2pden;
+ MAKE_EMC_REG(EMC_CKE2PDEN) = params->emc_cke2pden;
+ MAKE_EMC_REG(EMC_PDEX2CKE) = params->emc_pdex2che;
+ MAKE_EMC_REG(EMC_PDEX2MRR) = params->emc_pdex2mrr;
+ MAKE_EMC_REG(EMC_TXSR) = params->emc_txsr;
+ MAKE_EMC_REG(EMC_TXSRDLL) = params->emc_txsr_dll;
+ MAKE_EMC_REG(EMC_TCKE) = params->emc_tcke;
+ MAKE_EMC_REG(EMC_TCKESR) = params->emc_tckesr;
+ MAKE_EMC_REG(EMC_TPD) = params->emc_tpd;
+ MAKE_EMC_REG(EMC_TFAW) = params->emc_tfaw;
+ MAKE_EMC_REG(EMC_TRPAB) = params->emc_trpab;
+ MAKE_EMC_REG(EMC_TCLKSTABLE) = params->emc_tclkstable;
+ MAKE_EMC_REG(EMC_TCLKSTOP) = params->emc_tclkstop;
+ MAKE_EMC_REG(EMC_TREFBW) = params->emc_trefbw;
+ MAKE_EMC_REG(EMC_ODT_WRITE) = params->emc_odt_write;
+ MAKE_EMC_REG(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll;
+ MAKE_EMC_REG(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period;
+ MAKE_EMC_REG(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD;
+ MAKE_EMC_REG(EMC_CFG_RSV) = params->emc_cfg_rsv;
+ MAKE_EMC_REG(EMC_PMC_SCRATCH1) = params->emc_pmc_scratch1;
+ MAKE_EMC_REG(EMC_PMC_SCRATCH2) = params->emc_pmc_scratch2;
+ MAKE_EMC_REG(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
+ MAKE_EMC_REG(EMC_ACPD_CONTROL) = params->emc_acpd_control;
+ MAKE_EMC_REG(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
+ MAKE_EMC_REG(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
+
+ if (params->boot_rom_patch_control & 0x80000000)
+ {
+ *(volatile uint32_t *)(4 * (params->boot_rom_patch_control + 0x1C000000)) = params->boot_rom_patch_data;
+ MAKE_MC_REG(MC_TIMING_CONTROL) = 1;
+ }
+
+ pmc->io_dpd3_req = (((4 * params->emc_pmc_scratch1 >> 2) + 0x40000000) & 0xCFFF0000);
+ udelay(params->pmc_io_dpd3_req_wait);
+
+ if (!params->emc_auto_cal_interval)
+ MAKE_EMC_REG(EMC_AUTO_CAL_CONFIG) = (params->emc_auto_cal_config | 0x200);
+
+ MAKE_EMC_REG(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2;
+
+ if (params->emc_zcal_warm_cold_boot_enables & 1)
+ {
+ if (params->memory_type == 2)
+ MAKE_EMC_REG(EMC_ZCAL_WAIT_CNT) = (8 * params->emc_zcal_wait_cnt);
+
+ if (params->memory_type == 3)
+ {
+ MAKE_EMC_REG(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
+ MAKE_EMC_REG(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
+ }
+ }
+
+ MAKE_EMC_REG(EMC_TIMING_CONTROL) = 1;
+ udelay(params->emc_timing_control_wait);
+
+ pmc->ddr_cntrl &= 0xFFF8007F;
+ udelay(params->pmc_ddr_ctrl_wait);
+
+ if (params->memory_type == 2)
+ {
+ MAKE_EMC_REG(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12));
+ udelay(params->emc_pin_extra_wait + 200);
+ MAKE_EMC_REG(EMC_PIN) = (((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256);
+ udelay(params->emc_pin_extra_wait + 500);
+ }
+
+ if (params->memory_type == 3)
+ {
+ MAKE_EMC_REG(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12));
+ udelay(params->emc_pin_extra_wait + 200);
+ MAKE_EMC_REG(EMC_PIN) = (((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256);
+ udelay(params->emc_pin_extra_wait + 2000);
+ }
+
+ MAKE_EMC_REG(EMC_PIN) = (((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 0x101);
+ udelay(params->emc_pin_program_wait);
+
+ if (params->memory_type != 3)
+ MAKE_EMC_REG(EMC_NOP) = ((params->emc_dev_select << 30) + 1);
+
+ if (params->memory_type == 1)
+ udelay(params->emc_pin_extra_wait + 200);
+
+ if (params->memory_type == 3)
+ {
+ if (params->emc_bct_spare10)
+ *(volatile uint32_t *)params->emc_bct_spare10 = params->emc_bct_spare11;
+
+ MAKE_EMC_REG(EMC_MRW2) = params->emc_mrw2;
+ MAKE_EMC_REG(EMC_MRW) = params->emc_mrw1;
+ MAKE_EMC_REG(EMC_MRW3) = params->emc_mrw3;
+ MAKE_EMC_REG(EMC_MRW4) = params->emc_mrw4;
+ MAKE_EMC_REG(EMC_MRW6) = params->emc_mrw6;
+ MAKE_EMC_REG(EMC_MRW14) = params->emc_mrw14;
+ MAKE_EMC_REG(EMC_MRW8) = params->emc_mrw8;
+ MAKE_EMC_REG(EMC_MRW12) = params->emc_mrw12;
+ MAKE_EMC_REG(EMC_MRW9) = params->emc_mrw9;
+ MAKE_EMC_REG(EMC_MRW13) = params->emc_mrw13;
+
+ if (params->emc_zcal_warm_cold_boot_enables & 1)
+ {
+ MAKE_EMC_REG(EMC_ZQ_CAL) = params->emc_zcal_init_dev0;
+ udelay(params->emc_zcal_init_wait);
+ MAKE_EMC_REG(EMC_ZQ_CAL) = (params->emc_zcal_init_dev0 ^ 3);
+
+ if (!(params->emc_dev_select & 2))
+ {
+ MAKE_EMC_REG(EMC_ZQ_CAL) = params->emc_zcal_init_dev1;
+ udelay(params->emc_zcal_init_wait);
+ MAKE_EMC_REG(EMC_ZQ_CAL) = (params->emc_zcal_init_dev1 ^ 3);
+ }
+ }
+ }
+
+ pmc->ddr_cfg = params->pmc_ddr_cfg;
+ if ((params->memory_type - 1) <= 2)
+ {
+ MAKE_EMC_REG(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval;
+ MAKE_EMC_REG(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
+ MAKE_EMC_REG(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
+ }
+
+ if (params->emc_bct_spare12)
+ *(volatile uint32_t *)params->emc_bct_spare12 = params->emc_bct_spare13;
+
+ MAKE_EMC_REG(EMC_TIMING_CONTROL) = 1;
+
+ if (params->emc_extra_refresh_num)
+ MAKE_EMC_REG(EMC_REF) = (((1 << params->emc_extra_refresh_num << 8) - 0xFD) | (params->emc_pin_gpio << 30));
+
+ MAKE_EMC_REG(EMC_REFCTRL) = (params->emc_dev_select | 0x80000000);
+ MAKE_EMC_REG(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
+ MAKE_EMC_REG(EMC_CFG_UPDATE) = params->emc_cfg_update;
+ MAKE_EMC_REG(EMC_CFG) = params->emc_cfg;
+ MAKE_EMC_REG(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq;
+ MAKE_EMC_REG(EMC_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd;
+ MAKE_EMC_REG(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
+ MAKE_EMC_REG(EMC_FBIO_SPARE) = (params->emc_fbio_spare | 2);
+ MAKE_EMC_REG(EMC_TIMING_CONTROL) = 1;
+ MAKE_EMC_REG(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;
+ MAKE_EMC_REG(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;
+
+ AHB_ARBITRATION_XBAR_CTRL_0 = ((AHB_ARBITRATION_XBAR_CTRL_0 & 0xFFFEFFFF) | ((params->ahb_arbitration_xbar_ctrl_meminit_done & 0xFFFF) << 16));
+
+ MAKE_MC_REG(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
+ MAKE_MC_REG(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;
+ MAKE_MC_REG(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;
+ MAKE_MC_REG(MC_EMEM_CFG_ACCESS_CTRL) = 1; /* Disable write access to a bunch of MC registers. */
+}
+
+const void *sdram_get_params()
+{
+ /* TODO: sdram_id should be in [0, 7]. */
+
+#ifdef CONFIG_SDRAM_COMPRESS_CFG
+ uint8_t *buf = (uint8_t *)0x40030000;
+ LZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz));
+ return (const void *)&buf[sizeof(sdram_params_t) * _get_sdram_id()];
+#else
+ return _dram_cfgs[_get_sdram_id()];
+#endif
+}
+
+void sdram_init()
+{
+ volatile tegra_pmc_t *pmc = pmc_get_regs();
+
+ /* TODO: sdram_id should be in [0,4]. */
+ const sdram_params_t *params = (const sdram_params_t *)sdram_get_params();
+
+ uint8_t val = 5;
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD_CFG2, &val, 1);
+ val = 40; /* 40 = (1000 * 1100 - 600000) / 12500 -> 1.1V */
+ i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD1, &val, 1);
+
+ pmc->vddp_sel = params->pmc_vddp_sel;
+ udelay(params->pmc_vddp_sel_wait);
+
+ pmc->ddr_pwr = pmc->ddr_pwr;
+ pmc->no_iopower = params->pmc_no_io_power;
+ pmc->reg_short = params->pmc_reg_short;
+ pmc->ddr_cntrl = params->pmc_ddr_ctrl;
+
+ if (params->emc_bct_spare0)
+ *(volatile uint32_t *)params->emc_bct_spare0 = params->emc_bct_spare1;
+
+ _sdram_config(params);
+}
diff --git a/fusee/fusee-primary/src/sdram.h b/fusee/fusee-primary/src/sdram.h
new file mode 100644
index 000000000..b63f14ba6
--- /dev/null
+++ b/fusee/fusee-primary/src/sdram.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_SDRAM_H_
+#define FUSEE_SDRAM_H_
+
+void sdram_init();
+const void *sdram_get_params();
+void sdram_lp0_save_params(const void *params);
+
+#endif
diff --git a/fusee/fusee-primary/src/sdram.inl b/fusee/fusee-primary/src/sdram.inl
new file mode 100644
index 000000000..845ad1161
--- /dev/null
+++ b/fusee/fusee-primary/src/sdram.inl
@@ -0,0 +1,1152 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ *
+ * 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 .
+ */
+
+static const uint8_t _dram_cfg_0[1896] = {
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+ 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
+ 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
+ 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
+ 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
+ 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
+ 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
+ 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
+ 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
+ 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
+ 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
+ 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
+ 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
+ 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
+ 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
+ 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
+ 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
+ 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
+ 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
+ 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
+ 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00,
+ 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
+ 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
+ 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
+ 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
+ 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
+ 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
+ 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+ 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+ 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
+ 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
+ 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
+ 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t _dram_cfg_1[1896] = {
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+ 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
+ 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
+ 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
+ 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
+ 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
+ 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
+ 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
+ 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
+ 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
+ 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
+ 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
+ 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
+ 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
+ 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
+ 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
+ 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
+ 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
+ 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
+ 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
+ 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00,
+ 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
+ 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
+ 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
+ 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
+ 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
+ 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
+ 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+ 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+ 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
+ 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
+ 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
+ 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t _dram_cfg_2[1896] = {
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+ 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
+ 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
+ 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
+ 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
+ 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
+ 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
+ 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
+ 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
+ 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
+ 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
+ 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
+ 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
+ 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
+ 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
+ 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
+ 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
+ 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
+ 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
+ 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
+ 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00,
+ 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
+ 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
+ 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
+ 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
+ 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
+ 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
+ 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+ 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+ 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
+ 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
+ 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
+ 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t _dram_cfg_3[1896] = {
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+ 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
+ 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
+ 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
+ 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x12, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
+ 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
+ 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
+ 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
+ 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
+ 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
+ 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
+ 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
+ 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
+ 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
+ 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
+ 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
+ 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
+ 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
+ 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
+ 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
+ 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00,
+ 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
+ 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
+ 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
+ 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
+ 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
+ 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
+ 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+ 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+ 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
+ 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
+ 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
+ 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t _dram_cfg_4[1896] = {
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+ 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
+ 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
+ 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
+ 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
+ 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
+ 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
+ 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
+ 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
+ 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
+ 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
+ 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
+ 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
+ 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
+ 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
+ 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
+ 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
+ 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00,
+ 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
+ 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00,
+ 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00,
+ 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
+ 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
+ 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
+ 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
+ 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
+ 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
+ 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+ 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+ 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x0C, 0x00,
+ 0x02, 0x03, 0x0C, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
+ 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x18, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
+ 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t _dram_cfg_5[1896] = {
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+ 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
+ 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
+ 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
+ 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x12, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
+ 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
+ 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
+ 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
+ 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
+ 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
+ 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
+ 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
+ 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
+ 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
+ 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
+ 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
+ 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
+ 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00,
+ 0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00,
+ 0x2F, 0x00, 0x33, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00,
+ 0x2F, 0x00, 0x33, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x15, 0x00, 0x15, 0x00,
+ 0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00, 0x16, 0x00,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
+ 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
+ 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
+ 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
+ 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
+ 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
+ 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+ 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+ 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
+ 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
+ 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
+ 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t _dram_cfg_6[1896] = {
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+ 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, 0x01, 0x70,
+ 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00,
+ 0xA1, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00,
+ 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x0A, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x12, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91,
+ 0xBF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06,
+ 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A,
+ 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23,
+ 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D,
+ 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A,
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08,
+ 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08,
+ 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x0D, 0x0C,
+ 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x04, 0x00, 0x01, 0x08,
+ 0x00, 0x00, 0x11, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0xCC, 0x00,
+ 0x0A, 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00,
+ 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80,
+ 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
+ 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00,
+ 0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00,
+ 0x2F, 0x00, 0x33, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00,
+ 0x2F, 0x00, 0x33, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
+ 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x15, 0x00, 0x15, 0x00,
+ 0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x00, 0x16, 0x00,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40,
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04,
+ 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65,
+ 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32,
+ 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67,
+ 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00,
+ 0xFF, 0xFF, 0xAF, 0x4F, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40,
+ 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00,
+ 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+ 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+ 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0x07, 0x00,
+ 0x02, 0x03, 0x07, 0x00, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E,
+ 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00,
+ 0x28, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02,
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7E, 0x16, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1E, 0x40, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x46, 0x24, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x46, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint32_t *_dram_cfgs[7] = {
+ (const uint32_t *)_dram_cfg_0,
+ (const uint32_t *)_dram_cfg_1,
+ (const uint32_t *)_dram_cfg_2,
+ (const uint32_t *)_dram_cfg_3,
+ (const uint32_t *)_dram_cfg_4,
+ (const uint32_t *)_dram_cfg_5,
+ (const uint32_t *)_dram_cfg_6
+};
diff --git a/fusee/fusee-primary/src/sdram_lp0.c b/fusee/fusee-primary/src/sdram_lp0.c
new file mode 100644
index 000000000..12864e63c
--- /dev/null
+++ b/fusee/fusee-primary/src/sdram_lp0.c
@@ -0,0 +1,1125 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright 2014 Google Inc.
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 CTCaer
+ *
+ * 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.
+ */
+
+#include "pmc.h"
+#include "sdram_param_t210_lp0.h"
+
+/*
+ * This function reads SDRAM parameters from the common BCT format and
+ * writes them into PMC scratch registers (where the BootROM expects them
+ * on LP0 resume).
+ */
+void sdram_lp0_save_params(const void *params)
+{
+ struct sdram_params *sdram = (struct sdram_params *)params;
+ volatile tegra_pmc_t *pmc = pmc_get_regs();
+
+#define pack(src, src_bits, dst, dst_bits) { \
+ uint32_t mask = 0xffffffff >> (31 - ((1 ? src_bits) - (0 ? src_bits))); \
+ dst &= ~(mask << (0 ? dst_bits)); \
+ dst |= ((src >> (0 ? src_bits)) & mask) << (0 ? dst_bits); \
+}
+
+#define s(param, src_bits, pmcreg, dst_bits) \
+ pack(sdram->param, src_bits, pmc->pmcreg, dst_bits)
+
+#define c(value, pmcreg, dst_bits) \
+ pack(value, (1 ? dst_bits) - (0 ? dst_bits) : 0, pmc->pmcreg, dst_bits)
+
+/* 32 bits version of s macro */
+#define s32(param, pmcreg) pmc->pmcreg = sdram->param
+
+/* 32 bits version c macro */
+#define c32(value, pmcreg) pmc->pmcreg = value
+
+ //TODO: pkg1.1 (1.X - 3.X) reads them from MC.
+ // Patch carveout parameters.
+ /*sdram->McGeneralizedCarveout1Bom = 0;
+ sdram->McGeneralizedCarveout1BomHi = 0;
+ sdram->McGeneralizedCarveout1Size128kb = 0;
+ sdram->McGeneralizedCarveout1Access0 = 0;
+ sdram->McGeneralizedCarveout1Access1 = 0;
+ sdram->McGeneralizedCarveout1Access2 = 0;
+ sdram->McGeneralizedCarveout1Access3 = 0;
+ sdram->McGeneralizedCarveout1Access4 = 0;
+ sdram->McGeneralizedCarveout1ForceInternalAccess0 = 0;
+ sdram->McGeneralizedCarveout1ForceInternalAccess1 = 0;
+ sdram->McGeneralizedCarveout1ForceInternalAccess2 = 0;
+ sdram->McGeneralizedCarveout1ForceInternalAccess3 = 0;
+ sdram->McGeneralizedCarveout1ForceInternalAccess4 = 0;
+ sdram->McGeneralizedCarveout1Cfg0 = 0;
+ sdram->McGeneralizedCarveout2Bom = 0x80020000;
+ sdram->McGeneralizedCarveout2BomHi = 0;
+ sdram->McGeneralizedCarveout2Size128kb = 2;
+ sdram->McGeneralizedCarveout2Access0 = 0;
+ sdram->McGeneralizedCarveout2Access1 = 0;
+ sdram->McGeneralizedCarveout2Access2 = 0x3000000;
+ sdram->McGeneralizedCarveout2Access3 = 0;
+ sdram->McGeneralizedCarveout2Access4 = 0x300;
+ sdram->McGeneralizedCarveout2ForceInternalAccess0 = 0;
+ sdram->McGeneralizedCarveout2ForceInternalAccess1 = 0;
+ sdram->McGeneralizedCarveout2ForceInternalAccess2 = 0;
+ sdram->McGeneralizedCarveout2ForceInternalAccess3 = 0;
+ sdram->McGeneralizedCarveout2ForceInternalAccess4 = 0;
+ sdram->McGeneralizedCarveout2Cfg0 = 0x440167E;
+ sdram->McGeneralizedCarveout3Bom = 0;
+ sdram->McGeneralizedCarveout3BomHi = 0;
+ sdram->McGeneralizedCarveout3Size128kb = 0;
+ sdram->McGeneralizedCarveout3Access0 = 0;
+ sdram->McGeneralizedCarveout3Access1 = 0;
+ sdram->McGeneralizedCarveout3Access2 = 0x3000000;
+ sdram->McGeneralizedCarveout3Access3 = 0;
+ sdram->McGeneralizedCarveout3Access4 = 0x300;
+ sdram->McGeneralizedCarveout3ForceInternalAccess0 = 0;
+ sdram->McGeneralizedCarveout3ForceInternalAccess1 = 0;
+ sdram->McGeneralizedCarveout3ForceInternalAccess2 = 0;
+ sdram->McGeneralizedCarveout3ForceInternalAccess3 = 0;
+ sdram->McGeneralizedCarveout3ForceInternalAccess4 = 0;
+ sdram->McGeneralizedCarveout3Cfg0 = 0x4401E7E;
+ sdram->McGeneralizedCarveout4Bom = 0;
+ sdram->McGeneralizedCarveout4BomHi = 0;
+ sdram->McGeneralizedCarveout4Size128kb = 0;
+ sdram->McGeneralizedCarveout4Access0 = 0;
+ sdram->McGeneralizedCarveout4Access1 = 0;
+ sdram->McGeneralizedCarveout4Access2 = 0;
+ sdram->McGeneralizedCarveout4Access3 = 0;
+ sdram->McGeneralizedCarveout4Access4 = 0;
+ sdram->McGeneralizedCarveout4ForceInternalAccess0 = 0;
+ sdram->McGeneralizedCarveout4ForceInternalAccess1 = 0;
+ sdram->McGeneralizedCarveout4ForceInternalAccess2 = 0;
+ sdram->McGeneralizedCarveout4ForceInternalAccess3 = 0;
+ sdram->McGeneralizedCarveout4ForceInternalAccess4 = 0;
+ sdram->McGeneralizedCarveout4Cfg0 = 0x8F;
+ sdram->McGeneralizedCarveout5Bom = 0;
+ sdram->McGeneralizedCarveout5BomHi = 0;
+ sdram->McGeneralizedCarveout5Size128kb = 0;
+ sdram->McGeneralizedCarveout5Access0 = 0;
+ sdram->McGeneralizedCarveout5Access1 = 0;
+ sdram->McGeneralizedCarveout5Access2 = 0;
+ sdram->McGeneralizedCarveout5Access3 = 0;
+ sdram->McGeneralizedCarveout5Access4 = 0;
+ sdram->McGeneralizedCarveout5ForceInternalAccess0 = 0;
+ sdram->McGeneralizedCarveout5ForceInternalAccess1 = 0;
+ sdram->McGeneralizedCarveout5ForceInternalAccess2 = 0;
+ sdram->McGeneralizedCarveout5ForceInternalAccess3 = 0;
+ sdram->McGeneralizedCarveout5ForceInternalAccess4 = 0;
+ sdram->McGeneralizedCarveout5Cfg0 = 0x8F;*/
+
+ //TODO: this is 4.X+ behaviour which seems to work fine for < 4.X.
+ // Patch carveout parameters.
+ sdram->McGeneralizedCarveout1Cfg0 = 0;
+ sdram->McGeneralizedCarveout2Cfg0 = 0;
+ sdram->McGeneralizedCarveout3Cfg0 = 0;
+ sdram->McGeneralizedCarveout4Cfg0 = 0;
+ sdram->McGeneralizedCarveout5Cfg0 = 0;
+
+ // Patch SDRAM parameters.
+ uint32_t t0 = sdram->EmcSwizzleRank0Byte0 << 5 >> 29 > sdram->EmcSwizzleRank0Byte0 << 1 >> 29;
+ uint32_t t1 = (t0 & 0xFFFFFFEF) | ((sdram->EmcSwizzleRank1Byte0 << 5 >> 29 > sdram->EmcSwizzleRank1Byte0 << 1 >> 29) << 4);
+ uint32_t t2 = (t1 & 0xFFFFFFFD) | ((sdram->EmcSwizzleRank0Byte1 << 5 >> 29 > sdram->EmcSwizzleRank0Byte1 << 1 >> 29) << 1);
+ uint32_t t3 = (t2 & 0xFFFFFFDF) | ((sdram->EmcSwizzleRank1Byte1 << 5 >> 29 > sdram->EmcSwizzleRank1Byte1 << 1 >> 29) << 5);
+ uint32_t t4 = (t3 & 0xFFFFFFFB) | ((sdram->EmcSwizzleRank0Byte2 << 5 >> 29 > sdram->EmcSwizzleRank0Byte2 << 1 >> 29) << 2);
+ uint32_t t5 = (t4 & 0xFFFFFFBF) | ((sdram->EmcSwizzleRank1Byte2 << 5 >> 29 > sdram->EmcSwizzleRank1Byte2 << 1 >> 29) << 6);
+ uint32_t t6 = (t5 & 0xFFFFFFF7) | ((sdram->EmcSwizzleRank0Byte3 << 5 >> 29 > sdram->EmcSwizzleRank0Byte3 << 1 >> 29) << 3);
+ uint32_t t7 = (t6 & 0xFFFFFF7F) | ((sdram->EmcSwizzleRank1Byte3 << 5 >> 29 > sdram->EmcSwizzleRank1Byte3 << 1 >> 29) << 7);
+ sdram->SwizzleRankByteEncode = t7;
+ sdram->EmcBctSpare2 = 0x40000DD8;
+ sdram->EmcBctSpare3 = t7;
+
+ s(EmcClockSource, 7:0, scratch6, 15:8);
+ s(EmcClockSourceDll, 7:0, scratch6, 23:16);
+ s(EmcClockSource, 31:29, scratch6, 26:24);
+ s(EmcClockSourceDll, 31:29, scratch6, 29:27);
+ s(EmcClockSourceDll, 11:10, scratch6, 31:30);
+ s(ClkRstControllerPllmMisc2Override, 9:8, scratch7, 1:0);
+ s(ClkRstControllerPllmMisc2Override, 2:1, scratch7, 3:2);
+ s(EmcZqCalLpDdr4WarmBoot, 31:30, scratch7, 5:4);
+ s(EmcClockSource, 15:15, scratch7, 6:6);
+ s(EmcClockSource, 26:26, scratch7, 7:7);
+ s(EmcClockSource, 20:20, scratch7, 8:8);
+ s(EmcClockSource, 19:19, scratch7, 9:9);
+ s(ClkRstControllerPllmMisc2Override, 13:13, scratch7, 10:10);
+ s(ClkRstControllerPllmMisc2Override, 12:12, scratch7, 11:11);
+ s(ClkRstControllerPllmMisc2Override, 11:11, scratch7, 12:12);
+ s(ClkRstControllerPllmMisc2Override, 10:10, scratch7, 13:13);
+ s(ClkRstControllerPllmMisc2Override, 5:5, scratch7, 14:14);
+ s(ClkRstControllerPllmMisc2Override, 4:4, scratch7, 15:15);
+ s(ClkRstControllerPllmMisc2Override, 3:3, scratch7, 16:16);
+ s(ClkRstControllerPllmMisc2Override, 0:0, scratch7, 17:17);
+ s(EmcZqCalLpDdr4WarmBoot, 1:0, scratch7, 19:18);
+ s(EmcZqCalLpDdr4WarmBoot, 4:4, scratch7, 20:20);
+ s(EmcOdtWrite, 5:0, scratch7, 26:21);
+ s(EmcOdtWrite, 11:8, scratch7, 30:27);
+ s(EmcOdtWrite, 31:31, scratch7, 31:31);
+ s(EmcFdpdCtrlCmdNoRamp, 0:0, scratch13, 30:30);
+ s(EmcCfgPipeClk, 0:0, scratch13, 31:31);
+ s(McEmemArbMisc2, 0:0, scratch14, 30:30);
+ s(McDaCfg0, 0:0, scratch14, 31:31);
+ s(EmcQRst, 6:0, scratch15, 26:20);
+ s(EmcQRst, 20:16, scratch15, 31:27);
+ s(EmcPmacroCmdTxDrv, 5:0, scratch16, 25:20);
+ s(EmcPmacroCmdTxDrv, 13:8, scratch16, 31:26);
+ s(EmcPmacroAutocalCfg0, 2:0, scratch17, 22:20);
+ s(EmcPmacroAutocalCfg0, 10:8, scratch17, 25:23);
+ s(EmcPmacroAutocalCfg0, 18:16, scratch17, 28:26);
+ s(EmcPmacroAutocalCfg0, 26:24, scratch17, 31:29);
+ s(EmcPmacroAutocalCfg1, 2:0, scratch18, 22:20);
+ s(EmcPmacroAutocalCfg1, 10:8, scratch18, 25:23);
+ s(EmcPmacroAutocalCfg1, 18:16, scratch18, 28:26);
+ s(EmcPmacroAutocalCfg1, 26:24, scratch18, 31:29);
+ s(EmcPmacroAutocalCfg2, 2:0, scratch19, 22:20);
+ s(EmcPmacroAutocalCfg2, 10:8, scratch19, 25:23);
+ s(EmcPmacroAutocalCfg2, 18:16, scratch19, 28:26);
+ s(EmcPmacroAutocalCfg2, 26:24, scratch19, 31:29);
+ s32(EmcCfgRsv,scratch22);
+ s32(EmcAutoCalConfig, scratch23);
+ s32(EmcAutoCalVrefSel0, scratch24);
+ s32(EmcPmacroBrickCtrlRfu1, scratch25);
+ s32(EmcPmacroBrickCtrlRfu2, scratch26);
+ s32(EmcPmcScratch1, scratch27);
+ s32(EmcPmcScratch2, scratch28);
+ s32(EmcPmcScratch3, scratch29);
+ s32(McEmemArbDaTurns, scratch30);
+ s(EmcFbioSpare, 31:24, scratch58, 7:0);
+ s(EmcFbioSpare, 23:16, scratch58, 15:8);
+ s(EmcFbioSpare, 15:8, scratch58, 23:16);
+ s(EmcFbioSpare, 7:2, scratch58, 29:24);
+ s(EmcFbioSpare, 0:0, scratch58, 30:30);
+ s(EmcDllCfg0, 29:0, scratch59, 29:0);
+ s(EmcPmacroDdllBypass, 11:0, scratch60, 11:0);
+ s(EmcPmacroDdllBypass, 27:13, scratch60, 26:12);
+ s(EmcPmacroDdllBypass, 31:29, scratch60, 29:27);
+ s(McEmemArbMisc0, 14:0, scratch61, 14:0);
+ s(McEmemArbMisc0, 30:16, scratch61, 29:15);
+ s(EmcFdpdCtrlCmd, 16:0, scratch62, 16:0);
+ s(EmcFdpdCtrlCmd, 31:20, scratch62, 28:17);
+ s(EmcAutoCalConfig2, 27:0, scratch63, 27:0);
+ s(EmcBurstRefreshNum, 3:0, scratch63, 31:28);
+ s(EmcPmacroZctrl, 27:0, scratch64, 27:0);
+ s(EmcTppd, 3:0, scratch64, 31:28);
+ s(EmcCfgDigDll, 10:0, scratch65, 10:0);
+ s(EmcCfgDigDll, 25:12, scratch65, 24:11);
+ s(EmcCfgDigDll, 27:27, scratch65, 25:25);
+ s(EmcCfgDigDll, 31:30, scratch65, 27:26);
+ s(EmcR2r, 3:0, scratch65, 31:28);
+ s(EmcFdpdCtrlDq, 16:0, scratch66, 16:0);
+ s(EmcFdpdCtrlDq, 28:20, scratch66, 25:17);
+ s(EmcFdpdCtrlDq, 31:30, scratch66, 27:26);
+ s(EmcW2w, 3:0, scratch66, 31:28);
+ s(EmcPmacroTxPwrd4, 13:0, scratch67, 13:0);
+ s(EmcPmacroTxPwrd4, 29:16, scratch67, 27:14);
+ s(EmcPmacroCommonPadTxCtrl, 3:0, scratch67, 31:28);
+ s(EmcPmacroTxPwrd5, 13:0, scratch68, 13:0);
+ s(EmcPmacroTxPwrd5, 29:16, scratch68, 27:14);
+ s(EmcPmacroDdllPwrd0, 4:0, scratch69, 4:0);
+ s(EmcPmacroDdllPwrd0, 12:6, scratch69, 11:5);
+ s(EmcPmacroDdllPwrd0, 20:14, scratch69, 18:12);
+ s(EmcPmacroDdllPwrd0, 28:22, scratch69, 25:19);
+ s(EmcPmacroDdllPwrd0, 31:30, scratch69, 27:26);
+ s(EmcCfg, 4:4, scratch69, 31:31);
+ s(EmcPmacroDdllPwrd1, 4:0, scratch70, 4:0);
+ s(EmcPmacroDdllPwrd1, 12:6, scratch70, 11:5);
+ s(EmcPmacroDdllPwrd1, 20:14, scratch70, 18:12);
+ s(EmcPmacroDdllPwrd1, 28:22, scratch70, 25:19);
+ s(EmcPmacroDdllPwrd1, 31:30, scratch70, 27:26);
+ s(EmcCfg, 5:5, scratch70, 31:31);
+ s(EmcPmacroDdllPwrd2, 4:0, scratch71, 4:0);
+ s(EmcPmacroDdllPwrd2, 12:6, scratch71, 11:5);
+ s(EmcPmacroDdllPwrd2, 20:14, scratch71, 18:12);
+ s(EmcPmacroDdllPwrd2, 28:22, scratch71, 25:19);
+ s(EmcPmacroDdllPwrd2, 31:30, scratch71, 27:26);
+ s(EmcFbioCfg5, 23:20, scratch71, 31:28);
+ s(EmcPmacroIbVrefDq_0, 6:0, scratch72, 6:0);
+ s(EmcPmacroIbVrefDq_0, 14:8, scratch72, 13:7);
+ s(EmcPmacroIbVrefDq_0, 22:16, scratch72, 20:14);
+ s(EmcPmacroIbVrefDq_0, 30:24, scratch72, 27:21);
+ s(EmcFbioCfg5, 15:13, scratch72, 30:28);
+ s(EmcCfg, 6:6, scratch72, 31:31);
+ s(EmcPmacroIbVrefDq_1, 6:0, scratch73, 6:0);
+ s(EmcPmacroIbVrefDq_1, 14:8, scratch73, 13:7);
+ s(EmcPmacroIbVrefDq_1, 22:16, scratch73, 20:14);
+ s(EmcPmacroIbVrefDq_1, 30:24, scratch73, 27:21);
+ s(EmcCfg2, 5:3, scratch73, 30:28);
+ s(EmcCfg, 7:7, scratch73, 31:31);
+ s(EmcPmacroIbVrefDqs_0, 6:0, scratch74, 6:0);
+ s(EmcPmacroIbVrefDqs_0, 14:8, scratch74, 13:7);
+ s(EmcPmacroIbVrefDqs_0, 22:16, scratch74, 20:14);
+ s(EmcPmacroIbVrefDqs_0, 30:24, scratch74, 27:21);
+ s(EmcCfg, 17:16, scratch74, 29:28);
+ s(EmcFbioCfg5, 1:0, scratch74, 31:30);
+ s(EmcPmacroIbVrefDqs_1, 6:0, scratch75, 6:0);
+ s(EmcPmacroIbVrefDqs_1, 14:8, scratch75, 13:7);
+ s(EmcPmacroIbVrefDqs_1, 22:16, scratch75, 20:14);
+ s(EmcPmacroIbVrefDqs_1, 30:24, scratch75, 27:21);
+ s(EmcFbioCfg5, 3:2, scratch75, 29:28);
+ s(EmcCfg2, 27:26, scratch75, 31:30);
+ s(EmcPmacroDdllShortCmd_0, 6:0, scratch76, 6:0);
+ s(EmcPmacroDdllShortCmd_0, 14:8, scratch76, 13:7);
+ s(EmcPmacroDdllShortCmd_0, 22:16, scratch76, 20:14);
+ s(EmcPmacroDdllShortCmd_0, 30:24, scratch76, 27:21);
+ s(EmcPmacroCmdPadTxCtrl, 3:2, scratch76, 29:28);
+ s(EmcPmacroCmdPadTxCtrl, 7:6, scratch76, 31:30);
+ s(EmcPmacroDdllShortCmd_1, 6:0, scratch77, 6:0);
+ s(EmcPmacroDdllShortCmd_1, 14:8, scratch77, 13:7);
+ s(EmcPmacroDdllShortCmd_1, 22:16, scratch77, 20:14);
+ s(EmcPmacroDdllShortCmd_1, 30:24, scratch77, 27:21);
+ s(EmcPmacroCmdPadTxCtrl, 11:10, scratch77, 29:28);
+ s(EmcPmacroCmdPadTxCtrl, 15:14, scratch77, 31:30);
+ s(EmcAutoCalChannel, 5:0, scratch78, 5:0);
+ s(EmcAutoCalChannel, 11:8, scratch78, 9:6);
+ s(EmcAutoCalChannel, 27:16, scratch78, 21:10);
+ s(EmcAutoCalChannel, 31:29, scratch78, 24:22);
+ s(EmcConfigSampleDelay, 6:0, scratch78, 31:25);
+ s(EmcPmacroRxTerm, 5:0, scratch79, 5:0);
+ s(EmcPmacroRxTerm, 13:8, scratch79, 11:6);
+ s(EmcPmacroRxTerm, 21:16, scratch79, 17:12);
+ s(EmcPmacroRxTerm, 29:24, scratch79, 23:18);
+ s(EmcRc, 7:0, scratch79, 31:24);
+ s(EmcPmacroDqTxDrv, 5:0, scratch80, 5:0);
+ s(EmcPmacroDqTxDrv, 13:8, scratch80, 11:6);
+ s(EmcPmacroDqTxDrv, 21:16, scratch80, 17:12);
+ s(EmcPmacroDqTxDrv, 29:24, scratch80, 23:18);
+ s(EmcSelDpdCtrl, 5:2, scratch80, 27:24);
+ s(EmcSelDpdCtrl, 8:8, scratch80, 28:28);
+ s(EmcSelDpdCtrl, 18:16, scratch80, 31:29);
+ s(EmcPmacroCaTxDrv, 5:0, scratch81, 5:0);
+ s(EmcPmacroCaTxDrv, 13:8, scratch81, 11:6);
+ s(EmcPmacroCaTxDrv, 21:16, scratch81, 17:12);
+ s(EmcPmacroCaTxDrv, 29:24, scratch81, 23:18);
+ s(EmcObdly, 5:0, scratch81, 29:24);
+ s(EmcObdly, 29:28, scratch81, 31:30);
+ s(EmcZcalInterval, 23:10, scratch82, 13:0);
+ s(EmcZcalInterval, 9:0, scratch82, 23:14);
+ s(EmcPmacroCmdRxTermMode, 1:0, scratch82, 25:24);
+ s(EmcPmacroCmdRxTermMode, 5:4, scratch82, 27:26);
+ s(EmcPmacroCmdRxTermMode, 9:8, scratch82, 29:28);
+ s(EmcPmacroCmdRxTermMode, 13:12, scratch82, 31:30);
+ s(EmcDataBrlshft0, 23:0, scratch83, 23:0);
+ s(EmcPmacroDataRxTermMode, 1:0, scratch83, 25:24);
+ s(EmcPmacroDataRxTermMode, 5:4, scratch83, 27:26);
+ s(EmcPmacroDataRxTermMode, 9:8, scratch83, 29:28);
+ s(EmcPmacroDataRxTermMode, 13:12, scratch83, 31:30);
+ s(EmcDataBrlshft1, 23:0, scratch84, 23:0);
+ s(McEmemArbTimingRc, 7:0, scratch84, 31:24);
+ s(EmcDqsBrlshft0, 23:0, scratch85, 23:0);
+ s(McEmemArbRsv, 7:0, scratch85, 31:24);
+ s(EmcDqsBrlshft1, 23:0, scratch86, 23:0);
+ s(EmcCfgPipe2, 11:0, scratch87, 11:0);
+ s(EmcCfgPipe2, 27:16, scratch87, 23:12);
+ s(EmcCfgPipe1, 11:0, scratch88, 11:0);
+ s(EmcCfgPipe1, 27:16, scratch88, 23:12);
+ s(EmcPmacroCmdCtrl0, 5:0, scratch89, 5:0);
+ s(EmcPmacroCmdCtrl0, 13:8, scratch89, 11:6);
+ s(EmcPmacroCmdCtrl0, 21:16, scratch89, 17:12);
+ s(EmcPmacroCmdCtrl0, 29:24, scratch89, 23:18);
+ s(EmcPmacroCmdCtrl1, 5:0, scratch90, 5:0);
+ s(EmcPmacroCmdCtrl1, 13:8, scratch90, 11:6);
+ s(EmcPmacroCmdCtrl1, 21:16, scratch90, 17:12);
+ s(EmcPmacroCmdCtrl1, 29:24, scratch90, 23:18);
+ s(EmcRas, 6:0, scratch90, 30:24);
+ s(EmcCfg, 8:8, scratch90, 31:31);
+ s(EmcPmacroVttgenCtrl2, 23:0, scratch91, 23:0);
+ s(EmcW2p, 6:0, scratch91, 30:24);
+ s(EmcCfg, 9:9, scratch91, 31:31);
+ s(EmcPmacroCmdPadRxCtrl, 2:0, scratch92, 2:0);
+ s(EmcPmacroCmdPadRxCtrl, 5:4, scratch92, 4:3);
+ s(EmcPmacroCmdPadRxCtrl, 10:8, scratch92, 7:5);
+ s(EmcPmacroCmdPadRxCtrl, 22:12, scratch92, 18:8);
+ s(EmcPmacroCmdPadRxCtrl, 28:24, scratch92, 23:19);
+ s(EmcQSafe, 6:0, scratch92, 30:24);
+ s(EmcCfg, 18:18, scratch92, 31:31);
+ s(EmcPmacroDataPadRxCtrl, 2:0, scratch93, 2:0);
+ s(EmcPmacroDataPadRxCtrl, 5:4, scratch93, 4:3);
+ s(EmcPmacroDataPadRxCtrl, 10:8, scratch93, 7:5);
+ s(EmcPmacroDataPadRxCtrl, 22:12, scratch93, 18:8);
+ s(EmcPmacroDataPadRxCtrl, 28:24, scratch93, 23:19);
+ s(EmcRdv, 6:0, scratch93, 30:24);
+ s(EmcCfg, 21:21, scratch93, 31:31);
+ s(McEmemArbDaCovers, 23:0, scratch94, 23:0);
+ s(EmcRw2Pden, 6:0, scratch94, 30:24);
+ s(EmcCfg, 22:22, scratch94, 31:31);
+ s(EmcPmacroCmdCtrl2, 5:0, scratch95, 5:0);
+ s(EmcPmacroCmdCtrl2, 13:9, scratch95, 10:6);
+ s(EmcPmacroCmdCtrl2, 21:16, scratch95, 16:11);
+ s(EmcPmacroCmdCtrl2, 29:24, scratch95, 22:17);
+ s(EmcRfcPb, 8:0, scratch95, 31:23);
+ s(EmcPmacroQuseDdllRank0_0, 10:0, scratch96, 10:0);
+ s(EmcPmacroQuseDdllRank0_0, 26:16, scratch96, 21:11);
+ s(EmcCfgUpdate, 2:0, scratch96, 24:22);
+ s(EmcCfgUpdate, 10:8, scratch96, 27:25);
+ s(EmcCfgUpdate, 31:28, scratch96, 31:28);
+ s(EmcPmacroQuseDdllRank0_1, 10:0, scratch97, 10:0);
+ s(EmcPmacroQuseDdllRank0_1, 26:16, scratch97, 21:11);
+ s(EmcRfc, 9:0, scratch97, 31:22);
+ s(EmcPmacroQuseDdllRank0_2, 10:0, scratch98, 10:0);
+ s(EmcPmacroQuseDdllRank0_2, 26:16, scratch98, 21:11);
+ s(EmcTxsr, 9:0, scratch98, 31:22);
+ s(EmcPmacroQuseDdllRank0_3, 10:0, scratch99, 10:0);
+ s(EmcPmacroQuseDdllRank0_3, 26:16, scratch99, 21:11);
+ s(EmcMc2EmcQ, 2:0, scratch99, 24:22);
+ s(EmcMc2EmcQ, 10:8, scratch99, 27:25);
+ s(EmcMc2EmcQ, 27:24, scratch99, 31:28);
+ s(EmcPmacroQuseDdllRank0_4, 10:0, scratch100, 10:0);
+ s(EmcPmacroQuseDdllRank0_4, 26:16, scratch100, 21:11);
+ s(McEmemArbRing1Throttle, 4:0, scratch100, 26:22);
+ s(McEmemArbRing1Throttle, 20:16, scratch100, 31:27);
+ s(EmcPmacroQuseDdllRank0_5, 10:0, scratch101, 10:0);
+ s(EmcPmacroQuseDdllRank0_5, 26:16, scratch101, 21:11);
+ s(EmcPmacroQuseDdllRank1_0, 10:0, scratch102, 10:0);
+ s(EmcPmacroQuseDdllRank1_0, 26:16, scratch102, 21:11);
+ s(EmcAr2Pden, 8:0, scratch102, 30:22);
+ s(EmcCfg, 23:23, scratch102, 31:31);
+ s(EmcPmacroQuseDdllRank1_1, 10:0, scratch103, 10:0);
+ s(EmcPmacroQuseDdllRank1_1, 26:16, scratch103, 21:11);
+ s(EmcRfcSlr, 8:0, scratch103, 30:22);
+ s(EmcCfg, 24:24, scratch103, 31:31);
+ s(EmcPmacroQuseDdllRank1_2, 10:0, scratch104, 10:0);
+ s(EmcPmacroQuseDdllRank1_2, 26:16, scratch104, 21:11);
+ s(EmcIbdly, 6:0, scratch104, 28:22);
+ s(EmcIbdly, 29:28, scratch104, 30:29);
+ s(EmcCfg, 25:25, scratch104, 31:31);
+ s(EmcPmacroQuseDdllRank1_3, 10:0, scratch105, 10:0);
+ s(EmcPmacroQuseDdllRank1_3, 26:16, scratch105, 21:11);
+ s(McEmemArbTimingRFCPB, 8:0, scratch105, 30:22);
+ s(EmcCfg, 26:26, scratch105, 31:31);
+ s(EmcPmacroQuseDdllRank1_4, 10:0, scratch106, 10:0);
+ s(EmcPmacroQuseDdllRank1_4, 26:16, scratch106, 21:11);
+ s(EmcTfaw, 6:0, scratch106, 28:22);
+ s(EmcPmacroDataPadTxCtrl, 3:2, scratch106, 30:29);
+ s(EmcCfg, 28:28, scratch106, 31:31);
+ s(EmcPmacroQuseDdllRank1_5, 10:0, scratch107, 10:0);
+ s(EmcPmacroQuseDdllRank1_5, 26:16, scratch107, 21:11);
+ s(EmcTClkStable, 6:0, scratch107, 28:22);
+ s(EmcPmacroDataPadTxCtrl, 7:6, scratch107, 30:29);
+ s(EmcCfg, 29:29, scratch107, 31:31);
+ s(EmcPmacroObDdllLongDqRank0_0, 10:0, scratch108, 10:0);
+ s(EmcPmacroObDdllLongDqRank0_0, 26:16, scratch108, 21:11);
+ s(EmcPdex2Mrr, 6:0, scratch108, 28:22);
+ s(EmcPmacroDataPadTxCtrl, 11:10, scratch108, 30:29);
+ s(EmcCfg, 30:30, scratch108, 31:31);
+ s(EmcPmacroObDdllLongDqRank0_1, 10:0, scratch109, 10:0);
+ s(EmcPmacroObDdllLongDqRank0_1, 26:16, scratch109, 21:11);
+ s(EmcRdvMask, 6:0, scratch109, 28:22);
+ s(EmcPmacroDataPadTxCtrl, 15:14, scratch109, 30:29);
+ s(EmcCfg, 31:31, scratch109, 31:31);
+ s(EmcPmacroObDdllLongDqRank0_2, 10:0, scratch110, 10:0);
+ s(EmcPmacroObDdllLongDqRank0_2, 26:16, scratch110, 21:11);
+ s(EmcRdvEarlyMask, 6:0, scratch110, 28:22);
+ s(EmcFbioCfg5, 4:4, scratch110, 29:29);
+ s(EmcFbioCfg5, 8:8, scratch110, 30:30);
+ s(EmcFbioCfg5, 10:10, scratch110, 31:31);
+ s(EmcPmacroObDdllLongDqRank0_3, 10:0, scratch111, 10:0);
+ s(EmcPmacroObDdllLongDqRank0_3, 26:16, scratch111, 21:11);
+ s(EmcRdvEarly, 6:0, scratch111, 28:22);
+ s(EmcFbioCfg5, 12:12, scratch111, 29:29);
+ s(EmcFbioCfg5, 25:24, scratch111, 31:30);
+ s(EmcPmacroObDdllLongDqRank0_4, 10:0, scratch112, 10:0);
+ s(EmcPmacroObDdllLongDqRank0_4, 26:16, scratch112, 21:11);
+ s(EmcPmacroDdllShortCmd_2, 6:0, scratch112, 28:22);
+ s(EmcFbioCfg5, 28:26, scratch112, 31:29);
+ s(EmcPmacroObDdllLongDqRank0_5, 10:0, scratch113, 10:0);
+ s(EmcPmacroObDdllLongDqRank0_5, 26:16, scratch113, 21:11);
+ s(McEmemArbTimingRp, 6:0, scratch113, 28:22);
+ s(EmcFbioCfg5, 31:30, scratch113, 30:29);
+ s(EmcCfg2, 0:0, scratch113, 31:31);
+ s(EmcPmacroObDdllLongDqRank1_0, 10:0, scratch114, 10:0);
+ s(EmcPmacroObDdllLongDqRank1_0, 26:16, scratch114, 21:11);
+ s(McEmemArbTimingRas, 6:0, scratch114, 28:22);
+ s(EmcCfg2, 2:1, scratch114, 30:29);
+ s(EmcCfg2, 7:7, scratch114, 31:31);
+ s(EmcPmacroObDdllLongDqRank1_1, 10:0, scratch115, 10:0);
+ s(EmcPmacroObDdllLongDqRank1_1, 26:16, scratch115, 21:11);
+ s(McEmemArbTimingFaw, 6:0, scratch115, 28:22);
+ s(EmcCfg2, 11:10, scratch115, 30:29);
+ s(EmcCfg2, 14:14, scratch115, 31:31);
+ s(EmcPmacroObDdllLongDqRank1_2, 10:0, scratch123, 10:0);
+ s(EmcPmacroObDdllLongDqRank1_2, 26:16, scratch123, 21:11);
+ s(McEmemArbTimingRap2Pre, 6:0, scratch123, 28:22);
+ s(EmcCfg2, 16:15, scratch123, 30:29);
+ s(EmcCfg2, 20:20, scratch123, 31:31);
+ s(EmcPmacroObDdllLongDqRank1_3, 10:0, scratch124, 10:0);
+ s(EmcPmacroObDdllLongDqRank1_3, 26:16, scratch124, 21:11);
+ s(McEmemArbTimingWap2Pre, 6:0, scratch124, 28:22);
+ s(EmcCfg2, 24:22, scratch124, 31:29);
+ s(EmcPmacroObDdllLongDqRank1_4, 10:0, scratch125, 10:0);
+ s(EmcPmacroObDdllLongDqRank1_4, 26:16, scratch125, 21:11);
+ s(McEmemArbTimingR2W, 6:0, scratch125, 28:22);
+ s(EmcCfg2, 25:25, scratch125, 29:29);
+ s(EmcCfg2, 29:28, scratch125, 31:30);
+ s(EmcPmacroObDdllLongDqRank1_5, 10:0, scratch126, 10:0);
+ s(EmcPmacroObDdllLongDqRank1_5, 26:16, scratch126, 21:11);
+ s(McEmemArbTimingW2R, 6:0, scratch126, 28:22);
+ s(EmcCfg2, 31:30, scratch126, 30:29);
+ s(EmcCfgPipe, 0:0, scratch126, 31:31);
+ s(EmcPmacroObDdllLongDqsRank0_0, 10:0, scratch127, 10:0);
+ s(EmcPmacroObDdllLongDqsRank0_0, 26:16, scratch127, 21:11);
+ s(EmcRp, 5:0, scratch127, 27:22);
+ s(EmcCfgPipe, 4:1, scratch127, 31:28);
+ s(EmcPmacroObDdllLongDqsRank0_1, 10:0, scratch128, 10:0);
+ s(EmcPmacroObDdllLongDqsRank0_1, 26:16, scratch128, 21:11);
+ s(EmcR2w, 5:0, scratch128, 27:22);
+ s(EmcCfgPipe, 8:5, scratch128, 31:28);
+ s(EmcPmacroObDdllLongDqsRank0_2, 10:0, scratch129, 10:0);
+ s(EmcPmacroObDdllLongDqsRank0_2, 26:16, scratch129, 21:11);
+ s(EmcW2r, 5:0, scratch129, 27:22);
+ s(EmcCfgPipe, 11:9, scratch129, 30:28);
+ s(EmcCfgPipe, 16:16, scratch129, 31:31);
+ s(EmcPmacroObDdllLongDqsRank0_3, 10:0, scratch130, 10:0);
+ s(EmcPmacroObDdllLongDqsRank0_3, 26:16, scratch130, 21:11);
+ s(EmcR2p, 5:0, scratch130, 27:22);
+ s(EmcCfgPipe, 20:17, scratch130, 31:28);
+ s(EmcPmacroObDdllLongDqsRank0_4, 10:0, scratch131, 10:0);
+ s(EmcPmacroObDdllLongDqsRank0_4, 26:16, scratch131, 21:11);
+ s(EmcCcdmw, 5:0, scratch131, 27:22);
+ s(EmcCfgPipe, 24:21, scratch131, 31:28);
+ s(EmcPmacroObDdllLongDqsRank0_5, 10:0, scratch132, 10:0);
+ s(EmcPmacroObDdllLongDqsRank0_5, 26:16, scratch132, 21:11);
+ s(EmcRdRcd, 5:0, scratch132, 27:22);
+ s(EmcCfgPipe, 27:25, scratch132, 30:28);
+ s(EmcPmacroTxPwrd0, 0:0, scratch132, 31:31);
+ s(EmcPmacroObDdllLongDqsRank1_0, 10:0, scratch133, 10:0);
+ s(EmcPmacroObDdllLongDqsRank1_0, 26:16, scratch133, 21:11);
+ s(EmcWrRcd, 5:0, scratch133, 27:22);
+ s(EmcPmacroTxPwrd0, 4:1, scratch133, 31:28);
+ s(EmcPmacroObDdllLongDqsRank1_1, 10:0, scratch134, 10:0);
+ s(EmcPmacroObDdllLongDqsRank1_1, 26:16, scratch134, 21:11);
+ s(EmcWdv, 5:0, scratch134, 27:22);
+ s(EmcPmacroTxPwrd0, 8:5, scratch134, 31:28);
+ s(EmcPmacroObDdllLongDqsRank1_2, 10:0, scratch135, 10:0);
+ s(EmcPmacroObDdllLongDqsRank1_2, 26:16, scratch135, 21:11);
+ s(EmcQUse, 5:0, scratch135, 27:22);
+ s(EmcPmacroTxPwrd0, 12:9, scratch135, 31:28);
+ s(EmcPmacroObDdllLongDqsRank1_3, 10:0, scratch136, 10:0);
+ s(EmcPmacroObDdllLongDqsRank1_3, 26:16, scratch136, 21:11);
+ s(EmcPdEx2Wr, 5:0, scratch136, 27:22);
+ s(EmcPmacroTxPwrd0, 13:13, scratch136, 28:28);
+ s(EmcPmacroTxPwrd0, 18:16, scratch136, 31:29);
+ s(EmcPmacroObDdllLongDqsRank1_4, 10:0, scratch137, 10:0);
+ s(EmcPmacroObDdllLongDqsRank1_4, 26:16, scratch137, 21:11);
+ s(EmcPdEx2Rd, 5:0, scratch137, 27:22);
+ s(EmcPmacroTxPwrd0, 22:19, scratch137, 31:28);
+ s(EmcPmacroObDdllLongDqsRank1_5, 10:0, scratch138, 10:0);
+ s(EmcPmacroObDdllLongDqsRank1_5, 26:16, scratch138, 21:11);
+ s(EmcPdex2Cke, 5:0, scratch138, 27:22);
+ s(EmcPmacroTxPwrd0, 26:23, scratch138, 31:28);
+ s(EmcPmacroIbDdllLongDqsRank0_0, 10:0, scratch139, 10:0);
+ s(EmcPmacroIbDdllLongDqsRank0_0, 26:16, scratch139, 21:11);
+ s(EmcPChg2Pden, 5:0, scratch139, 27:22);
+ s(EmcPmacroTxPwrd0, 29:27, scratch139, 30:28);
+ s(EmcPmacroTxPwrd1, 0:0, scratch139, 31:31);
+ s(EmcPmacroIbDdllLongDqsRank0_1, 10:0, scratch140, 10:0);
+ s(EmcPmacroIbDdllLongDqsRank0_1, 26:16, scratch140, 21:11);
+ s(EmcAct2Pden, 5:0, scratch140, 27:22);
+ s(EmcPmacroTxPwrd1, 4:1, scratch140, 31:28);
+ s(EmcPmacroIbDdllLongDqsRank0_2, 10:0, scratch141, 10:0);
+ s(EmcPmacroIbDdllLongDqsRank0_2, 26:16, scratch141, 21:11);
+ s(EmcCke2Pden, 5:0, scratch141, 27:22);
+ s(EmcPmacroTxPwrd1, 8:5, scratch141, 31:28);
+ s(EmcPmacroIbDdllLongDqsRank0_3, 10:0, scratch142, 10:0);
+ s(EmcPmacroIbDdllLongDqsRank0_3, 26:16, scratch142, 21:11);
+ s(EmcTcke, 5:0, scratch142, 27:22);
+ s(EmcPmacroTxPwrd1, 12:9, scratch142, 31:28);
+ s(EmcPmacroIbDdllLongDqsRank1_0, 10:0, scratch143, 10:0);
+ s(EmcPmacroIbDdllLongDqsRank1_0, 26:16, scratch143, 21:11);
+ s(EmcTrpab, 5:0, scratch143, 27:22);
+ s(EmcPmacroTxPwrd1, 13:13, scratch143, 28:28);
+ s(EmcPmacroTxPwrd1, 18:16, scratch143, 31:29);
+ s(EmcPmacroIbDdllLongDqsRank1_1, 10:0, scratch144, 10:0);
+ s(EmcPmacroIbDdllLongDqsRank1_1, 26:16, scratch144, 21:11);
+ s(EmcClkenOverride, 3:1, scratch144, 24:22);
+ s(EmcClkenOverride, 8:6, scratch144, 27:25);
+ s(EmcPmacroTxPwrd1, 22:19, scratch144, 31:28);
+ s(EmcPmacroIbDdllLongDqsRank1_2, 10:0, scratch145, 10:0);
+ s(EmcPmacroIbDdllLongDqsRank1_2, 26:16, scratch145, 21:11);
+ s(EmcEInput, 5:0, scratch145, 27:22);
+ s(EmcPmacroTxPwrd1, 26:23, scratch145, 31:28);
+ s(EmcPmacroIbDdllLongDqsRank1_3, 10:0, scratch146, 10:0);
+ s(EmcPmacroIbDdllLongDqsRank1_3, 26:16, scratch146, 21:11);
+ s(EmcEInputDuration, 5:0, scratch146, 27:22);
+ s(EmcPmacroTxPwrd1, 29:27, scratch146, 30:28);
+ s(EmcPmacroTxPwrd2, 0:0, scratch146, 31:31);
+ s(EmcPmacroDdllLongCmd_0, 10:0, scratch147, 10:0);
+ s(EmcPmacroDdllLongCmd_0, 26:16, scratch147, 21:11);
+ s(EmcPutermExtra, 5:0, scratch147, 27:22);
+ s(EmcPmacroTxPwrd2, 4:1, scratch147, 31:28);
+ s(EmcPmacroDdllLongCmd_1, 10:0, scratch148, 10:0);
+ s(EmcPmacroDdllLongCmd_1, 26:16, scratch148, 21:11);
+ s(EmcTckesr, 5:0, scratch148, 27:22);
+ s(EmcPmacroTxPwrd2, 8:5, scratch148, 31:28);
+ s(EmcPmacroDdllLongCmd_2, 10:0, scratch149, 10:0);
+ s(EmcPmacroDdllLongCmd_2, 26:16, scratch149, 21:11);
+ s(EmcTpd, 5:0, scratch149, 27:22);
+ s(EmcPmacroTxPwrd2, 12:9, scratch149, 31:28);
+ s(EmcPmacroDdllLongCmd_3, 10:0, scratch150, 10:0);
+ s(EmcPmacroDdllLongCmd_3, 26:16, scratch150, 21:11);
+ s(EmcWdvMask, 5:0, scratch150, 27:22);
+ s(EmcPmacroTxPwrd2, 13:13, scratch150, 28:28);
+ s(EmcPmacroTxPwrd2, 18:16, scratch150, 31:29);
+ s(McEmemArbCfg, 8:0, scratch151, 8:0);
+ s(McEmemArbCfg, 20:16, scratch151, 13:9);
+ s(McEmemArbCfg, 31:24, scratch151, 21:14);
+ s(EmcWdvChk, 5:0, scratch151, 27:22);
+ s(EmcPmacroTxPwrd2, 22:19, scratch151, 31:28);
+ s(McEmemArbMisc1, 12:0, scratch152, 12:0);
+ s(McEmemArbMisc1, 25:21, scratch152, 17:13);
+ s(McEmemArbMisc1, 31:28, scratch152, 21:18);
+ s(EmcCmdBrlshft0, 5:0, scratch152, 27:22);
+ s(EmcPmacroTxPwrd2, 26:23, scratch152, 31:28);
+ s(EmcMrsWaitCnt2, 9:0, scratch153, 9:0);
+ s(EmcMrsWaitCnt2, 26:16, scratch153, 20:10);
+ s(EmcPmacroIbRxrt, 10:0, scratch153, 31:21);
+ s(EmcMrsWaitCnt, 9:0, scratch154, 9:0);
+ s(EmcMrsWaitCnt, 26:16, scratch154, 20:10);
+ s(EmcPmacroDdllLongCmd_4, 10:0, scratch154, 31:21);
+ s(EmcAutoCalInterval, 20:0, scratch155, 20:0);
+ s(McEmemArbOutstandingReq, 8:0, scratch155, 29:21);
+ s(McEmemArbOutstandingReq, 31:30, scratch155, 31:30);
+ s(McEmemArbRefpbHpCtrl, 6:0, scratch156, 6:0);
+ s(McEmemArbRefpbHpCtrl, 14:8, scratch156, 13:7);
+ s(McEmemArbRefpbHpCtrl, 22:16, scratch156, 20:14);
+ s(EmcCmdBrlshft1, 5:0, scratch156, 26:21);
+ s(EmcRrd, 4:0, scratch156, 31:27);
+ s(EmcQuseBrlshft0, 19:0, scratch157, 19:0);
+ s(EmcFbioCfg8, 27:16, scratch157, 31:20);
+ s(EmcQuseBrlshft1, 19:0, scratch158, 19:0);
+ s(EmcTxsrDll, 11:0, scratch158, 31:20);
+ s(EmcQuseBrlshft2, 19:0, scratch159, 19:0);
+ s(EmcTxdsrvttgen, 11:0, scratch159, 31:20);
+ s(EmcQuseBrlshft3, 19:0, scratch160, 19:0);
+ s(EmcPmacroVttgenCtrl0, 3:0, scratch160, 23:20);
+ s(EmcPmacroVttgenCtrl0, 11:8, scratch160, 27:24);
+ s(EmcPmacroVttgenCtrl0, 19:16, scratch160, 31:28);
+ s(EmcPmacroVttgenCtrl1, 19:0, scratch161, 19:0);
+ s(EmcCmdBrlshft2, 5:0, scratch161, 25:20);
+ s(EmcCmdBrlshft3, 5:0, scratch161, 31:26);
+ s(EmcAutoCalConfig3, 5:0, scratch162, 5:0);
+ s(EmcAutoCalConfig3, 13:8, scratch162, 11:6);
+ s(EmcAutoCalConfig3, 18:16, scratch162, 14:12);
+ s(EmcAutoCalConfig3, 22:20, scratch162, 17:15);
+ s(EmcTRefBw, 13:0, scratch162, 31:18);
+ s(EmcAutoCalConfig4, 5:0, scratch163, 5:0);
+ s(EmcAutoCalConfig4, 13:8, scratch163, 11:6);
+ s(EmcAutoCalConfig4, 18:16, scratch163, 14:12);
+ s(EmcAutoCalConfig4, 22:20, scratch163, 17:15);
+ s(EmcQpop, 6:0, scratch163, 24:18);
+ s(EmcQpop, 22:16, scratch163, 31:25);
+ s(EmcAutoCalConfig5, 5:0, scratch164, 5:0);
+ s(EmcAutoCalConfig5, 13:8, scratch164, 11:6);
+ s(EmcAutoCalConfig5, 18:16, scratch164, 14:12);
+ s(EmcAutoCalConfig5, 22:20, scratch164, 17:15);
+ s(EmcPmacroAutocalCfgCommon, 5:0, scratch164, 23:18);
+ s(EmcPmacroAutocalCfgCommon, 13:8, scratch164, 29:24);
+ s(EmcPmacroAutocalCfgCommon, 16:16, scratch164, 30:30);
+ s(EmcPmacroTxPwrd2, 27:27, scratch164, 31:31);
+ s(EmcAutoCalConfig6, 5:0, scratch165, 5:0);
+ s(EmcAutoCalConfig6, 13:8, scratch165, 11:6);
+ s(EmcAutoCalConfig6, 18:16, scratch165, 14:12);
+ s(EmcAutoCalConfig6, 22:20, scratch165, 17:15);
+ s(EmcWev, 5:0, scratch165, 23:18);
+ s(EmcWsv, 5:0, scratch165, 29:24);
+ s(EmcPmacroTxPwrd2, 29:28, scratch165, 31:30);
+ s(EmcAutoCalConfig7, 5:0, scratch166, 5:0);
+ s(EmcAutoCalConfig7, 13:8, scratch166, 11:6);
+ s(EmcAutoCalConfig7, 18:16, scratch166, 14:12);
+ s(EmcAutoCalConfig7, 22:20, scratch166, 17:15);
+ s(EmcCfg3, 2:0, scratch166, 20:18);
+ s(EmcCfg3, 6:4, scratch166, 23:21);
+ s(EmcQuseWidth, 3:0, scratch166, 27:24);
+ s(EmcQuseWidth, 29:28, scratch166, 29:28);
+ s(EmcPmacroTxPwrd3, 1:0, scratch166, 31:30);
+ s(EmcAutoCalConfig8, 5:0, scratch167, 5:0);
+ s(EmcAutoCalConfig8, 13:8, scratch167, 11:6);
+ s(EmcAutoCalConfig8, 18:16, scratch167, 14:12);
+ s(EmcAutoCalConfig8, 22:20, scratch167, 17:15);
+ s(EmcPmacroBgBiasCtrl0, 2:0, scratch167, 20:18);
+ s(EmcPmacroBgBiasCtrl0, 6:4, scratch167, 23:21);
+ s(McEmemArbTimingRcd, 5:0, scratch167, 29:24);
+ s(EmcPmacroTxPwrd3, 3:2, scratch167, 31:30);
+ s(EmcXm2CompPadCtrl2, 17:0, scratch168, 17:0);
+ s(McEmemArbTimingCcdmw, 5:0, scratch168, 23:18);
+ s(McEmemArbOverride, 27:27, scratch168, 24:24);
+ s(McEmemArbOverride, 26:26, scratch168, 25:25);
+ s(McEmemArbOverride, 16:16, scratch168, 26:26);
+ s(McEmemArbOverride, 10:10, scratch168, 27:27);
+ s(McEmemArbOverride, 4:4, scratch168, 28:28);
+ s(McEmemArbOverride, 3:3, scratch168, 29:29);
+ s(EmcPmacroTxPwrd3, 5:4, scratch168, 31:30);
+ s(EmcXm2CompPadCtrl3, 17:0, scratch169, 17:0);
+ s(EmcRext, 4:0, scratch169, 22:18);
+ s(EmcTClkStop, 4:0, scratch169, 27:23);
+ s(EmcPmacroTxPwrd3, 9:6, scratch169, 31:28);
+ s(EmcZcalWaitCnt, 10:0, scratch170, 10:0);
+ s(EmcZcalWaitCnt, 21:16, scratch170, 16:11);
+ s(EmcZcalWaitCnt, 31:31, scratch170, 17:17);
+ s(EmcWext, 4:0, scratch170, 22:18);
+ s(EmcRefctrl2, 0:0, scratch170, 23:23);
+ s(EmcRefctrl2, 26:24, scratch170, 26:24);
+ s(EmcRefctrl2, 31:31, scratch170, 27:27);
+ s(EmcPmacroTxPwrd3, 13:10, scratch170, 31:28);
+ s(EmcZcalMrwCmd, 7:0, scratch171, 7:0);
+ s(EmcZcalMrwCmd, 23:16, scratch171, 15:8);
+ s(EmcZcalMrwCmd, 31:30, scratch171, 17:16);
+ s(EmcWeDuration, 4:0, scratch171, 22:18);
+ s(EmcWsDuration, 4:0, scratch171, 27:23);
+ s(EmcPmacroTxPwrd3, 19:16, scratch171, 31:28);
+ s(EmcSwizzleRank0Byte0, 2:0, scratch172, 2:0);
+ s(EmcSwizzleRank0Byte0, 6:4, scratch172, 5:3);
+ s(EmcSwizzleRank0Byte0, 10:8, scratch172, 8:6);
+ s(EmcSwizzleRank0Byte0, 14:12, scratch172, 11:9);
+ s(EmcSwizzleRank0Byte0, 18:16, scratch172, 14:12);
+ s(EmcSwizzleRank0Byte0, 22:20, scratch172, 17:15);
+ s(EmcPutermWidth, 31:31, scratch172, 18:18);
+ s(EmcPutermWidth, 3:0, scratch172, 22:19);
+ s(McEmemArbTimingRrd, 4:0, scratch172, 27:23);
+ s(EmcPmacroTxPwrd3, 23:20, scratch172, 31:28);
+ s(EmcSwizzleRank0Byte1, 2:0, scratch173, 2:0);
+ s(EmcSwizzleRank0Byte1, 6:4, scratch173, 5:3);
+ s(EmcSwizzleRank0Byte1, 10:8, scratch173, 8:6);
+ s(EmcSwizzleRank0Byte1, 14:12, scratch173, 11:9);
+ s(EmcSwizzleRank0Byte1, 18:16, scratch173, 14:12);
+ s(EmcSwizzleRank0Byte1, 22:20, scratch173, 17:15);
+ s(McEmemArbTimingR2R, 4:0, scratch173, 22:18);
+ s(McEmemArbTimingW2W, 4:0, scratch173, 27:23);
+ s(EmcPmacroTxPwrd3, 27:24, scratch173, 31:28);
+ s(EmcSwizzleRank0Byte2, 2:0, scratch174, 2:0);
+ s(EmcSwizzleRank0Byte2, 6:4, scratch174, 5:3);
+ s(EmcSwizzleRank0Byte2, 10:8, scratch174, 8:6);
+ s(EmcSwizzleRank0Byte2, 14:12, scratch174, 11:9);
+ s(EmcSwizzleRank0Byte2, 18:16, scratch174, 14:12);
+ s(EmcSwizzleRank0Byte2, 22:20, scratch174, 17:15);
+ s(EmcPmacroTxPwrd3, 29:28, scratch174, 19:18);
+ s(EmcPmacroTxSelClkSrc0, 11:0, scratch174, 31:20);
+ s(EmcSwizzleRank0Byte3, 2:0, scratch175, 2:0);
+ s(EmcSwizzleRank0Byte3, 6:4, scratch175, 5:3);
+ s(EmcSwizzleRank0Byte3, 10:8, scratch175, 8:6);
+ s(EmcSwizzleRank0Byte3, 14:12, scratch175, 11:9);
+ s(EmcSwizzleRank0Byte3, 18:16, scratch175, 14:12);
+ s(EmcSwizzleRank0Byte3, 22:20, scratch175, 17:15);
+ s(EmcPmacroTxSelClkSrc0, 27:16, scratch175, 29:18);
+ s(EmcPmacroTxSelClkSrc1, 1:0, scratch175, 31:30);
+ s(EmcSwizzleRank1Byte0, 2:0, scratch176, 2:0);
+ s(EmcSwizzleRank1Byte0, 6:4, scratch176, 5:3);
+ s(EmcSwizzleRank1Byte0, 10:8, scratch176, 8:6);
+ s(EmcSwizzleRank1Byte0, 14:12, scratch176, 11:9);
+ s(EmcSwizzleRank1Byte0, 18:16, scratch176, 14:12);
+ s(EmcSwizzleRank1Byte0, 22:20, scratch176, 17:15);
+ s(EmcPmacroTxSelClkSrc1, 11:2, scratch176, 27:18);
+ s(EmcPmacroTxSelClkSrc1, 19:16, scratch176, 31:28);
+ s(EmcSwizzleRank1Byte1, 2:0, scratch177, 2:0);
+ s(EmcSwizzleRank1Byte1, 6:4, scratch177, 5:3);
+ s(EmcSwizzleRank1Byte1, 10:8, scratch177, 8:6);
+ s(EmcSwizzleRank1Byte1, 14:12, scratch177, 11:9);
+ s(EmcSwizzleRank1Byte1, 18:16, scratch177, 14:12);
+ s(EmcSwizzleRank1Byte1, 22:20, scratch177, 17:15);
+ s(EmcPmacroTxSelClkSrc1, 27:20, scratch177, 25:18);
+ s(EmcPmacroTxSelClkSrc3, 5:0, scratch177, 31:26);
+ s(EmcSwizzleRank1Byte2, 2:0, scratch178, 2:0);
+ s(EmcSwizzleRank1Byte2, 6:4, scratch178, 5:3);
+ s(EmcSwizzleRank1Byte2, 10:8, scratch178, 8:6);
+ s(EmcSwizzleRank1Byte2, 14:12, scratch178, 11:9);
+ s(EmcSwizzleRank1Byte2, 18:16, scratch178, 14:12);
+ s(EmcSwizzleRank1Byte2, 22:20, scratch178, 17:15);
+ s(EmcPmacroTxSelClkSrc3, 11:6, scratch178, 23:18);
+ s(EmcPmacroTxSelClkSrc3, 23:16, scratch178, 31:24);
+ s(EmcSwizzleRank1Byte3, 2:0, scratch179, 2:0);
+ s(EmcSwizzleRank1Byte3, 6:4, scratch179, 5:3);
+ s(EmcSwizzleRank1Byte3, 10:8, scratch179, 8:6);
+ s(EmcSwizzleRank1Byte3, 14:12, scratch179, 11:9);
+ s(EmcSwizzleRank1Byte3, 18:16, scratch179, 14:12);
+ s(EmcSwizzleRank1Byte3, 22:20, scratch179, 17:15);
+ s(EmcPmacroTxSelClkSrc3, 27:24, scratch179, 21:18);
+ s(EmcPmacroTxSelClkSrc2, 9:0, scratch179, 31:22);
+ s(EmcPmacroCmdBrickCtrlFdpd, 17:0, scratch180, 17:0);
+ s(EmcPmacroTxSelClkSrc2, 11:10, scratch180, 19:18);
+ s(EmcPmacroTxSelClkSrc2, 27:16, scratch180, 31:20);
+ s(EmcPmacroDataBrickCtrlFdpd, 17:0, scratch181, 17:0);
+ s(EmcPmacroTxSelClkSrc4, 11:0, scratch181, 29:18);
+ s(EmcPmacroTxSelClkSrc4, 17:16, scratch181, 31:30);
+ s(EmcFbioCfg7, 16:0, scratch182, 16:0);
+ s(McEmemArbRefpbBankCtrl, 6:0, scratch182, 23:17);
+ s(McEmemArbRefpbBankCtrl, 14:8, scratch182, 30:24);
+ s(McEmemArbRefpbBankCtrl, 31:31, scratch182, 31:31);
+ s(EmcDynSelfRefControl, 15:0, scratch183, 15:0);
+ s(EmcDynSelfRefControl, 31:31, scratch183, 16:16);
+ s(EmcPmacroTxSelClkSrc4, 27:18, scratch183, 26:17);
+ s(EmcPmacroTxSelClkSrc5, 4:0, scratch183, 31:27);
+ s(EmcDllCfg1, 16:0, scratch184, 16:0);
+ s(EmcPmacroTxSelClkSrc5, 11:5, scratch184, 23:17);
+ s(EmcPmacroTxSelClkSrc5, 23:16, scratch184, 31:24);
+ s(EmcPmacroPadCfgCtrl, 1:0, scratch185, 1:0);
+ s(EmcPmacroPadCfgCtrl, 6:5, scratch185, 3:2);
+ s(EmcPmacroPadCfgCtrl, 11:9, scratch185, 6:4);
+ s(EmcPmacroPadCfgCtrl, 13:13, scratch185, 7:7);
+ s(EmcPmacroPadCfgCtrl, 17:16, scratch185, 9:8);
+ s(EmcPmacroPadCfgCtrl, 21:20, scratch185, 11:10);
+ s(EmcPmacroPadCfgCtrl, 25:24, scratch185, 13:12);
+ s(EmcPmacroPadCfgCtrl, 30:28, scratch185, 16:14);
+ s(EmcPmacroTxSelClkSrc5, 27:24, scratch185, 20:17);
+ s(EmcPmacroCmdPadTxCtrl, 1:0, scratch185, 22:21);
+ s(EmcPmacroCmdPadTxCtrl, 5:4, scratch185, 24:23);
+ s(EmcPmacroCmdPadTxCtrl, 9:8, scratch185, 26:25);
+ s(EmcPmacroCmdPadTxCtrl, 13:12, scratch185, 28:27);
+ s(EmcPmacroCmdPadTxCtrl, 16:16, scratch185, 29:29);
+ s(EmcPmacroCmdPadTxCtrl, 21:20, scratch185, 31:30);
+ s(EmcRefresh, 15:0, scratch186, 15:0);
+ s(EmcCmdQ, 4:0, scratch186, 20:16);
+ s(EmcCmdQ, 10:8, scratch186, 23:21);
+ s(EmcCmdQ, 14:12, scratch186, 26:24);
+ s(EmcCmdQ, 28:24, scratch186, 31:27);
+ s(EmcAcpdControl, 15:0, scratch187, 15:0);
+ s(EmcAutoCalVrefSel1, 15:0, scratch187, 31:16);
+ s(EmcXm2CompPadCtrl, 1:0, scratch188, 1:0);
+ s(EmcXm2CompPadCtrl, 6:3, scratch188, 5:2);
+ s(EmcXm2CompPadCtrl, 9:9, scratch188, 6:6);
+ s(EmcXm2CompPadCtrl, 19:11, scratch188, 15:7);
+ s(EmcCfgDigDllPeriod, 15:0, scratch188, 31:16);
+ s(EmcCfgDigDll_1, 15:0, scratch189, 15:0);
+ s(EmcPreRefreshReqCnt, 15:0, scratch189, 31:16);
+ s(EmcPmacroCmdPadTxCtrl, 27:24, scratch190, 19:16);
+ s(EmcPmacroDataPadTxCtrl, 1:0, scratch190, 21:20);
+ s(EmcPmacroDataPadTxCtrl, 5:4, scratch190, 23:22);
+ s(EmcPmacroDataPadTxCtrl, 9:8, scratch190, 25:24);
+ s(EmcPmacroDataPadTxCtrl, 13:12, scratch190, 27:26);
+ s(EmcPmacroDataPadTxCtrl, 16:16, scratch190, 28:28);
+ s(EmcPmacroDataPadTxCtrl, 21:20, scratch190, 30:29);
+ s(EmcPmacroDataPadTxCtrl, 24:24, scratch190, 31:31);
+ s(EmcPmacroDataPadTxCtrl, 27:25, scratch191, 2:0);
+
+ s(EmcPinGpio, 1:0, scratch8, 31:30);
+ s(EmcPinGpioEn, 1:0, scratch9, 31:30);
+ s(EmcDevSelect, 1:0, scratch10, 31:30);
+ s(EmcZcalWarmColdBootEnables, 1:0, scratch11, 31:30);
+ s(EmcCfgDigDllPeriodWarmBoot, 1:0, scratch12, 31:30);
+ s32(EmcBctSpare13, scratch31);
+ s32(EmcBctSpare12, scratch32);
+ s32(EmcBctSpare7, scratch33);
+ s32(EmcBctSpare6, scratch40);
+ s32(EmcBctSpare5, scratch42);
+ s32(EmcBctSpare4, scratch44);
+ s32(EmcBctSpare3, scratch45);
+ s32(EmcBctSpare2, scratch46);
+ s32(EmcBctSpare1, scratch47);
+ s32(EmcBctSpare0, scratch48);
+ s32(EmcBctSpare9, scratch50);
+ s32(EmcBctSpare8, scratch51);
+ s32(BootRomPatchData, scratch56);
+ s32(BootRomPatchControl, scratch57);
+ s(McClkenOverrideAllWarmBoot, 0:0, scratch58, 31:31);
+ s(EmcClkenOverrideAllWarmBoot, 0:0, scratch59, 30:30);
+ s(EmcMrsWarmBootEnable, 0:0, scratch59, 31:31);
+ s(ClearClk2Mc1, 0:0, scratch60, 30:30);
+ s(EmcWarmBootExtraModeRegWriteEnable, 0:0, scratch60, 31:31);
+ s(ClkRstControllerPllmMisc2OverrideEnable, 0:0, scratch61, 30:30);
+ s(EmcDbgWriteMux, 0:0, scratch61, 31:31);
+ s(EmcExtraRefreshNum, 2:0, scratch62, 31:29);
+ s(PmcIoDpd3ReqWait, 2:0, scratch68, 30:28);
+ s(AhbArbitrationXbarCtrlMemInitDone, 0:0, scratch68, 31:31);
+ s(MemoryType, 2:0, scratch69, 30:28);
+ s(PmcIoDpd4ReqWait, 2:0, scratch70, 30:28);
+ s(EmcTimingControlWait, 7:0, scratch86, 31:24);
+ s(EmcZcalWarmBootWait, 7:0, scratch87, 31:24);
+ s(WarmBootWait, 7:0, scratch88, 31:24);
+ s(EmcPinProgramWait, 7:0, scratch89, 31:24);
+ s(EmcAutoCalWait, 9:0, scratch101, 31:22);
+ s(SwizzleRankByteEncode, 15:0, scratch190, 15:0);
+
+ switch (sdram->MemoryType)
+ {
+ case NvBootMemoryType_LpDdr2:
+ case NvBootMemoryType_LpDdr4:
+ s(EmcMrwLpddr2ZcalWarmBoot, 23:16, scratch5, 7:0);
+ s(EmcMrwLpddr2ZcalWarmBoot, 7:0, scratch5, 15:8);
+ s(EmcWarmBootMrwExtra, 23:16, scratch5, 23:16);
+ s(EmcWarmBootMrwExtra, 7:0, scratch5, 31:24);
+ s(EmcMrwLpddr2ZcalWarmBoot, 31:30, scratch6, 1:0);
+ s(EmcWarmBootMrwExtra, 31:30, scratch6, 3:2);
+ s(EmcMrwLpddr2ZcalWarmBoot, 27:26, scratch6, 5:4);
+ s(EmcWarmBootMrwExtra, 27:26, scratch6, 7:6);
+ s(EmcMrw6, 27:0, scratch8, 27:0);
+ s(EmcMrw6, 31:30, scratch8, 29:28);
+ s(EmcMrw8, 27:0, scratch9, 27:0);
+ s(EmcMrw8, 31:30, scratch9, 29:28);
+ s(EmcMrw9, 27:0, scratch10, 27:0);
+ s(EmcMrw9, 31:30, scratch10, 29:28);
+ s(EmcMrw10, 27:0, scratch11, 27:0);
+ s(EmcMrw10, 31:30, scratch11, 29:28);
+ s(EmcMrw12, 27:0, scratch12, 27:0);
+ s(EmcMrw12, 31:30, scratch12, 29:28);
+ s(EmcMrw13, 27:0, scratch13, 27:0);
+ s(EmcMrw13, 31:30, scratch13, 29:28);
+ s(EmcMrw14, 27:0, scratch14, 27:0);
+ s(EmcMrw14, 31:30, scratch14, 29:28);
+ s(EmcMrw1, 7:0, scratch15, 7:0);
+ s(EmcMrw1, 23:16, scratch15, 15:8);
+ s(EmcMrw1, 27:26, scratch15, 17:16);
+ s(EmcMrw1, 31:30, scratch15, 19:18);
+ s(EmcWarmBootMrwExtra, 7:0, scratch16, 7:0);
+ s(EmcWarmBootMrwExtra, 23:16, scratch16, 15:8);
+ s(EmcWarmBootMrwExtra, 27:26, scratch16, 17:16);
+ s(EmcWarmBootMrwExtra, 31:30, scratch16, 19:18);
+ s(EmcMrw2, 7:0, scratch17, 7:0);
+ s(EmcMrw2, 23:16, scratch17, 15:8);
+ s(EmcMrw2, 27:26, scratch17, 17:16);
+ s(EmcMrw2, 31:30, scratch17, 19:18);
+ s(EmcMrw3, 7:0, scratch18, 7:0);
+ s(EmcMrw3, 23:16, scratch18, 15:8);
+ s(EmcMrw3, 27:26, scratch18, 17:16);
+ s(EmcMrw3, 31:30, scratch18, 19:18);
+ s(EmcMrw4, 7:0, scratch19, 7:0);
+ s(EmcMrw4, 23:16, scratch19, 15:8);
+ s(EmcMrw4, 27:26, scratch19, 17:16);
+ s(EmcMrw4, 31:30, scratch19, 19:18);
+ break;
+ case NvBootMemoryType_Ddr3:
+ s(EmcMrs, 13:0, scratch5, 13:0);
+ s(EmcEmrs, 13:0, scratch5, 27:14);
+ s(EmcMrs, 21:20, scratch5, 29:28);
+ s(EmcMrs, 31:30, scratch5, 31:30);
+ s(EmcEmrs2, 13:0, scratch8, 13:0);
+ s(EmcEmrs3, 13:0, scratch8, 27:14);
+ s(EmcEmrs, 21:20, scratch8, 29:28);
+ s(EmcWarmBootMrsExtra, 13:0, scratch9, 13:0);
+ s(EmcEmrs, 31:30, scratch9, 15:14);
+ s(EmcEmrs2, 21:20, scratch9, 17:16);
+ s(EmcEmrs2, 31:30, scratch9, 19:18);
+ s(EmcEmrs3, 21:20, scratch9, 21:20);
+ s(EmcEmrs3, 31:30, scratch9, 23:22);
+ s(EmcWarmBootMrsExtra, 31:30, scratch9, 25:24);
+ s(EmcWarmBootMrsExtra, 21:20, scratch9, 27:26);
+ s(EmcZqCalDdr3WarmBoot, 31:30, scratch9, 29:28);
+ s(EmcMrs, 27:26, scratch10, 1:0);
+ s(EmcEmrs, 27:26, scratch10, 3:2);
+ s(EmcEmrs2, 27:26, scratch10, 5:4);
+ s(EmcEmrs3, 27:26, scratch10, 7:6);
+ s(EmcWarmBootMrsExtra, 27:27, scratch10, 8:8);
+ s(EmcWarmBootMrsExtra, 26:26, scratch10, 9:9);
+ s(EmcZqCalDdr3WarmBoot, 0:0, scratch10, 10:10);
+ s(EmcZqCalDdr3WarmBoot, 4:4, scratch10, 11:11);
+ break;
+ }
+
+ s32(EmcCmdMappingByte, secure_scratch8);
+ s32(EmcPmacroBrickMapping0, secure_scratch9);
+ s32(EmcPmacroBrickMapping1, secure_scratch10);
+ s32(EmcPmacroBrickMapping2, secure_scratch11);
+ s32(McVideoProtectGpuOverride0, secure_scratch12);
+ s(EmcCmdMappingCmd0_0, 6:0, secure_scratch13, 6:0);
+ s(EmcCmdMappingCmd0_0, 14:8, secure_scratch13, 13:7);
+ s(EmcCmdMappingCmd0_0, 22:16, secure_scratch13, 20:14);
+ s(EmcCmdMappingCmd0_0, 30:24, secure_scratch13, 27:21);
+ s(McVideoProtectBomAdrHi, 1:0, secure_scratch13, 29:28);
+ s(McVideoProtectWriteAccess, 1:0, secure_scratch13, 31:30);
+ s(EmcCmdMappingCmd0_1, 6:0, secure_scratch14, 6:0);
+ s(EmcCmdMappingCmd0_1, 14:8, secure_scratch14, 13:7);
+ s(EmcCmdMappingCmd0_1, 22:16, secure_scratch14, 20:14);
+ s(EmcCmdMappingCmd0_1, 30:24, secure_scratch14, 27:21);
+ s(McSecCarveoutAdrHi, 1:0, secure_scratch14, 29:28);
+ s(McMtsCarveoutAdrHi, 1:0, secure_scratch14, 31:30);
+ s(EmcCmdMappingCmd1_0, 6:0, secure_scratch15, 6:0);
+ s(EmcCmdMappingCmd1_0, 14:8, secure_scratch15, 13:7);
+ s(EmcCmdMappingCmd1_0, 22:16, secure_scratch15, 20:14);
+ s(EmcCmdMappingCmd1_0, 30:24, secure_scratch15, 27:21);
+ s(McGeneralizedCarveout5BomHi, 1:0, secure_scratch15, 29:28);
+ s(McGeneralizedCarveout3BomHi, 1:0, secure_scratch15, 31:30);
+ s(EmcCmdMappingCmd1_1, 6:0, secure_scratch16, 6:0);
+ s(EmcCmdMappingCmd1_1, 14:8, secure_scratch16, 13:7);
+ s(EmcCmdMappingCmd1_1, 22:16, secure_scratch16, 20:14);
+ s(EmcCmdMappingCmd1_1, 30:24, secure_scratch16, 27:21);
+ s(McGeneralizedCarveout2BomHi, 1:0, secure_scratch16, 29:28);
+ s(McGeneralizedCarveout4BomHi, 1:0, secure_scratch16, 31:30);
+ s(EmcCmdMappingCmd2_0, 6:0, secure_scratch17, 6:0);
+ s(EmcCmdMappingCmd2_0, 14:8, secure_scratch17, 13:7);
+ s(EmcCmdMappingCmd2_0, 22:16, secure_scratch17, 20:14);
+ s(EmcCmdMappingCmd2_0, 30:24, secure_scratch17, 27:21);
+ s(McGeneralizedCarveout1BomHi, 1:0, secure_scratch17, 29:28);
+ s(EmcAdrCfg, 0:0, secure_scratch17, 30:30);
+ s(EmcFbioSpare, 1:1, secure_scratch17, 31:31);
+ s(EmcCmdMappingCmd2_1, 6:0, secure_scratch18, 6:0);
+ s(EmcCmdMappingCmd2_1, 14:8, secure_scratch18, 13:7);
+ s(EmcCmdMappingCmd2_1, 22:16, secure_scratch18, 20:14);
+ s(EmcCmdMappingCmd2_1, 30:24, secure_scratch18, 27:21);
+ s(EmcFbioCfg8, 15:15, secure_scratch18, 28:28);
+ s(McEmemAdrCfg, 0:0, secure_scratch18, 29:29);
+ s(McSecCarveoutProtectWriteAccess, 0:0, secure_scratch18, 30:30);
+ s(McMtsCarveoutRegCtrl, 0:0, secure_scratch18, 31:31);
+ s(EmcCmdMappingCmd3_0, 6:0, secure_scratch19, 6:0);
+ s(EmcCmdMappingCmd3_0, 14:8, secure_scratch19, 13:7);
+ s(EmcCmdMappingCmd3_0, 22:16, secure_scratch19, 20:14);
+ s(EmcCmdMappingCmd3_0, 30:24, secure_scratch19, 27:21);
+ s(McGeneralizedCarveout2Cfg0, 6:3, secure_scratch19, 31:28);
+ s(EmcCmdMappingCmd3_1, 6:0, secure_scratch20, 6:0);
+ s(EmcCmdMappingCmd3_1, 14:8, secure_scratch20, 13:7);
+ s(EmcCmdMappingCmd3_1, 22:16, secure_scratch20, 20:14);
+ s(EmcCmdMappingCmd3_1, 30:24, secure_scratch20, 27:21);
+ s(McGeneralizedCarveout2Cfg0, 10:7, secure_scratch20, 31:28);
+ s(McGeneralizedCarveout4Cfg0, 26:0, secure_scratch39, 26:0);
+ s(McGeneralizedCarveout2Cfg0, 17:14, secure_scratch39, 30:27);
+ s(McVideoProtectVprOverride, 0:0, secure_scratch39, 31:31);
+ s(McGeneralizedCarveout5Cfg0, 26:0, secure_scratch40, 26:0);
+ s(McGeneralizedCarveout2Cfg0, 21:18, secure_scratch40, 30:27);
+ s(McVideoProtectVprOverride, 1:1, secure_scratch40, 31:31);
+ s(EmcCmdMappingCmd0_2, 6:0, secure_scratch41, 6:0);
+ s(EmcCmdMappingCmd0_2, 14:8, secure_scratch41, 13:7);
+ s(EmcCmdMappingCmd0_2, 22:16, secure_scratch41, 20:14);
+ s(EmcCmdMappingCmd0_2, 27:24, secure_scratch41, 24:21);
+ s(McGeneralizedCarveout1Cfg0, 6:3, secure_scratch41, 28:25);
+ s(McGeneralizedCarveout2Cfg0, 13:11, secure_scratch41, 31:29);
+ s(EmcCmdMappingCmd1_2, 6:0, secure_scratch42, 6:0);
+ s(EmcCmdMappingCmd1_2, 14:8, secure_scratch42, 13:7);
+ s(EmcCmdMappingCmd1_2, 22:16, secure_scratch42, 20:14);
+ s(EmcCmdMappingCmd1_2, 27:24, secure_scratch42, 24:21);
+ s(McGeneralizedCarveout1Cfg0, 13:7, secure_scratch42, 31:25);
+ s(EmcCmdMappingCmd2_2, 6:0, secure_scratch43, 6:0);
+ s(EmcCmdMappingCmd2_2, 14:8, secure_scratch43, 13:7);
+ s(EmcCmdMappingCmd2_2, 22:16, secure_scratch43, 20:14);
+ s(EmcCmdMappingCmd2_2, 27:24, secure_scratch43, 24:21);
+ s(McGeneralizedCarveout1Cfg0, 17:14, secure_scratch43, 28:25);
+ s(McGeneralizedCarveout3Cfg0, 13:11, secure_scratch43, 31:29);
+ s(EmcCmdMappingCmd3_2, 6:0, secure_scratch44, 6:0);
+ s(EmcCmdMappingCmd3_2, 14:8, secure_scratch44, 13:7);
+ s(EmcCmdMappingCmd3_2, 22:16, secure_scratch44, 20:14);
+ s(EmcCmdMappingCmd3_2, 27:24, secure_scratch44, 24:21);
+ s(McGeneralizedCarveout1Cfg0, 21:18, secure_scratch44, 28:25);
+ s(McVideoProtectVprOverride, 3:2, secure_scratch44, 30:29);
+ s(McVideoProtectVprOverride, 6:6, secure_scratch44, 31:31);
+ s(McEmemAdrCfgChannelMask, 31:9, secure_scratch45, 22:0);
+ s(McEmemAdrCfgDev0, 2:0, secure_scratch45, 25:23);
+ s(McEmemAdrCfgDev0, 9:8, secure_scratch45, 27:26);
+ s(McEmemAdrCfgDev0, 19:16, secure_scratch45, 31:28);
+ s(McEmemAdrCfgBankMask0, 31:10, secure_scratch46, 21:0);
+ s(McEmemAdrCfgDev1, 2:0, secure_scratch46, 24:22);
+ s(McEmemAdrCfgDev1, 9:8, secure_scratch46, 26:25);
+ s(McEmemAdrCfgDev1, 19:16, secure_scratch46, 30:27);
+ s(McVideoProtectVprOverride, 7:7, secure_scratch46, 31:31);
+ s(McEmemAdrCfgBankMask1, 31:10, secure_scratch47, 21:0);
+ s(McGeneralizedCarveout3Cfg0, 10:3, secure_scratch47, 29:22);
+ s(McVideoProtectVprOverride, 9:8, secure_scratch47, 31:30);
+ s(McEmemAdrCfgBankMask2, 31:10, secure_scratch48, 21:0);
+ s(McGeneralizedCarveout3Cfg0, 21:14, secure_scratch48, 29:22);
+ s(McVideoProtectVprOverride, 11:11, secure_scratch48, 30:30);
+ s(McVideoProtectVprOverride, 14:14, secure_scratch48, 31:31);
+ s(McVideoProtectGpuOverride1, 15:0, secure_scratch49, 15:0);
+ s(McEmemCfg, 13:0, secure_scratch49, 29:16);
+ s(McEmemCfg, 31:31, secure_scratch49, 30:30);
+ s(McVideoProtectVprOverride, 15:15, secure_scratch49, 31:31);
+ s(McGeneralizedCarveout3Bom, 31:17, secure_scratch50, 14:0);
+ s(McGeneralizedCarveout1Bom, 31:17, secure_scratch50, 29:15);
+ s(McVideoProtectVprOverride, 18:17, secure_scratch50, 31:30);
+ s(McGeneralizedCarveout4Bom, 31:17, secure_scratch51, 14:0);
+ s(McGeneralizedCarveout2Bom, 31:17, secure_scratch51, 29:15);
+ s(McVideoProtectVprOverride, 20:19, secure_scratch51, 31:30);
+ s(McGeneralizedCarveout5Bom, 31:17, secure_scratch52, 14:0);
+ s(McVideoProtectBom, 31:20, secure_scratch52, 26:15);
+ s(McVideoProtectVprOverride, 23:21, secure_scratch52, 29:27);
+ s(McVideoProtectVprOverride, 26:26, secure_scratch52, 30:30);
+ s(McVideoProtectVprOverride, 29:29, secure_scratch52, 31:31);
+ s(McVideoProtectSizeMb, 11:0, secure_scratch53, 11:0);
+ s(McSecCarveoutBom, 31:20, secure_scratch53, 23:12);
+ s(McVideoProtectVprOverride, 31:30, secure_scratch53, 25:24);
+ s(McVideoProtectVprOverride1, 1:0, secure_scratch53, 27:26);
+ s(McVideoProtectVprOverride1, 7:4, secure_scratch53, 31:28);
+ s(McSecCarveoutSizeMb, 11:0, secure_scratch54, 11:0);
+ s(McMtsCarveoutBom, 31:20, secure_scratch54, 23:12);
+ s(McVideoProtectVprOverride1, 15:8, secure_scratch54, 31:24);
+ s(McMtsCarveoutSizeMb, 11:0, secure_scratch55, 11:0);
+ s(McGeneralizedCarveout4Size128kb, 11:0, secure_scratch55, 23:12);
+ s(McVideoProtectVprOverride1, 16:16, secure_scratch55, 24:24);
+ s(McGeneralizedCarveout2Cfg0, 2:0, secure_scratch55, 27:25);
+ s(McGeneralizedCarveout2Cfg0, 25:22, secure_scratch55, 31:28);
+ s(McGeneralizedCarveout3Size128kb, 11:0, secure_scratch56, 11:0);
+ s(McGeneralizedCarveout2Size128kb, 11:0, secure_scratch56, 23:12);
+ s(McGeneralizedCarveout2Cfg0, 26:26, secure_scratch56, 24:24);
+ s(McGeneralizedCarveout1Cfg0, 2:0, secure_scratch56, 27:25);
+ s(McGeneralizedCarveout1Cfg0, 25:22, secure_scratch56, 31:28);
+ s(McGeneralizedCarveout1Size128kb, 11:0, secure_scratch57, 11:0);
+ s(McGeneralizedCarveout5Size128kb, 11:0, secure_scratch57, 23:12);
+ s(McGeneralizedCarveout1Cfg0, 26:26, secure_scratch57, 24:24);
+ s(McGeneralizedCarveout3Cfg0, 2:0, secure_scratch57, 27:25);
+ s(McGeneralizedCarveout3Cfg0, 25:22, secure_scratch57, 31:28);
+ s(McGeneralizedCarveout3Cfg0, 26:26, secure_scratch58, 0:0);
+
+ s32(McGeneralizedCarveout1Access0, secure_scratch59);
+ s32(McGeneralizedCarveout1Access1, secure_scratch60);
+ s32(McGeneralizedCarveout1Access2, secure_scratch61);
+ s32(McGeneralizedCarveout1Access3, secure_scratch62);
+ s32(McGeneralizedCarveout1Access4, secure_scratch63);
+ s32(McGeneralizedCarveout2Access0, secure_scratch64);
+ s32(McGeneralizedCarveout2Access1, secure_scratch65);
+ s32(McGeneralizedCarveout2Access2, secure_scratch66);
+ s32(McGeneralizedCarveout2Access3, secure_scratch67);
+ s32(McGeneralizedCarveout2Access4, secure_scratch68);
+ s32(McGeneralizedCarveout3Access0, secure_scratch69);
+ s32(McGeneralizedCarveout3Access1, secure_scratch70);
+ s32(McGeneralizedCarveout3Access2, secure_scratch71);
+ s32(McGeneralizedCarveout3Access3, secure_scratch72);
+ s32(McGeneralizedCarveout3Access4, secure_scratch73);
+ s32(McGeneralizedCarveout4Access0, secure_scratch74);
+ s32(McGeneralizedCarveout4Access1, secure_scratch75);
+ s32(McGeneralizedCarveout4Access2, secure_scratch76);
+ s32(McGeneralizedCarveout4Access3, secure_scratch77);
+ s32(McGeneralizedCarveout4Access4, secure_scratch78);
+ s32(McGeneralizedCarveout5Access0, secure_scratch79);
+ s32(McGeneralizedCarveout5Access1, secure_scratch80);
+ s32(McGeneralizedCarveout5Access2, secure_scratch81);
+ s32(McGeneralizedCarveout5Access3, secure_scratch82);
+ s32(McGeneralizedCarveout1ForceInternalAccess0, secure_scratch84);
+ s32(McGeneralizedCarveout1ForceInternalAccess1, secure_scratch85);
+ s32(McGeneralizedCarveout1ForceInternalAccess2, secure_scratch86);
+ s32(McGeneralizedCarveout1ForceInternalAccess3, secure_scratch87);
+ s32(McGeneralizedCarveout1ForceInternalAccess4, secure_scratch88);
+ s32(McGeneralizedCarveout2ForceInternalAccess0, secure_scratch89);
+ s32(McGeneralizedCarveout2ForceInternalAccess1, secure_scratch90);
+ s32(McGeneralizedCarveout2ForceInternalAccess2, secure_scratch91);
+ s32(McGeneralizedCarveout2ForceInternalAccess3, secure_scratch92);
+ s32(McGeneralizedCarveout2ForceInternalAccess4, secure_scratch93);
+ s32(McGeneralizedCarveout3ForceInternalAccess0, secure_scratch94);
+ s32(McGeneralizedCarveout3ForceInternalAccess1, secure_scratch95);
+ s32(McGeneralizedCarveout3ForceInternalAccess2, secure_scratch96);
+ s32(McGeneralizedCarveout3ForceInternalAccess3, secure_scratch97);
+ s32(McGeneralizedCarveout3ForceInternalAccess4, secure_scratch98);
+ s32(McGeneralizedCarveout4ForceInternalAccess0, secure_scratch99);
+ s32(McGeneralizedCarveout4ForceInternalAccess1, secure_scratch100);
+ s32(McGeneralizedCarveout4ForceInternalAccess2, secure_scratch101);
+ s32(McGeneralizedCarveout4ForceInternalAccess3, secure_scratch102);
+ s32(McGeneralizedCarveout4ForceInternalAccess4, secure_scratch103);
+ s32(McGeneralizedCarveout5ForceInternalAccess0, secure_scratch104);
+ s32(McGeneralizedCarveout5ForceInternalAccess1, secure_scratch105);
+ s32(McGeneralizedCarveout5ForceInternalAccess2, secure_scratch106);
+ s32(McGeneralizedCarveout5ForceInternalAccess3, secure_scratch107);
+
+ c32(0, scratch2);
+ s(PllMInputDivider, 7:0, scratch2, 7:0);
+ s(PllMFeedbackDivider, 7:0, scratch2, 15:8);
+ s(PllMPostDivider, 4:0, scratch2, 20:16);
+ s(PllMKVCO, 0:0, scratch2, 21:21);
+ s(PllMKCP, 1:0, scratch2, 23:22);
+
+ c32(0, scratch35);
+ s(PllMSetupControl, 15:0, scratch35, 15:0);
+
+ c32(0, scratch3);
+ s(PllMInputDivider, 7:0, scratch3, 7:0);
+ c(0x3e, scratch3, 15:8);
+ c(0, scratch3, 20:16);
+ s(PllMKVCO, 0:0, scratch3, 21:21);
+ s(PllMKCP, 1:0, scratch3, 23:22);
+
+ c32(0, scratch36);
+ s(PllMSetupControl, 23:0, scratch36, 23:0);
+
+ c32(0, scratch4);
+ s(PllMStableTime, 9:0, scratch4, 9:0);
+}
diff --git a/fusee/fusee-primary/src/sdram_lz.inl b/fusee/fusee-primary/src/sdram_lz.inl
new file mode 100644
index 000000000..f8f46fbd4
--- /dev/null
+++ b/fusee/fusee-primary/src/sdram_lz.inl
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ *
+ * 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 .
+ */
+
+static const uint8_t _dram_cfg_lz[1262] = {
+ 0x17, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
+ 0x00, 0x2C, 0x17, 0x04, 0x09, 0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08,
+ 0x17, 0x10, 0x10, 0x00, 0x00, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00,
+ 0x00, 0x04, 0xB4, 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00,
+ 0x70, 0x17, 0x10, 0x24, 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40,
+ 0x00, 0x00, 0x00, 0x17, 0x04, 0x04, 0x17, 0x09, 0x18, 0xFF, 0xFF, 0x1F,
+ 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77,
+ 0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08, 0x17, 0x08, 0x08, 0xA6, 0xA6,
+ 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x04,
+ 0x04, 0x04, 0x17, 0x04, 0x04, 0x17, 0x04, 0x3C, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x17, 0x04, 0x04, 0x17, 0x06, 0x06, 0x00, 0x00, 0x04, 0x08, 0x17, 0x06,
+ 0x46, 0xA1, 0x01, 0x00, 0x00, 0x32, 0x17, 0x0B, 0x64, 0x01, 0x17, 0x04,
+ 0x7C, 0x17, 0x07, 0x0C, 0x03, 0x17, 0x04, 0x04, 0x00, 0x00, 0x00, 0x1E,
+ 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13,
+ 0x17, 0x0B, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x17, 0x05, 0x5D, 0x17, 0x07,
+ 0x10, 0x0B, 0x17, 0x07, 0x28, 0x08, 0x17, 0x07, 0x0C, 0x17, 0x04, 0x1C,
+ 0x20, 0x00, 0x00, 0x00, 0x06, 0x17, 0x04, 0x04, 0x17, 0x07, 0x08, 0x17,
+ 0x04, 0x50, 0x17, 0x04, 0x2C, 0x17, 0x04, 0x1C, 0x17, 0x04, 0x10, 0x17,
+ 0x08, 0x6C, 0x17, 0x04, 0x10, 0x17, 0x04, 0x38, 0x17, 0x04, 0x40, 0x05,
+ 0x17, 0x07, 0x1C, 0x17, 0x08, 0x58, 0x17, 0x04, 0x24, 0x17, 0x04, 0x18,
+ 0x17, 0x08, 0x64, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x17, 0x09, 0x0C, 0x17, 0x05, 0x82,
+ 0x58, 0x17, 0x07, 0x61, 0xC1, 0x17, 0x07, 0x50, 0x17, 0x04, 0x04, 0x17,
+ 0x08, 0x81, 0x48, 0x17, 0x04, 0x04, 0x17, 0x04, 0x28, 0x17, 0x04, 0x60,
+ 0x17, 0x08, 0x54, 0x27, 0x17, 0x04, 0x04, 0x17, 0x07, 0x14, 0x17, 0x04,
+ 0x04, 0x04, 0x17, 0x07, 0x81, 0x58, 0x17, 0x0C, 0x0C, 0x1C, 0x03, 0x00,
+ 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x17, 0x04, 0x5A, 0xF3, 0x0C,
+ 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05,
+ 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03,
+ 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02,
+ 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08,
+ 0x24, 0x06, 0x07, 0x9A, 0x12, 0x17, 0x05, 0x83, 0x41, 0x00, 0xFF, 0x17,
+ 0x10, 0x83, 0x6C, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00,
+ 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00,
+ 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x17, 0x04, 0x20, 0x08, 0x08,
+ 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x17, 0x06,
+ 0x2C, 0x11, 0x08, 0x17, 0x10, 0x84, 0x67, 0x15, 0x00, 0xCC, 0x00, 0x0A,
+ 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF,
+ 0x0F, 0xFF, 0x0F, 0x17, 0x08, 0x83, 0x4C, 0x01, 0x03, 0x00, 0x70, 0x00,
+ 0x0C, 0x00, 0x01, 0x17, 0x04, 0x0C, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04,
+ 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x17, 0x04, 0x10, 0xA0, 0x00, 0x2C,
+ 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x17, 0x06, 0x48, 0x08, 0x00,
+ 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28,
+ 0x28, 0x28, 0x17, 0x04, 0x04, 0x11, 0x11, 0x11, 0x11, 0x17, 0x04, 0x04,
+ 0xBE, 0x00, 0x00, 0x17, 0x05, 0x58, 0x17, 0x08, 0x5C, 0x17, 0x22, 0x85,
+ 0x6A, 0x17, 0x1A, 0x1A, 0x14, 0x00, 0x12, 0x00, 0x10, 0x17, 0x05, 0x83,
+ 0x0A, 0x17, 0x16, 0x18, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00,
+ 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x17, 0x05, 0x83, 0x0C, 0x17,
+ 0x04, 0x20, 0x17, 0x18, 0x18, 0x28, 0x00, 0x28, 0x17, 0x04, 0x04, 0x17,
+ 0x08, 0x08, 0x17, 0x10, 0x10, 0x00, 0x14, 0x17, 0x05, 0x5A, 0x17, 0x04,
+ 0x5C, 0x17, 0x04, 0x5E, 0x17, 0x04, 0x0E, 0x17, 0x0E, 0x78, 0x17, 0x09,
+ 0x82, 0x50, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51,
+ 0x17, 0x08, 0x18, 0x80, 0x01, 0x00, 0x00, 0x40, 0x17, 0x04, 0x20, 0x03,
+ 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x17, 0x08, 0x82, 0x58,
+ 0x17, 0x0C, 0x38, 0x17, 0x1B, 0x81, 0x6C, 0x17, 0x08, 0x85, 0x60, 0x17,
+ 0x08, 0x86, 0x50, 0x17, 0x08, 0x86, 0x60, 0x17, 0x06, 0x83, 0x21, 0x22,
+ 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x17, 0x0C, 0x86, 0x74, 0x17, 0x08, 0x2C,
+ 0x8B, 0xFF, 0x07, 0x17, 0x06, 0x81, 0x04, 0x32, 0x54, 0x76, 0x10, 0x47,
+ 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75,
+ 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45,
+ 0x32, 0x67, 0x17, 0x04, 0x24, 0x49, 0x92, 0x24, 0x17, 0x04, 0x04, 0x17,
+ 0x11, 0x7C, 0x1B, 0x17, 0x04, 0x04, 0x17, 0x13, 0x81, 0x14, 0x2F, 0x41,
+ 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x17, 0x04, 0x7C, 0xFF, 0xFF, 0xFF,
+ 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03,
+ 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x17, 0x06, 0x86, 0x59,
+ 0x17, 0x0F, 0x89, 0x14, 0x37, 0x17, 0x07, 0x82, 0x72, 0x10, 0x17, 0x06,
+ 0x83, 0x0D, 0x00, 0x11, 0x01, 0x17, 0x05, 0x85, 0x39, 0x17, 0x04, 0x0E,
+ 0x0A, 0x17, 0x07, 0x89, 0x29, 0x17, 0x04, 0x1B, 0x17, 0x08, 0x86, 0x77,
+ 0x17, 0x09, 0x12, 0x20, 0x00, 0x00, 0x00, 0x81, 0x10, 0x09, 0x28, 0x93,
+ 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x17, 0x18, 0x82, 0x2C, 0xFF,
+ 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0x17, 0x04, 0x04, 0xDC, 0xDC,
+ 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x17, 0x04, 0x04, 0x17, 0x04, 0x04,
+ 0x17, 0x05, 0x82, 0x24, 0x03, 0x07, 0x17, 0x04, 0x04, 0x00, 0x00, 0x24,
+ 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10,
+ 0x9C, 0x4B, 0x17, 0x04, 0x64, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00,
+ 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x17, 0x06, 0x85, 0x60, 0x17,
+ 0x10, 0x82, 0x74, 0x17, 0x08, 0x08, 0x17, 0x08, 0x88, 0x00, 0x17, 0x04,
+ 0x10, 0x04, 0x17, 0x0B, 0x87, 0x6C, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02,
+ 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x17, 0x08, 0x8B, 0x18,
+ 0x1F, 0x17, 0x09, 0x81, 0x73, 0x00, 0xFF, 0x00, 0xFF, 0x17, 0x05, 0x86,
+ 0x48, 0x17, 0x04, 0x0C, 0x17, 0x07, 0x86, 0x34, 0x00, 0x00, 0xF0, 0x17,
+ 0x09, 0x87, 0x54, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x17, 0x0C, 0x81,
+ 0x52, 0x17, 0x0A, 0x1C, 0x17, 0x10, 0x81, 0x6C, 0x17, 0x0A, 0x82, 0x21,
+ 0x17, 0x07, 0x82, 0x4D, 0x17, 0x0A, 0x8A, 0x1B, 0x17, 0x11, 0x2C, 0x76,
+ 0x0C, 0x17, 0x0A, 0x8A, 0x67, 0x17, 0x0F, 0x84, 0x28, 0x17, 0x06, 0x34,
+ 0x17, 0x17, 0x3A, 0x7E, 0x16, 0x40, 0x17, 0x0C, 0x8B, 0x1F, 0x17, 0x2A,
+ 0x38, 0x1E, 0x17, 0x0A, 0x38, 0x17, 0x13, 0x81, 0x28, 0x00, 0xC0, 0x17,
+ 0x17, 0x55, 0x46, 0x24, 0x17, 0x0A, 0x81, 0x28, 0x17, 0x14, 0x38, 0x17,
+ 0x18, 0x81, 0x60, 0x46, 0x2C, 0x17, 0x06, 0x38, 0xEC, 0x17, 0x0D, 0x16,
+ 0x17, 0x0E, 0x82, 0x3C, 0x17, 0x82, 0x0C, 0x8E, 0x68, 0x17, 0x04, 0x24,
+ 0x17, 0x5C, 0x8E, 0x68, 0x17, 0x07, 0x82, 0x5F, 0x80, 0x17, 0x87, 0x01,
+ 0x8E, 0x68, 0x02, 0x17, 0x81, 0x4A, 0x8E, 0x68, 0x17, 0x0C, 0x87, 0x78,
+ 0x17, 0x85, 0x28, 0x8E, 0x68, 0x17, 0x8E, 0x68, 0x9D, 0x50, 0x17, 0x81,
+ 0x24, 0x8E, 0x68, 0x17, 0x04, 0x2C, 0x17, 0x28, 0x8E, 0x68, 0x17, 0x04,
+ 0x30, 0x17, 0x85, 0x3C, 0x8E, 0x68, 0x12, 0x17, 0x07, 0x85, 0x70, 0x17,
+ 0x88, 0x74, 0x8E, 0x68, 0x17, 0x87, 0x3E, 0x9D, 0x50, 0x0C, 0x17, 0x04,
+ 0x04, 0x17, 0x12, 0x8E, 0x68, 0x18, 0x17, 0x87, 0x12, 0xBB, 0x20, 0x17,
+ 0x83, 0x04, 0x9D, 0x50, 0x15, 0x17, 0x05, 0x8D, 0x76, 0x17, 0x0F, 0x8B,
+ 0x49, 0x17, 0x0B, 0x18, 0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00,
+ 0x34, 0x00, 0x36, 0x00, 0x2F, 0x00, 0x33, 0x17, 0x09, 0x84, 0x0C, 0x17,
+ 0x18, 0x18, 0x17, 0x20, 0x8E, 0x68, 0x15, 0x17, 0x07, 0x5A, 0x17, 0x06,
+ 0x5E, 0x16, 0x00, 0x15, 0x17, 0x82, 0x40, 0x9D, 0x50, 0x17, 0x86, 0x5F,
+ 0xBB, 0x20, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x17, 0x81, 0x4F, 0xAC, 0x38,
+ 0x3B, 0x17, 0x04, 0x04, 0x17, 0x86, 0x30, 0x8E, 0x68, 0x17, 0x81, 0x53,
+ 0xAC, 0x38, 0x07, 0x17, 0x0D, 0x8E, 0x68, 0xA3, 0x72, 0x17, 0x83, 0x10,
+ 0x8E, 0x68
+};
diff --git a/fusee/fusee-primary/src/sdram_param_t210.h b/fusee/fusee-primary/src/sdram_param_t210.h
new file mode 100644
index 000000000..328ee5109
--- /dev/null
+++ b/fusee/fusee-primary/src/sdram_param_t210.h
@@ -0,0 +1,933 @@
+/*
+ * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * 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 .
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ */
+
+/**
+ * Defines the SDRAM parameter structure.
+ *
+ * Note that PLLM is used by EMC.
+ */
+
+#ifndef _SDRAM_PARAM_T210_H_
+#define _SDRAM_PARAM_T210_H_
+
+#include
+
+#define MEMORY_TYPE_NONE 0
+#define MEMORY_TYPE_DDR 0
+#define MEMORY_TYPE_LPDDR 0
+#define MEMORY_TYPE_DDR2 0
+#define MEMORY_TYPE_LPDDR2 1
+#define MEMORY_TYPE_DDR3 2
+#define MEMORY_TYPE_LPDDR4 3
+
+/**
+ * Defines the SDRAM parameter structure
+ */
+typedef struct _sdram_params
+{
+ /* Specifies the type of memory device */
+ uint32_t memory_type;
+
+ /* MC/EMC clock source configuration */
+
+ /* Specifies the M value for PllM */
+ uint32_t pllm_input_divider;
+ /* Specifies the N value for PllM */
+ uint32_t pllm_feedback_divider;
+ /* Specifies the time to wait for PLLM to lock (in microseconds) */
+ uint32_t pllm_stable_time;
+ /* Specifies misc. control bits */
+ uint32_t pllm_setup_control;
+ /* Specifies the P value for PLLM */
+ uint32_t pllm_post_divider;
+ /* Specifies value for Charge Pump Gain Control */
+ uint32_t pllm_kcp;
+ /* Specifies VCO gain */
+ uint32_t pllm_kvco;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare0;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare1;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare2;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare3;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare4;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare5;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare6;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare7;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare8;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare9;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare10;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare11;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare12;
+ /* Spare BCT param */
+ uint32_t emc_bct_spare13;
+
+ /* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
+ uint32_t emc_clock_source;
+ uint32_t emc_clock_source_dll;
+
+ /* Defines possible override for PLLLM_MISC2 */
+ uint32_t clk_rst_pllm_misc20_override;
+ /* enables override for PLLLM_MISC2 */
+ uint32_t clk_rst_pllm_misc20_override_enable;
+ /* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
+ uint32_t clear_clock2_mc1;
+
+ /* Auto-calibration of EMC pads */
+
+ /* Specifies the value for EMC_AUTO_CAL_INTERVAL */
+ uint32_t emc_auto_cal_interval;
+ /*
+ * Specifies the value for EMC_AUTO_CAL_CONFIG
+ * Note: Trigger bits are set by the SDRAM code.
+ */
+ uint32_t emc_auto_cal_config;
+
+ /* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
+ uint32_t emc_auto_cal_config2;
+
+ /* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
+ uint32_t emc_auto_cal_config3;
+
+ uint32_t emc_auto_cal_config4;
+ uint32_t emc_auto_cal_config5;
+ uint32_t emc_auto_cal_config6;
+ uint32_t emc_auto_cal_config7;
+ uint32_t emc_auto_cal_config8;
+ /* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
+ uint32_t emc_auto_cal_vref_sel0;
+ uint32_t emc_auto_cal_vref_sel1;
+
+ /* Specifies the value for EMC_AUTO_CAL_CHANNEL */
+ uint32_t emc_auto_cal_channel;
+
+ /* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
+ uint32_t emc_pmacro_auto_cal_cfg0;
+ uint32_t emc_pmacro_auto_cal_cfg1;
+ uint32_t emc_pmacro_auto_cal_cfg2;
+
+ uint32_t emc_pmacro_rx_term;
+ uint32_t emc_pmacro_dq_tx_drive;
+ uint32_t emc_pmacro_ca_tx_drive;
+ uint32_t emc_pmacro_cmd_tx_drive;
+ uint32_t emc_pmacro_auto_cal_common;
+ uint32_t emc_pmacro_zcrtl;
+
+ /*
+ * Specifies the time for the calibration
+ * to stabilize (in microseconds)
+ */
+ uint32_t emc_auto_cal_wait;
+
+ uint32_t emc_xm2_comp_pad_ctrl;
+ uint32_t emc_xm2_comp_pad_ctrl2;
+ uint32_t emc_xm2_comp_pad_ctrl3;
+
+ /*
+ * DRAM size information
+ * Specifies the value for EMC_ADR_CFG
+ */
+ uint32_t emc_adr_cfg;
+
+ /*
+ * Specifies the time to wait after asserting pin
+ * CKE (in microseconds)
+ */
+ uint32_t emc_pin_program_wait;
+ /* Specifies the extra delay before/after pin RESET/CKE command */
+ uint32_t emc_pin_extra_wait;
+
+ uint32_t emc_pin_gpio_enable;
+ uint32_t emc_pin_gpio;
+
+ /*
+ * Specifies the extra delay after the first writing
+ * of EMC_TIMING_CONTROL
+ */
+ uint32_t emc_timing_control_wait;
+
+ /* Timing parameters required for the SDRAM */
+
+ /* Specifies the value for EMC_RC */
+ uint32_t emc_rc;
+ /* Specifies the value for EMC_RFC */
+ uint32_t emc_rfc;
+
+ uint32_t emc_rfc_pb;
+ uint32_t emc_ref_ctrl2;
+
+ /* Specifies the value for EMC_RFC_SLR */
+ uint32_t emc_rfc_slr;
+ /* Specifies the value for EMC_RAS */
+ uint32_t emc_ras;
+ /* Specifies the value for EMC_RP */
+ uint32_t emc_rp;
+ /* Specifies the value for EMC_R2R */
+ uint32_t emc_r2r;
+ /* Specifies the value for EMC_W2W */
+ uint32_t emc_w2w;
+ /* Specifies the value for EMC_R2W */
+ uint32_t emc_r2w;
+ /* Specifies the value for EMC_W2R */
+ uint32_t emc_w2r;
+ /* Specifies the value for EMC_R2P */
+ uint32_t emc_r2p;
+ /* Specifies the value for EMC_W2P */
+ uint32_t emc_w2p;
+ /* Specifies the value for EMC_RD_RCD */
+
+ uint32_t emc_tppd;
+ uint32_t emc_ccdmw;
+
+ uint32_t emc_rd_rcd;
+ /* Specifies the value for EMC_WR_RCD */
+ uint32_t emc_wr_rcd;
+ /* Specifies the value for EMC_RRD */
+ uint32_t emc_rrd;
+ /* Specifies the value for EMC_REXT */
+ uint32_t emc_rext;
+ /* Specifies the value for EMC_WEXT */
+ uint32_t emc_wext;
+ /* Specifies the value for EMC_WDV */
+ uint32_t emc_wdv;
+
+ uint32_t emc_wdv_chk;
+ uint32_t emc_wsv;
+ uint32_t emc_wev;
+
+ /* Specifies the value for EMC_WDV_MASK */
+ uint32_t emc_wdv_mask;
+
+ uint32_t emc_ws_duration;
+ uint32_t emc_we_duration;
+
+ /* Specifies the value for EMC_QUSE */
+ uint32_t emc_quse;
+ /* Specifies the value for EMC_QUSE_WIDTH */
+ uint32_t emc_quse_width;
+ /* Specifies the value for EMC_IBDLY */
+ uint32_t emc_ibdly;
+
+ uint32_t emc_obdly;
+
+ /* Specifies the value for EMC_EINPUT */
+ uint32_t emc_einput;
+ /* Specifies the value for EMC_EINPUT_DURATION */
+ uint32_t emc_einput_duration;
+ /* Specifies the value for EMC_PUTERM_EXTRA */
+ uint32_t emc_puterm_extra;
+ /* Specifies the value for EMC_PUTERM_WIDTH */
+ uint32_t emc_puterm_width;
+
+ uint32_t emc_qrst;
+ uint32_t emc_qsafe;
+ uint32_t emc_rdv;
+ uint32_t emc_rdv_mask;
+
+ uint32_t emc_rdv_early;
+ uint32_t emc_rdv_early_mask;
+
+ /* Specifies the value for EMC_QPOP */
+ uint32_t emc_qpop;
+
+ /* Specifies the value for EMC_REFRESH */
+ uint32_t emc_refresh;
+ /* Specifies the value for EMC_BURST_REFRESH_NUM */
+ uint32_t emc_burst_refresh_num;
+ /* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
+ uint32_t emc_prerefresh_req_cnt;
+ /* Specifies the value for EMC_PDEX2WR */
+ uint32_t emc_pdex2wr;
+ /* Specifies the value for EMC_PDEX2RD */
+ uint32_t emc_pdex2rd;
+ /* Specifies the value for EMC_PCHG2PDEN */
+ uint32_t emc_pchg2pden;
+ /* Specifies the value for EMC_ACT2PDEN */
+ uint32_t emc_act2pden;
+ /* Specifies the value for EMC_AR2PDEN */
+ uint32_t emc_ar2pden;
+ /* Specifies the value for EMC_RW2PDEN */
+ uint32_t emc_rw2pden;
+
+ uint32_t emc_cke2pden;
+ uint32_t emc_pdex2che;
+ uint32_t emc_pdex2mrr;
+
+ /* Specifies the value for EMC_TXSR */
+ uint32_t emc_txsr;
+ /* Specifies the value for EMC_TXSRDLL */
+ uint32_t emc_txsr_dll;
+ /* Specifies the value for EMC_TCKE */
+ uint32_t emc_tcke;
+ /* Specifies the value for EMC_TCKESR */
+ uint32_t emc_tckesr;
+ /* Specifies the value for EMC_TPD */
+ uint32_t emc_tpd;
+ /* Specifies the value for EMC_TFAW */
+ uint32_t emc_tfaw;
+ /* Specifies the value for EMC_TRPAB */
+ uint32_t emc_trpab;
+ /* Specifies the value for EMC_TCLKSTABLE */
+ uint32_t emc_tclkstable;
+ /* Specifies the value for EMC_TCLKSTOP */
+ uint32_t emc_tclkstop;
+ /* Specifies the value for EMC_TREFBW */
+ uint32_t emc_trefbw;
+
+ /* FBIO configuration values */
+
+ /* Specifies the value for EMC_FBIO_CFG5 */
+ uint32_t emc_fbio_cfg5;
+ /* Specifies the value for EMC_FBIO_CFG7 */
+ uint32_t emc_fbio_cfg7;
+ uint32_t emc_fbio_cfg8;
+
+ /* Command mapping for CMD brick 0 */
+ uint32_t emc_cmd_mapping_cmd0_0;
+ uint32_t emc_cmd_mapping_cmd0_1;
+ uint32_t emc_cmd_mapping_cmd0_2;
+ uint32_t emc_cmd_mapping_cmd1_0;
+ uint32_t emc_cmd_mapping_cmd1_1;
+ uint32_t emc_cmd_mapping_cmd1_2;
+ uint32_t emc_cmd_mapping_cmd2_0;
+ uint32_t emc_cmd_mapping_cmd2_1;
+ uint32_t emc_cmd_mapping_cmd2_2;
+ uint32_t emc_cmd_mapping_cmd3_0;
+ uint32_t emc_cmd_mapping_cmd3_1;
+ uint32_t emc_cmd_mapping_cmd3_2;
+ uint32_t emc_cmd_mapping_byte;
+
+ /* Specifies the value for EMC_FBIO_SPARE */
+ uint32_t emc_fbio_spare;
+
+ /* Specifies the value for EMC_CFG_RSV */
+ uint32_t emc_cfg_rsv;
+
+ /* MRS command values */
+
+ /* Specifies the value for EMC_MRS */
+ uint32_t emc_mrs;
+ /* Specifies the MP0 command to initialize mode registers */
+ uint32_t emc_emrs;
+ /* Specifies the MP2 command to initialize mode registers */
+ uint32_t emc_emrs2;
+ /* Specifies the MP3 command to initialize mode registers */
+ uint32_t emc_emrs3;
+ /* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
+ uint32_t emc_mrw1;
+ /* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
+ uint32_t emc_mrw2;
+ /* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
+ uint32_t emc_mrw3;
+ /* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
+ uint32_t emc_mrw4;
+
+ /* Specifies the programming to LPDDR4 Mode Register 3 at cold boot */
+ uint32_t emc_mrw6;
+ /* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
+ uint32_t emc_mrw8;
+ /* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
+ uint32_t emc_mrw9;
+ /* Specifies the programming to LPDDR4 Mode Register 12 at cold boot */
+ uint32_t emc_mrw10;
+ /* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
+ uint32_t emc_mrw12;
+ /* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
+ uint32_t emc_mrw13;
+ /* Specifies the programming to LPDDR4 Mode Register 22 at cold boot */
+ uint32_t emc_mrw14;
+
+ /*
+ * Specifies the programming to extra LPDDR2 Mode Register
+ * at cold boot
+ */
+ uint32_t emc_mrw_extra;
+ /*
+ * Specifies the programming to extra LPDDR2 Mode Register
+ * at warm boot
+ */
+ uint32_t emc_warm_boot_mrw_extra;
+ /*
+ * Specify the enable of extra Mode Register programming at
+ * warm boot
+ */
+ uint32_t emc_warm_boot_extramode_reg_write_enable;
+ /*
+ * Specify the enable of extra Mode Register programming at
+ * cold boot
+ */
+ uint32_t emc_extramode_reg_write_enable;
+
+ /* Specifies the EMC_MRW reset command value */
+ uint32_t emc_mrw_reset_command;
+ /* Specifies the EMC Reset wait time (in microseconds) */
+ uint32_t emc_mrw_reset_ninit_wait;
+ /* Specifies the value for EMC_MRS_WAIT_CNT */
+ uint32_t emc_mrs_wait_cnt;
+ /* Specifies the value for EMC_MRS_WAIT_CNT2 */
+ uint32_t emc_mrs_wait_cnt2;
+
+ /* EMC miscellaneous configurations */
+
+ /* Specifies the value for EMC_CFG */
+ uint32_t emc_cfg;
+ /* Specifies the value for EMC_CFG_2 */
+ uint32_t emc_cfg2;
+ /* Specifies the pipe bypass controls */
+ uint32_t emc_cfg_pipe;
+
+ uint32_t emc_cfg_pipe_clk;
+ uint32_t emc_fdpd_ctrl_cmd_no_ramp;
+ uint32_t emc_cfg_update;
+
+ /* Specifies the value for EMC_DBG */
+ uint32_t emc_dbg;
+
+ uint32_t emc_dbg_write_mux;
+
+ /* Specifies the value for EMC_CMDQ */
+ uint32_t emc_cmd_q;
+ /* Specifies the value for EMC_MC2EMCQ */
+ uint32_t emc_mc2emc_q;
+ /* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
+ uint32_t emc_dyn_self_ref_control;
+
+ /* Specifies the value for MEM_INIT_DONE */
+ uint32_t ahb_arbitration_xbar_ctrl_meminit_done;
+
+ /* Specifies the value for EMC_CFG_DIG_DLL */
+ uint32_t emc_cfg_dig_dll;
+ uint32_t emc_cfg_dig_dll_1;
+
+ /* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
+ uint32_t emc_cfg_dig_dll_period;
+ /* Specifies the value of *DEV_SELECTN of various EMC registers */
+ uint32_t emc_dev_select;
+
+ /* Specifies the value for EMC_SEL_DPD_CTRL */
+ uint32_t emc_sel_dpd_ctrl;
+
+ /* Pads trimmer delays */
+ uint32_t emc_fdpd_ctrl_dq;
+ uint32_t emc_fdpd_ctrl_cmd;
+ uint32_t emc_pmacro_ib_vref_dq_0;
+ uint32_t emc_pmacro_ib_vref_dq_1;
+ uint32_t emc_pmacro_ib_vref_dqs_0;
+ uint32_t emc_pmacro_ib_vref_dqs_1;
+ uint32_t emc_pmacro_ib_rxrt;
+ uint32_t emc_cfg_pipe1;
+ uint32_t emc_cfg_pipe2;
+
+ /* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
+ uint32_t emc_pmacro_quse_ddll_rank0_0;
+ uint32_t emc_pmacro_quse_ddll_rank0_1;
+ uint32_t emc_pmacro_quse_ddll_rank0_2;
+ uint32_t emc_pmacro_quse_ddll_rank0_3;
+ uint32_t emc_pmacro_quse_ddll_rank0_4;
+ uint32_t emc_pmacro_quse_ddll_rank0_5;
+ uint32_t emc_pmacro_quse_ddll_rank1_0;
+ uint32_t emc_pmacro_quse_ddll_rank1_1;
+ uint32_t emc_pmacro_quse_ddll_rank1_2;
+ uint32_t emc_pmacro_quse_ddll_rank1_3;
+ uint32_t emc_pmacro_quse_ddll_rank1_4;
+ uint32_t emc_pmacro_quse_ddll_rank1_5;
+
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank0_0;
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank0_1;
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank0_2;
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank0_3;
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank0_4;
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank0_5;
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank1_0;
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank1_1;
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank1_2;
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank1_3;
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank1_4;
+ uint32_t emc_pmacro_ob_ddll_long_dq_rank1_5;
+
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_0;
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_1;
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_2;
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_3;
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_4;
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank0_5;
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_0;
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_1;
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_2;
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_3;
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_4;
+ uint32_t emc_pmacro_ob_ddll_long_dqs_rank1_5;
+
+ uint32_t emc_pmacro_ib_ddll_long_dqs_rank0_0;
+ uint32_t emc_pmacro_ib_ddll_long_dqs_rank0_1;
+ uint32_t emc_pmacro_ib_ddll_long_dqs_rank0_2;
+ uint32_t emc_pmacro_ib_ddll_long_dqs_rank0_3;
+ uint32_t emc_pmacro_ib_ddll_long_dqs_rank1_0;
+ uint32_t emc_pmacro_ib_ddll_long_dqs_rank1_1;
+ uint32_t emc_pmacro_ib_ddll_long_dqs_rank1_2;
+ uint32_t emc_pmacro_ib_ddll_long_dqs_rank1_3;
+
+ uint32_t emc_pmacro_ddll_long_cmd_0;
+ uint32_t emc_pmacro_ddll_long_cmd_1;
+ uint32_t emc_pmacro_ddll_long_cmd_2;
+ uint32_t emc_pmacro_ddll_long_cmd_3;
+ uint32_t emc_pmacro_ddll_long_cmd_4;
+ uint32_t emc_pmacro_ddll_short_cmd_0;
+ uint32_t emc_pmacro_ddll_short_cmd_1;
+ uint32_t emc_pmacro_ddll_short_cmd_2;
+
+ /*
+ * Specifies the delay after asserting CKE pin during a WarmBoot0
+ * sequence (in microseconds)
+ */
+ uint32_t warm_boot_wait;
+
+ /* Specifies the value for EMC_ODT_WRITE */
+ uint32_t emc_odt_write;
+
+ /* Periodic ZQ calibration */
+
+ /*
+ * Specifies the value for EMC_ZCAL_INTERVAL
+ * Value 0 disables ZQ calibration
+ */
+ uint32_t emc_zcal_interval;
+ /* Specifies the value for EMC_ZCAL_WAIT_CNT */
+ uint32_t emc_zcal_wait_cnt;
+ /* Specifies the value for EMC_ZCAL_MRW_CMD */
+ uint32_t emc_zcal_mrw_cmd;
+
+ /* DRAM initialization sequence flow control */
+
+ /* Specifies the MRS command value for resetting DLL */
+ uint32_t emc_mrs_reset_dll;
+ /* Specifies the command for ZQ initialization of device 0 */
+ uint32_t emc_zcal_init_dev0;
+ /* Specifies the command for ZQ initialization of device 1 */
+ uint32_t emc_zcal_init_dev1;
+ /*
+ * Specifies the wait time after programming a ZQ initialization
+ * command (in microseconds)
+ */
+ uint32_t emc_zcal_init_wait;
+ /*
+ * Specifies the enable for ZQ calibration at cold boot [bit 0]
+ * and warm boot [bit 1]
+ */
+ uint32_t emc_zcal_warm_cold_boot_enables;
+
+ /*
+ * Specifies the MRW command to LPDDR2 for ZQ calibration
+ * on warmboot
+ */
+ /* Is issued to both devices separately */
+ uint32_t emc_mrw_lpddr2zcal_warm_boot;
+ /*
+ * Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
+ * Is issued to both devices separately
+ */
+ uint32_t emc_zqcal_ddr3_warm_boot;
+
+ uint32_t emc_zqcal_lpddr4_warm_boot;
+
+ /*
+ * Specifies the wait time for ZQ calibration on warmboot
+ * (in microseconds)
+ */
+ uint32_t emc_zcal_warm_boot_wait;
+ /*
+ * Specifies the enable for DRAM Mode Register programming
+ * at warm boot
+ */
+ uint32_t emc_mrs_warm_boot_enable;
+ /*
+ * Specifies the wait time after sending an MRS DLL reset command
+ * in microseconds)
+ */
+ uint32_t emc_mrs_reset_dll_wait;
+ /* Specifies the extra MRS command to initialize mode registers */
+ uint32_t emc_mrs_extra;
+ /* Specifies the extra MRS command at warm boot */
+ uint32_t emc_warm_boot_mrs_extra;
+ /* Specifies the EMRS command to enable the DDR2 DLL */
+ uint32_t emc_emrs_ddr2_dll_enable;
+ /* Specifies the MRS command to reset the DDR2 DLL */
+ uint32_t emc_mrs_ddr2_dll_reset;
+ /* Specifies the EMRS command to set OCD calibration */
+ uint32_t emc_emrs_ddr2_ocd_calib;
+ /*
+ * Specifies the wait between initializing DDR and setting OCD
+ * calibration (in microseconds)
+ */
+ uint32_t emc_ddr2_wait;
+ /* Specifies the value for EMC_CLKEN_OVERRIDE */
+ uint32_t emc_clken_override;
+ /*
+ * Specifies LOG2 of the extra refresh numbers after booting
+ * Program 0 to disable
+ */
+ uint32_t emc_extra_refresh_num;
+ /* Specifies the master override for all EMC clocks */
+ uint32_t emc_clken_override_allwarm_boot;
+ /* Specifies the master override for all MC clocks */
+ uint32_t mc_clken_override_allwarm_boot;
+ /* Specifies digital dll period, choosing between 4 to 64 ms */
+ uint32_t emc_cfg_dig_dll_period_warm_boot;
+
+ /* Pad controls */
+
+ /* Specifies the value for PMC_VDDP_SEL */
+ uint32_t pmc_vddp_sel;
+ /* Specifies the wait time after programming PMC_VDDP_SEL */
+ uint32_t pmc_vddp_sel_wait;
+ /* Specifies the value for PMC_DDR_PWR */
+ uint32_t pmc_ddr_pwr;
+ /* Specifies the value for PMC_DDR_CFG */
+ uint32_t pmc_ddr_cfg;
+ /* Specifies the value for PMC_IO_DPD3_REQ */
+ uint32_t pmc_io_dpd3_req;
+ /* Specifies the wait time after programming PMC_IO_DPD3_REQ */
+ uint32_t pmc_io_dpd3_req_wait;
+
+ uint32_t pmc_io_dpd4_req_wait;
+
+ /* Specifies the value for PMC_REG_SHORT */
+ uint32_t pmc_reg_short;
+ /* Specifies the value for PMC_NO_IOPOWER */
+ uint32_t pmc_no_io_power;
+
+ uint32_t pmc_ddr_ctrl_wait;
+ uint32_t pmc_ddr_ctrl;
+
+ /* Specifies the value for EMC_ACPD_CONTROL */
+ uint32_t emc_acpd_control;
+
+ /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
+ uint32_t emc_swizzle_rank0_byte0;
+ /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
+ uint32_t emc_swizzle_rank0_byte1;
+ /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
+ uint32_t emc_swizzle_rank0_byte2;
+ /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
+ uint32_t emc_swizzle_rank0_byte3;
+ /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
+ uint32_t emc_swizzle_rank1_byte0;
+ /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
+ uint32_t emc_swizzle_rank1_byte1;
+ /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
+ uint32_t emc_swizzle_rank1_byte2;
+ /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
+ uint32_t emc_swizzle_rank1_byte3;
+
+ /* Specifies the value for EMC_TXDSRVTTGEN */
+ uint32_t emc_txdsrvttgen;
+
+ /* Specifies the value for EMC_DATA_BRLSHFT_0 */
+ uint32_t emc_data_brlshft0;
+ uint32_t emc_data_brlshft1;
+
+ uint32_t emc_dqs_brlshft0;
+ uint32_t emc_dqs_brlshft1;
+
+ uint32_t emc_cmd_brlshft0;
+ uint32_t emc_cmd_brlshft1;
+ uint32_t emc_cmd_brlshft2;
+ uint32_t emc_cmd_brlshft3;
+
+ uint32_t emc_quse_brlshft0;
+ uint32_t emc_quse_brlshft1;
+ uint32_t emc_quse_brlshft2;
+ uint32_t emc_quse_brlshft3;
+
+ uint32_t emc_dll_cfg0;
+ uint32_t emc_dll_cfg1;
+
+ uint32_t emc_pmc_scratch1;
+ uint32_t emc_pmc_scratch2;
+ uint32_t emc_pmc_scratch3;
+
+ uint32_t emc_pmacro_pad_cfg_ctrl;
+
+ uint32_t emc_pmacro_vttgen_ctrl0;
+ uint32_t emc_pmacro_vttgen_ctrl1;
+ uint32_t emc_pmacro_vttgen_ctrl2;
+
+ uint32_t emc_pmacro_brick_ctrl_rfu1;
+ uint32_t emc_pmacro_cmd_brick_ctrl_fdpd;
+ uint32_t emc_pmacro_brick_ctrl_rfu2;
+ uint32_t emc_pmacro_data_brick_ctrl_fdpd;
+ uint32_t emc_pmacro_bg_bias_ctrl0;
+ uint32_t emc_pmacro_data_pad_rx_ctrl;
+ uint32_t emc_pmacro_cmd_pad_rx_ctrl;
+ uint32_t emc_pmacro_data_rx_term_mode;
+ uint32_t emc_pmacro_cmd_rx_term_mode;
+ uint32_t emc_pmacro_data_pad_tx_ctrl;
+ uint32_t emc_pmacro_common_pad_tx_ctrl;
+ uint32_t emc_pmacro_cmd_pad_tx_ctrl;
+ uint32_t emc_cfg3;
+
+ uint32_t emc_pmacro_tx_pwrd0;
+ uint32_t emc_pmacro_tx_pwrd1;
+ uint32_t emc_pmacro_tx_pwrd2;
+ uint32_t emc_pmacro_tx_pwrd3;
+ uint32_t emc_pmacro_tx_pwrd4;
+ uint32_t emc_pmacro_tx_pwrd5;
+
+ uint32_t emc_config_sample_delay;
+
+ uint32_t emc_pmacro_brick_mapping0;
+ uint32_t emc_pmacro_brick_mapping1;
+ uint32_t emc_pmacro_brick_mapping2;
+
+ uint32_t emc_pmacro_tx_sel_clk_src0;
+ uint32_t emc_pmacro_tx_sel_clk_src1;
+ uint32_t emc_pmacro_tx_sel_clk_src2;
+ uint32_t emc_pmacro_tx_sel_clk_src3;
+ uint32_t emc_pmacro_tx_sel_clk_src4;
+ uint32_t emc_pmacro_tx_sel_clk_src5;
+
+ uint32_t emc_pmacro_ddll_bypass;
+
+ uint32_t emc_pmacro_ddll_pwrd0;
+ uint32_t emc_pmacro_ddll_pwrd1;
+ uint32_t emc_pmacro_ddll_pwrd2;
+
+ uint32_t emc_pmacro_cmd_ctrl0;
+ uint32_t emc_pmacro_cmd_ctrl1;
+ uint32_t emc_pmacro_cmd_ctrl2;
+
+ /* DRAM size information */
+
+ /* Specifies the value for MC_EMEM_ADR_CFG */
+ uint32_t mc_emem_adr_cfg;
+ /* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
+ uint32_t mc_emem_adr_cfg_dev0;
+ /* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
+ uint32_t mc_emem_adr_cfg_dev1;
+
+ uint32_t mc_emem_adr_cfg_channel_mask;
+
+ /* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG0 */
+ uint32_t mc_emem_adr_cfg_bank_mask0;
+ /* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
+ uint32_t mc_emem_adr_cfg_bank_mask1;
+ /* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
+ uint32_t mc_emem_adr_cfg_bank_mask2;
+
+ /*
+ * Specifies the value for MC_EMEM_CFG which holds the external memory
+ * size (in KBytes)
+ */
+ uint32_t mc_emem_cfg;
+
+ /* MC arbitration configuration */
+
+ /* Specifies the value for MC_EMEM_ARB_CFG */
+ uint32_t mc_emem_arb_cfg;
+ /* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
+ uint32_t mc_emem_arb_outstanding_req;
+
+ uint32_t emc_emem_arb_refpb_hp_ctrl;
+ uint32_t emc_emem_arb_refpb_bank_ctrl;
+
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
+ uint32_t mc_emem_arb_timing_rcd;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RP */
+ uint32_t mc_emem_arb_timing_rp;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RC */
+ uint32_t mc_emem_arb_timing_rc;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
+ uint32_t mc_emem_arb_timing_ras;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
+ uint32_t mc_emem_arb_timing_faw;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
+ uint32_t mc_emem_arb_timing_rrd;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
+ uint32_t mc_emem_arb_timing_rap2pre;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
+ uint32_t mc_emem_arb_timing_wap2pre;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
+ uint32_t mc_emem_arb_timing_r2r;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
+ uint32_t mc_emem_arb_timing_w2w;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
+ uint32_t mc_emem_arb_timing_r2w;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
+ uint32_t mc_emem_arb_timing_w2r;
+
+ uint32_t mc_emem_arb_timing_rfcpb;
+
+ /* Specifies the value for MC_EMEM_ARB_DA_TURNS */
+ uint32_t mc_emem_arb_da_turns;
+ /* Specifies the value for MC_EMEM_ARB_DA_COVERS */
+ uint32_t mc_emem_arb_da_covers;
+ /* Specifies the value for MC_EMEM_ARB_MISC0 */
+ uint32_t mc_emem_arb_misc0;
+ /* Specifies the value for MC_EMEM_ARB_MISC1 */
+ uint32_t mc_emem_arb_misc1;
+ uint32_t mc_emem_arb_misc2;
+
+ /* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
+ uint32_t mc_emem_arb_ring1_throttle;
+ /* Specifies the value for MC_EMEM_ARB_OVERRIDE */
+ uint32_t mc_emem_arb_override;
+ /* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
+ uint32_t mc_emem_arb_override1;
+ /* Specifies the value for MC_EMEM_ARB_RSV */
+ uint32_t mc_emem_arb_rsv;
+
+ uint32_t mc_da_cfg0;
+ uint32_t mc_emem_arb_timing_ccdmw;
+
+ /* Specifies the value for MC_CLKEN_OVERRIDE */
+ uint32_t mc_clken_override;
+
+ /* Specifies the value for MC_STAT_CONTROL */
+ uint32_t mc_stat_control;
+ /* Specifies the value for MC_VIDEO_PROTECT_BOM */
+ uint32_t mc_video_protect_bom;
+ /* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
+ uint32_t mc_video_protect_bom_adr_hi;
+ /* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
+ uint32_t mc_video_protect_size_mb;
+ /* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
+ uint32_t mc_video_protect_vpr_override;
+ /* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
+ uint32_t mc_video_protect_vpr_override1;
+ /* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
+ uint32_t mc_video_protect_gpu_override0;
+ /* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
+ uint32_t mc_video_protect_gpu_override1;
+ /* Specifies the value for MC_SEC_CARVEOUT_BOM */
+ uint32_t mc_sec_carveout_bom;
+ /* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
+ uint32_t mc_sec_carveout_adr_hi;
+ /* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
+ uint32_t mc_sec_carveout_size_mb;
+ /* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.VIDEO_PROTECT_WRITE_ACCESS */
+ uint32_t mc_video_protect_write_access;
+ /* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.SEC_CARVEOUT_WRITE_ACCESS */
+ uint32_t mc_sec_carveout_protect_write_access;
+
+ uint32_t mc_generalized_carveout1_bom;
+ uint32_t mc_generalized_carveout1_bom_hi;
+ uint32_t mc_generalized_carveout1_size_128kb;
+ uint32_t mc_generalized_carveout1_access0;
+ uint32_t mc_generalized_carveout1_access1;
+ uint32_t mc_generalized_carveout1_access2;
+ uint32_t mc_generalized_carveout1_access3;
+ uint32_t mc_generalized_carveout1_access4;
+ uint32_t mc_generalized_carveout1_force_internal_access0;
+ uint32_t mc_generalized_carveout1_force_internal_access1;
+ uint32_t mc_generalized_carveout1_force_internal_access2;
+ uint32_t mc_generalized_carveout1_force_internal_access3;
+ uint32_t mc_generalized_carveout1_force_internal_access4;
+ uint32_t mc_generalized_carveout1_cfg0;
+
+ uint32_t mc_generalized_carveout2_bom;
+ uint32_t mc_generalized_carveout2_bom_hi;
+ uint32_t mc_generalized_carveout2_size_128kb;
+ uint32_t mc_generalized_carveout2_access0;
+ uint32_t mc_generalized_carveout2_access1;
+ uint32_t mc_generalized_carveout2_access2;
+ uint32_t mc_generalized_carveout2_access3;
+ uint32_t mc_generalized_carveout2_access4;
+ uint32_t mc_generalized_carveout2_force_internal_access0;
+ uint32_t mc_generalized_carveout2_force_internal_access1;
+ uint32_t mc_generalized_carveout2_force_internal_access2;
+ uint32_t mc_generalized_carveout2_force_internal_access3;
+ uint32_t mc_generalized_carveout2_force_internal_access4;
+ uint32_t mc_generalized_carveout2_cfg0;
+
+ uint32_t mc_generalized_carveout3_bom;
+ uint32_t mc_generalized_carveout3_bom_hi;
+ uint32_t mc_generalized_carveout3_size_128kb;
+ uint32_t mc_generalized_carveout3_access0;
+ uint32_t mc_generalized_carveout3_access1;
+ uint32_t mc_generalized_carveout3_access2;
+ uint32_t mc_generalized_carveout3_access3;
+ uint32_t mc_generalized_carveout3_access4;
+ uint32_t mc_generalized_carveout3_force_internal_access0;
+ uint32_t mc_generalized_carveout3_force_internal_access1;
+ uint32_t mc_generalized_carveout3_force_internal_access2;
+ uint32_t mc_generalized_carveout3_force_internal_access3;
+ uint32_t mc_generalized_carveout3_force_internal_access4;
+ uint32_t mc_generalized_carveout3_cfg0;
+
+ uint32_t mc_generalized_carveout4_bom;
+ uint32_t mc_generalized_carveout4_bom_hi;
+ uint32_t mc_generalized_carveout4_size_128kb;
+ uint32_t mc_generalized_carveout4_access0;
+ uint32_t mc_generalized_carveout4_access1;
+ uint32_t mc_generalized_carveout4_access2;
+ uint32_t mc_generalized_carveout4_access3;
+ uint32_t mc_generalized_carveout4_access4;
+ uint32_t mc_generalized_carveout4_force_internal_access0;
+ uint32_t mc_generalized_carveout4_force_internal_access1;
+ uint32_t mc_generalized_carveout4_force_internal_access2;
+ uint32_t mc_generalized_carveout4_force_internal_access3;
+ uint32_t mc_generalized_carveout4_force_internal_access4;
+ uint32_t mc_generalized_carveout4_cfg0;
+
+ uint32_t mc_generalized_carveout5_bom;
+ uint32_t mc_generalized_carveout5_bom_hi;
+ uint32_t mc_generalized_carveout5_size_128kb;
+ uint32_t mc_generalized_carveout5_access0;
+ uint32_t mc_generalized_carveout5_access1;
+ uint32_t mc_generalized_carveout5_access2;
+ uint32_t mc_generalized_carveout5_access3;
+ uint32_t mc_generalized_carveout5_access4;
+ uint32_t mc_generalized_carveout5_force_internal_access0;
+ uint32_t mc_generalized_carveout5_force_internal_access1;
+ uint32_t mc_generalized_carveout5_force_internal_access2;
+ uint32_t mc_generalized_carveout5_force_internal_access3;
+ uint32_t mc_generalized_carveout5_force_internal_access4;
+ uint32_t mc_generalized_carveout5_cfg0;
+
+ /* Specifies enable for CA training */
+ uint32_t emc_ca_training_enable;
+ /* Set if bit 6 select is greater than bit 7 select; uses aremc.spec packet SWIZZLE_BIT6_GT_BIT7 */
+ uint32_t swizzle_rank_byte_encode;
+ /* Specifies enable and offset for patched boot rom write */
+ uint32_t boot_rom_patch_control;
+ /* Specifies data for patched boot rom write */
+ uint32_t boot_rom_patch_data;
+
+ /* Specifies the value for MC_MTS_CARVEOUT_BOM */
+ uint32_t mc_mts_carveout_bom;
+ /* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
+ uint32_t mc_mts_carveout_adr_hi;
+ /* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
+ uint32_t mc_mts_carveout_size_mb;
+ /* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
+ uint32_t mc_mts_carveout_reg_ctrl;
+} sdram_params_t;
+
+#endif
diff --git a/fusee/fusee-primary/src/sdram_param_t210_lp0.h b/fusee/fusee-primary/src/sdram_param_t210_lp0.h
new file mode 100644
index 000000000..0a1d41840
--- /dev/null
+++ b/fusee/fusee-primary/src/sdram_param_t210_lp0.h
@@ -0,0 +1,964 @@
+/*
+ * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
+ * Copyright 2014 Google Inc.
+ * Copyright (c) 2018 CTCaer
+ *
+ * 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.
+ */
+
+/**
+ * Defines the SDRAM parameter structure.
+ *
+ * Note that PLLM is used by EMC. The field names are in camel case to ease
+ * directly converting BCT config files (*.cfg) into C structure.
+ */
+
+#ifndef __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__
+#define __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__
+
+#include
+
+enum
+{
+ /* Specifies the memory type to be undefined */
+ NvBootMemoryType_None = 0,
+
+ /* Specifies the memory type to be DDR SDRAM */
+ NvBootMemoryType_Ddr = 0,
+
+ /* Specifies the memory type to be LPDDR SDRAM */
+ NvBootMemoryType_LpDdr = 0,
+
+ /* Specifies the memory type to be DDR2 SDRAM */
+ NvBootMemoryType_Ddr2 = 0,
+
+ /* Specifies the memory type to be LPDDR2 SDRAM */
+ NvBootMemoryType_LpDdr2,
+
+ /* Specifies the memory type to be DDR3 SDRAM */
+ NvBootMemoryType_Ddr3,
+
+ /* Specifies the memory type to be LPDDR4 SDRAM */
+ NvBootMemoryType_LpDdr4,
+
+ NvBootMemoryType_Num,
+
+ /* Specifies an entry in the ram_code table that's not in use */
+ NvBootMemoryType_Unused = 0X7FFFFFF,
+};
+
+/**
+ * Defines the SDRAM parameter structure
+ */
+struct sdram_params
+{
+
+ /* Specifies the type of memory device */
+ uint32_t MemoryType;
+
+ /* MC/EMC clock source configuration */
+
+ /* Specifies the M value for PllM */
+ uint32_t PllMInputDivider;
+ /* Specifies the N value for PllM */
+ uint32_t PllMFeedbackDivider;
+ /* Specifies the time to wait for PLLM to lock (in microseconds) */
+ uint32_t PllMStableTime;
+ /* Specifies misc. control bits */
+ uint32_t PllMSetupControl;
+ /* Specifies the P value for PLLM */
+ uint32_t PllMPostDivider;
+ /* Specifies value for Charge Pump Gain Control */
+ uint32_t PllMKCP;
+ /* Specifies VCO gain */
+ uint32_t PllMKVCO;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare0;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare1;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare2;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare3;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare4;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare5;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare6;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare7;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare8;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare9;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare10;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare11;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare12;
+ /* Spare BCT param */
+ uint32_t EmcBctSpare13;
+
+ /* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
+ uint32_t EmcClockSource;
+ uint32_t EmcClockSourceDll;
+
+ /* Defines possible override for PLLLM_MISC2 */
+ uint32_t ClkRstControllerPllmMisc2Override;
+ /* enables override for PLLLM_MISC2 */
+ uint32_t ClkRstControllerPllmMisc2OverrideEnable;
+ /* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
+ uint32_t ClearClk2Mc1;
+
+ /* Auto-calibration of EMC pads */
+
+ /* Specifies the value for EMC_AUTO_CAL_INTERVAL */
+ uint32_t EmcAutoCalInterval;
+ /*
+ * Specifies the value for EMC_AUTO_CAL_CONFIG
+ * Note: Trigger bits are set by the SDRAM code.
+ */
+ uint32_t EmcAutoCalConfig;
+
+ /* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
+ uint32_t EmcAutoCalConfig2;
+
+ /* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
+ uint32_t EmcAutoCalConfig3;
+
+ /* Specifies the values for EMC_AUTO_CAL_CONFIG4-8 */
+ uint32_t EmcAutoCalConfig4;
+ uint32_t EmcAutoCalConfig5;
+ uint32_t EmcAutoCalConfig6;
+ uint32_t EmcAutoCalConfig7;
+ uint32_t EmcAutoCalConfig8;
+
+ /* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
+ uint32_t EmcAutoCalVrefSel0;
+ uint32_t EmcAutoCalVrefSel1;
+
+ /* Specifies the value for EMC_AUTO_CAL_CHANNEL */
+ uint32_t EmcAutoCalChannel;
+
+ /* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
+ uint32_t EmcPmacroAutocalCfg0;
+ uint32_t EmcPmacroAutocalCfg1;
+ uint32_t EmcPmacroAutocalCfg2;
+ uint32_t EmcPmacroRxTerm;
+ uint32_t EmcPmacroDqTxDrv;
+ uint32_t EmcPmacroCaTxDrv;
+ uint32_t EmcPmacroCmdTxDrv;
+ uint32_t EmcPmacroAutocalCfgCommon;
+ uint32_t EmcPmacroZctrl;
+
+ /*
+ * Specifies the time for the calibration
+ * to stabilize (in microseconds)
+ */
+ uint32_t EmcAutoCalWait;
+
+ uint32_t EmcXm2CompPadCtrl;
+ uint32_t EmcXm2CompPadCtrl2;
+ uint32_t EmcXm2CompPadCtrl3;
+
+ /*
+ * DRAM size information
+ * Specifies the value for EMC_ADR_CFG
+ */
+ uint32_t EmcAdrCfg;
+
+ /*
+ * Specifies the time to wait after asserting pin
+ * CKE (in microseconds)
+ */
+ uint32_t EmcPinProgramWait;
+ /* Specifies the extra delay before/after pin RESET/CKE command */
+ uint32_t EmcPinExtraWait;
+
+ uint32_t EmcPinGpioEn;
+ uint32_t EmcPinGpio;
+
+ /*
+ * Specifies the extra delay after the first writing
+ * of EMC_TIMING_CONTROL
+ */
+ uint32_t EmcTimingControlWait;
+
+ /* Timing parameters required for the SDRAM */
+
+ /* Specifies the value for EMC_RC */
+ uint32_t EmcRc;
+ /* Specifies the value for EMC_RFC */
+ uint32_t EmcRfc;
+ /* Specifies the value for EMC_RFC_PB */
+ uint32_t EmcRfcPb;
+ /* Specifies the value for EMC_RFC_CTRL2 */
+ uint32_t EmcRefctrl2;
+ /* Specifies the value for EMC_RFC_SLR */
+ uint32_t EmcRfcSlr;
+ /* Specifies the value for EMC_RAS */
+ uint32_t EmcRas;
+ /* Specifies the value for EMC_RP */
+ uint32_t EmcRp;
+ /* Specifies the value for EMC_R2R */
+ uint32_t EmcR2r;
+ /* Specifies the value for EMC_W2W */
+ uint32_t EmcW2w;
+ /* Specifies the value for EMC_R2W */
+ uint32_t EmcR2w;
+ /* Specifies the value for EMC_W2R */
+ uint32_t EmcW2r;
+ /* Specifies the value for EMC_R2P */
+ uint32_t EmcR2p;
+ /* Specifies the value for EMC_W2P */
+ uint32_t EmcW2p;
+
+ uint32_t EmcTppd;
+ uint32_t EmcCcdmw;
+
+ /* Specifies the value for EMC_RD_RCD */
+ uint32_t EmcRdRcd;
+ /* Specifies the value for EMC_WR_RCD */
+ uint32_t EmcWrRcd;
+ /* Specifies the value for EMC_RRD */
+ uint32_t EmcRrd;
+ /* Specifies the value for EMC_REXT */
+ uint32_t EmcRext;
+ /* Specifies the value for EMC_WEXT */
+ uint32_t EmcWext;
+ /* Specifies the value for EMC_WDV */
+ uint32_t EmcWdv;
+
+ uint32_t EmcWdvChk;
+ uint32_t EmcWsv;
+ uint32_t EmcWev;
+
+ /* Specifies the value for EMC_WDV_MASK */
+ uint32_t EmcWdvMask;
+
+ uint32_t EmcWsDuration;
+ uint32_t EmcWeDuration;
+
+ /* Specifies the value for EMC_QUSE */
+ uint32_t EmcQUse;
+ /* Specifies the value for EMC_QUSE_WIDTH */
+ uint32_t EmcQuseWidth;
+ /* Specifies the value for EMC_IBDLY */
+ uint32_t EmcIbdly;
+ /* Specifies the value for EMC_OBDLY */
+ uint32_t EmcObdly;
+ /* Specifies the value for EMC_EINPUT */
+ uint32_t EmcEInput;
+ /* Specifies the value for EMC_EINPUT_DURATION */
+ uint32_t EmcEInputDuration;
+ /* Specifies the value for EMC_PUTERM_EXTRA */
+ uint32_t EmcPutermExtra;
+ /* Specifies the value for EMC_PUTERM_WIDTH */
+ uint32_t EmcPutermWidth;
+ /* Specifies the value for EMC_PUTERM_ADJ */
+ ////uint32_t EmcPutermAdj;
+
+ /* Specifies the value for EMC_QRST */
+ uint32_t EmcQRst;
+ /* Specifies the value for EMC_QSAFE */
+ uint32_t EmcQSafe;
+ /* Specifies the value for EMC_RDV */
+ uint32_t EmcRdv;
+ /* Specifies the value for EMC_RDV_MASK */
+ uint32_t EmcRdvMask;
+ /* Specifies the value for EMC_RDV_EARLY */
+ uint32_t EmcRdvEarly;
+ /* Specifies the value for EMC_RDV_EARLY_MASK */
+ uint32_t EmcRdvEarlyMask;
+ /* Specifies the value for EMC_QPOP */
+ uint32_t EmcQpop;
+
+ /* Specifies the value for EMC_REFRESH */
+ uint32_t EmcRefresh;
+ /* Specifies the value for EMC_BURST_REFRESH_NUM */
+ uint32_t EmcBurstRefreshNum;
+ /* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
+ uint32_t EmcPreRefreshReqCnt;
+ /* Specifies the value for EMC_PDEX2WR */
+ uint32_t EmcPdEx2Wr;
+ /* Specifies the value for EMC_PDEX2RD */
+ uint32_t EmcPdEx2Rd;
+ /* Specifies the value for EMC_PCHG2PDEN */
+ uint32_t EmcPChg2Pden;
+ /* Specifies the value for EMC_ACT2PDEN */
+ uint32_t EmcAct2Pden;
+ /* Specifies the value for EMC_AR2PDEN */
+ uint32_t EmcAr2Pden;
+ /* Specifies the value for EMC_RW2PDEN */
+ uint32_t EmcRw2Pden;
+ /* Specifies the value for EMC_CKE2PDEN */
+ uint32_t EmcCke2Pden;
+ /* Specifies the value for EMC_PDEX2CKE */
+ uint32_t EmcPdex2Cke;
+ /* Specifies the value for EMC_PDEX2MRR */
+ uint32_t EmcPdex2Mrr;
+ /* Specifies the value for EMC_TXSR */
+ uint32_t EmcTxsr;
+ /* Specifies the value for EMC_TXSRDLL */
+ uint32_t EmcTxsrDll;
+ /* Specifies the value for EMC_TCKE */
+ uint32_t EmcTcke;
+ /* Specifies the value for EMC_TCKESR */
+ uint32_t EmcTckesr;
+ /* Specifies the value for EMC_TPD */
+ uint32_t EmcTpd;
+ /* Specifies the value for EMC_TFAW */
+ uint32_t EmcTfaw;
+ /* Specifies the value for EMC_TRPAB */
+ uint32_t EmcTrpab;
+ /* Specifies the value for EMC_TCLKSTABLE */
+ uint32_t EmcTClkStable;
+ /* Specifies the value for EMC_TCLKSTOP */
+ uint32_t EmcTClkStop;
+ /* Specifies the value for EMC_TREFBW */
+ uint32_t EmcTRefBw;
+
+ /* FBIO configuration values */
+
+ /* Specifies the value for EMC_FBIO_CFG5 */
+ uint32_t EmcFbioCfg5;
+ /* Specifies the value for EMC_FBIO_CFG7 */
+ uint32_t EmcFbioCfg7;
+ /* Specifies the value for EMC_FBIO_CFG8 */
+ uint32_t EmcFbioCfg8;
+
+ /* Command mapping for CMD brick 0 */
+ uint32_t EmcCmdMappingCmd0_0;
+ uint32_t EmcCmdMappingCmd0_1;
+ uint32_t EmcCmdMappingCmd0_2;
+ uint32_t EmcCmdMappingCmd1_0;
+ uint32_t EmcCmdMappingCmd1_1;
+ uint32_t EmcCmdMappingCmd1_2;
+ uint32_t EmcCmdMappingCmd2_0;
+ uint32_t EmcCmdMappingCmd2_1;
+ uint32_t EmcCmdMappingCmd2_2;
+ uint32_t EmcCmdMappingCmd3_0;
+ uint32_t EmcCmdMappingCmd3_1;
+ uint32_t EmcCmdMappingCmd3_2;
+ uint32_t EmcCmdMappingByte;
+
+ /* Specifies the value for EMC_FBIO_SPARE */
+ uint32_t EmcFbioSpare;
+
+ /* Specifies the value for EMC_CFG_RSV */
+ uint32_t EmcCfgRsv;
+
+ /* MRS command values */
+
+ /* Specifies the value for EMC_MRS */
+ uint32_t EmcMrs;
+ /* Specifies the MP0 command to initialize mode registers */
+ uint32_t EmcEmrs;
+ /* Specifies the MP2 command to initialize mode registers */
+ uint32_t EmcEmrs2;
+ /* Specifies the MP3 command to initialize mode registers */
+ uint32_t EmcEmrs3;
+ /* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
+ uint32_t EmcMrw1;
+ /* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
+ uint32_t EmcMrw2;
+ /* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
+ uint32_t EmcMrw3;
+ /* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
+ uint32_t EmcMrw4;
+ /* Specifies the programming to LPDDR2 Mode Register 3? at cold boot */
+ uint32_t EmcMrw6;
+ /* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
+ uint32_t EmcMrw8;
+ /* Specifies the programming to LPDDR2 Mode Register 11? at cold boot */
+ uint32_t EmcMrw9;
+ /* Specifies the programming to LPDDR2 Mode Register 12 at cold boot */
+ uint32_t EmcMrw10;
+ /* Specifies the programming to LPDDR2 Mode Register 14 at cold boot */
+ uint32_t EmcMrw12;
+ /* Specifies the programming to LPDDR2 Mode Register 14? at cold boot */
+ uint32_t EmcMrw13;
+ /* Specifies the programming to LPDDR2 Mode Register 22 at cold boot */
+ uint32_t EmcMrw14;
+ /*
+ * Specifies the programming to extra LPDDR2 Mode Register
+ * at cold boot
+ */
+ uint32_t EmcMrwExtra;
+ /*
+ * Specifies the programming to extra LPDDR2 Mode Register
+ * at warm boot
+ */
+ uint32_t EmcWarmBootMrwExtra;
+ /*
+ * Specify the enable of extra Mode Register programming at
+ * warm boot
+ */
+ uint32_t EmcWarmBootExtraModeRegWriteEnable;
+ /*
+ * Specify the enable of extra Mode Register programming at
+ * cold boot
+ */
+ uint32_t EmcExtraModeRegWriteEnable;
+
+ /* Specifies the EMC_MRW reset command value */
+ uint32_t EmcMrwResetCommand;
+ /* Specifies the EMC Reset wait time (in microseconds) */
+ uint32_t EmcMrwResetNInitWait;
+ /* Specifies the value for EMC_MRS_WAIT_CNT */
+ uint32_t EmcMrsWaitCnt;
+ /* Specifies the value for EMC_MRS_WAIT_CNT2 */
+ uint32_t EmcMrsWaitCnt2;
+
+ /* EMC miscellaneous configurations */
+
+ /* Specifies the value for EMC_CFG */
+ uint32_t EmcCfg;
+ /* Specifies the value for EMC_CFG_2 */
+ uint32_t EmcCfg2;
+ /* Specifies the pipe bypass controls */
+ uint32_t EmcCfgPipe;
+ uint32_t EmcCfgPipeClk;
+ uint32_t EmcFdpdCtrlCmdNoRamp;
+ uint32_t EmcCfgUpdate;
+
+ /* Specifies the value for EMC_DBG */
+ uint32_t EmcDbg;
+ uint32_t EmcDbgWriteMux;
+
+ /* Specifies the value for EMC_CMDQ */
+ uint32_t EmcCmdQ;
+ /* Specifies the value for EMC_MC2EMCQ */
+ uint32_t EmcMc2EmcQ;
+ /* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
+ uint32_t EmcDynSelfRefControl;
+
+ /* Specifies the value for MEM_INIT_DONE */
+ uint32_t AhbArbitrationXbarCtrlMemInitDone;
+
+ /* Specifies the value for EMC_CFG_DIG_DLL */
+ uint32_t EmcCfgDigDll;
+ uint32_t EmcCfgDigDll_1;
+ /* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
+ uint32_t EmcCfgDigDllPeriod;
+ /* Specifies the value of *DEV_SELECTN of various EMC registers */
+ uint32_t EmcDevSelect;
+
+ /* Specifies the value for EMC_SEL_DPD_CTRL */
+ uint32_t EmcSelDpdCtrl;
+
+ /* Pads trimmer delays */
+ uint32_t EmcFdpdCtrlDq;
+ uint32_t EmcFdpdCtrlCmd;
+ uint32_t EmcPmacroIbVrefDq_0;
+ uint32_t EmcPmacroIbVrefDq_1;
+ uint32_t EmcPmacroIbVrefDqs_0;
+ uint32_t EmcPmacroIbVrefDqs_1;
+ uint32_t EmcPmacroIbRxrt;
+ uint32_t EmcCfgPipe1;
+ uint32_t EmcCfgPipe2;
+
+ /* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
+ uint32_t EmcPmacroQuseDdllRank0_0;
+ uint32_t EmcPmacroQuseDdllRank0_1;
+ uint32_t EmcPmacroQuseDdllRank0_2;
+ uint32_t EmcPmacroQuseDdllRank0_3;
+ uint32_t EmcPmacroQuseDdllRank0_4;
+ uint32_t EmcPmacroQuseDdllRank0_5;
+ uint32_t EmcPmacroQuseDdllRank1_0;
+ uint32_t EmcPmacroQuseDdllRank1_1;
+ uint32_t EmcPmacroQuseDdllRank1_2;
+ uint32_t EmcPmacroQuseDdllRank1_3;
+ uint32_t EmcPmacroQuseDdllRank1_4;
+ uint32_t EmcPmacroQuseDdllRank1_5;
+
+ uint32_t EmcPmacroObDdllLongDqRank0_0;
+ uint32_t EmcPmacroObDdllLongDqRank0_1;
+ uint32_t EmcPmacroObDdllLongDqRank0_2;
+ uint32_t EmcPmacroObDdllLongDqRank0_3;
+ uint32_t EmcPmacroObDdllLongDqRank0_4;
+ uint32_t EmcPmacroObDdllLongDqRank0_5;
+ uint32_t EmcPmacroObDdllLongDqRank1_0;
+ uint32_t EmcPmacroObDdllLongDqRank1_1;
+ uint32_t EmcPmacroObDdllLongDqRank1_2;
+ uint32_t EmcPmacroObDdllLongDqRank1_3;
+ uint32_t EmcPmacroObDdllLongDqRank1_4;
+ uint32_t EmcPmacroObDdllLongDqRank1_5;
+
+ uint32_t EmcPmacroObDdllLongDqsRank0_0;
+ uint32_t EmcPmacroObDdllLongDqsRank0_1;
+ uint32_t EmcPmacroObDdllLongDqsRank0_2;
+ uint32_t EmcPmacroObDdllLongDqsRank0_3;
+ uint32_t EmcPmacroObDdllLongDqsRank0_4;
+ uint32_t EmcPmacroObDdllLongDqsRank0_5;
+ uint32_t EmcPmacroObDdllLongDqsRank1_0;
+ uint32_t EmcPmacroObDdllLongDqsRank1_1;
+ uint32_t EmcPmacroObDdllLongDqsRank1_2;
+ uint32_t EmcPmacroObDdllLongDqsRank1_3;
+ uint32_t EmcPmacroObDdllLongDqsRank1_4;
+ uint32_t EmcPmacroObDdllLongDqsRank1_5;
+
+ uint32_t EmcPmacroIbDdllLongDqsRank0_0;
+ uint32_t EmcPmacroIbDdllLongDqsRank0_1;
+ uint32_t EmcPmacroIbDdllLongDqsRank0_2;
+ uint32_t EmcPmacroIbDdllLongDqsRank0_3;
+ uint32_t EmcPmacroIbDdllLongDqsRank1_0;
+ uint32_t EmcPmacroIbDdllLongDqsRank1_1;
+ uint32_t EmcPmacroIbDdllLongDqsRank1_2;
+ uint32_t EmcPmacroIbDdllLongDqsRank1_3;
+
+ uint32_t EmcPmacroDdllLongCmd_0;
+ uint32_t EmcPmacroDdllLongCmd_1;
+ uint32_t EmcPmacroDdllLongCmd_2;
+ uint32_t EmcPmacroDdllLongCmd_3;
+ uint32_t EmcPmacroDdllLongCmd_4;
+ uint32_t EmcPmacroDdllShortCmd_0;
+ uint32_t EmcPmacroDdllShortCmd_1;
+ uint32_t EmcPmacroDdllShortCmd_2;
+
+ /*
+ * Specifies the delay after asserting CKE pin during a WarmBoot0
+ * sequence (in microseconds)
+ */
+ uint32_t WarmBootWait;
+
+ /* Specifies the value for EMC_ODT_WRITE */
+ uint32_t EmcOdtWrite;
+
+ /* Periodic ZQ calibration */
+
+ /*
+ * Specifies the value for EMC_ZCAL_INTERVAL
+ * Value 0 disables ZQ calibration
+ */
+ uint32_t EmcZcalInterval;
+ /* Specifies the value for EMC_ZCAL_WAIT_CNT */
+ uint32_t EmcZcalWaitCnt;
+ /* Specifies the value for EMC_ZCAL_MRW_CMD */
+ uint32_t EmcZcalMrwCmd;
+
+ /* DRAM initialization sequence flow control */
+
+ /* Specifies the MRS command value for resetting DLL */
+ uint32_t EmcMrsResetDll;
+ /* Specifies the command for ZQ initialization of device 0 */
+ uint32_t EmcZcalInitDev0;
+ /* Specifies the command for ZQ initialization of device 1 */
+ uint32_t EmcZcalInitDev1;
+ /*
+ * Specifies the wait time after programming a ZQ initialization
+ * command (in microseconds)
+ */
+ uint32_t EmcZcalInitWait;
+ /*
+ * Specifies the enable for ZQ calibration at cold boot [bit 0]
+ * and warm boot [bit 1]
+ */
+ uint32_t EmcZcalWarmColdBootEnables;
+
+ /*
+ * Specifies the MRW command to LPDDR2 for ZQ calibration
+ * on warmboot
+ */
+ /* Is issued to both devices separately */
+ uint32_t EmcMrwLpddr2ZcalWarmBoot;
+ /*
+ * Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
+ * Is issued to both devices separately
+ */
+ uint32_t EmcZqCalDdr3WarmBoot;
+ uint32_t EmcZqCalLpDdr4WarmBoot;
+ /*
+ * Specifies the wait time for ZQ calibration on warmboot
+ * (in microseconds)
+ */
+ uint32_t EmcZcalWarmBootWait;
+ /*
+ * Specifies the enable for DRAM Mode Register programming
+ * at warm boot
+ */
+ uint32_t EmcMrsWarmBootEnable;
+ /*
+ * Specifies the wait time after sending an MRS DLL reset command
+ * in microseconds)
+ */
+ uint32_t EmcMrsResetDllWait;
+ /* Specifies the extra MRS command to initialize mode registers */
+ uint32_t EmcMrsExtra;
+ /* Specifies the extra MRS command at warm boot */
+ uint32_t EmcWarmBootMrsExtra;
+ /* Specifies the EMRS command to enable the DDR2 DLL */
+ uint32_t EmcEmrsDdr2DllEnable;
+ /* Specifies the MRS command to reset the DDR2 DLL */
+ uint32_t EmcMrsDdr2DllReset;
+ /* Specifies the EMRS command to set OCD calibration */
+ uint32_t EmcEmrsDdr2OcdCalib;
+ /*
+ * Specifies the wait between initializing DDR and setting OCD
+ * calibration (in microseconds)
+ */
+ uint32_t EmcDdr2Wait;
+ /* Specifies the value for EMC_CLKEN_OVERRIDE */
+ uint32_t EmcClkenOverride;
+
+ /*
+ * Specifies LOG2 of the extra refresh numbers after booting
+ * Program 0 to disable
+ */
+ uint32_t EmcExtraRefreshNum;
+ /* Specifies the master override for all EMC clocks */
+ uint32_t EmcClkenOverrideAllWarmBoot;
+ /* Specifies the master override for all MC clocks */
+ uint32_t McClkenOverrideAllWarmBoot;
+ /* Specifies digital dll period, choosing between 4 to 64 ms */
+ uint32_t EmcCfgDigDllPeriodWarmBoot;
+
+ /* Pad controls */
+
+ /* Specifies the value for PMC_VDDP_SEL */
+ uint32_t PmcVddpSel;
+ /* Specifies the wait time after programming PMC_VDDP_SEL */
+ uint32_t PmcVddpSelWait;
+ /* Specifies the value for PMC_DDR_PWR */
+ uint32_t PmcDdrPwr;
+ /* Specifies the value for PMC_DDR_CFG */
+ uint32_t PmcDdrCfg;
+ /* Specifies the value for PMC_IO_DPD3_REQ */
+ uint32_t PmcIoDpd3Req;
+ /* Specifies the wait time after programming PMC_IO_DPD3_REQ */
+ uint32_t PmcIoDpd3ReqWait;
+ uint32_t PmcIoDpd4ReqWait;
+
+ /* Specifies the value for PMC_REG_SHORT */
+ uint32_t PmcRegShort;
+ /* Specifies the value for PMC_NO_IOPOWER */
+ uint32_t PmcNoIoPower;
+
+ uint32_t PmcDdrCntrlWait;
+ uint32_t PmcDdrCntrl;
+
+ /* Specifies the value for EMC_ACPD_CONTROL */
+ uint32_t EmcAcpdControl;
+
+ /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE_CFG */
+ ////uint32_t EmcSwizzleRank0ByteCfg;
+ /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
+ uint32_t EmcSwizzleRank0Byte0;
+ /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
+ uint32_t EmcSwizzleRank0Byte1;
+ /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
+ uint32_t EmcSwizzleRank0Byte2;
+ /* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
+ uint32_t EmcSwizzleRank0Byte3;
+ /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE_CFG */
+ ////uint32_t EmcSwizzleRank1ByteCfg;
+ /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
+ uint32_t EmcSwizzleRank1Byte0;
+ /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
+ uint32_t EmcSwizzleRank1Byte1;
+ /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
+ uint32_t EmcSwizzleRank1Byte2;
+ /* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
+ uint32_t EmcSwizzleRank1Byte3;
+
+ /* Specifies the value for EMC_TXDSRVTTGEN */
+ uint32_t EmcTxdsrvttgen;
+
+ /* Specifies the value for EMC_DATA_BRLSHFT_0 */
+ uint32_t EmcDataBrlshft0;
+ uint32_t EmcDataBrlshft1;
+
+ uint32_t EmcDqsBrlshft0;
+ uint32_t EmcDqsBrlshft1;
+
+ uint32_t EmcCmdBrlshft0;
+ uint32_t EmcCmdBrlshft1;
+ uint32_t EmcCmdBrlshft2;
+ uint32_t EmcCmdBrlshft3;
+
+ uint32_t EmcQuseBrlshft0;
+ uint32_t EmcQuseBrlshft1;
+ uint32_t EmcQuseBrlshft2;
+ uint32_t EmcQuseBrlshft3;
+
+ uint32_t EmcDllCfg0;
+ uint32_t EmcDllCfg1;
+
+ uint32_t EmcPmcScratch1;
+ uint32_t EmcPmcScratch2;
+ uint32_t EmcPmcScratch3;
+
+ uint32_t EmcPmacroPadCfgCtrl;
+
+ uint32_t EmcPmacroVttgenCtrl0;
+ uint32_t EmcPmacroVttgenCtrl1;
+ uint32_t EmcPmacroVttgenCtrl2;
+
+ uint32_t EmcPmacroBrickCtrlRfu1;
+ uint32_t EmcPmacroCmdBrickCtrlFdpd;
+ uint32_t EmcPmacroBrickCtrlRfu2;
+ uint32_t EmcPmacroDataBrickCtrlFdpd;
+ uint32_t EmcPmacroBgBiasCtrl0;
+ uint32_t EmcPmacroDataPadRxCtrl;
+ uint32_t EmcPmacroCmdPadRxCtrl;
+ uint32_t EmcPmacroDataRxTermMode;
+ uint32_t EmcPmacroCmdRxTermMode;
+ uint32_t EmcPmacroDataPadTxCtrl;
+ uint32_t EmcPmacroCommonPadTxCtrl;
+ uint32_t EmcPmacroCmdPadTxCtrl;
+ uint32_t EmcCfg3;
+
+ uint32_t EmcPmacroTxPwrd0;
+ uint32_t EmcPmacroTxPwrd1;
+ uint32_t EmcPmacroTxPwrd2;
+ uint32_t EmcPmacroTxPwrd3;
+ uint32_t EmcPmacroTxPwrd4;
+ uint32_t EmcPmacroTxPwrd5;
+
+ uint32_t EmcConfigSampleDelay;
+
+ uint32_t EmcPmacroBrickMapping0;
+ uint32_t EmcPmacroBrickMapping1;
+ uint32_t EmcPmacroBrickMapping2;
+
+ uint32_t EmcPmacroTxSelClkSrc0;
+ uint32_t EmcPmacroTxSelClkSrc1;
+ uint32_t EmcPmacroTxSelClkSrc2;
+ uint32_t EmcPmacroTxSelClkSrc3;
+ uint32_t EmcPmacroTxSelClkSrc4;
+ uint32_t EmcPmacroTxSelClkSrc5;
+
+ uint32_t EmcPmacroDdllBypass;
+
+ uint32_t EmcPmacroDdllPwrd0;
+ uint32_t EmcPmacroDdllPwrd1;
+ uint32_t EmcPmacroDdllPwrd2;
+
+ uint32_t EmcPmacroCmdCtrl0;
+ uint32_t EmcPmacroCmdCtrl1;
+ uint32_t EmcPmacroCmdCtrl2;
+
+ /* DRAM size information */
+
+ /* Specifies the value for MC_EMEM_ADR_CFG */
+ uint32_t McEmemAdrCfg;
+ /* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
+ uint32_t McEmemAdrCfgDev0;
+ /* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
+ uint32_t McEmemAdrCfgDev1;
+ uint32_t McEmemAdrCfgChannelMask;
+
+ /* Specifies the value for MC_EMEM_BANK_SWIZZLECfg0 */
+ uint32_t McEmemAdrCfgBankMask0;
+ /* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
+ uint32_t McEmemAdrCfgBankMask1;
+ /* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
+ uint32_t McEmemAdrCfgBankMask2;
+
+ /*
+ * Specifies the value for MC_EMEM_CFG which holds the external memory
+ * size (in KBytes)
+ */
+ uint32_t McEmemCfg;
+
+ /* MC arbitration configuration */
+
+ /* Specifies the value for MC_EMEM_ARB_CFG */
+ uint32_t McEmemArbCfg;
+ /* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
+ uint32_t McEmemArbOutstandingReq;
+
+ uint32_t McEmemArbRefpbHpCtrl;
+ uint32_t McEmemArbRefpbBankCtrl;
+
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
+ uint32_t McEmemArbTimingRcd;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RP */
+ uint32_t McEmemArbTimingRp;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RC */
+ uint32_t McEmemArbTimingRc;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
+ uint32_t McEmemArbTimingRas;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
+ uint32_t McEmemArbTimingFaw;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
+ uint32_t McEmemArbTimingRrd;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
+ uint32_t McEmemArbTimingRap2Pre;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
+ uint32_t McEmemArbTimingWap2Pre;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
+ uint32_t McEmemArbTimingR2R;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
+ uint32_t McEmemArbTimingW2W;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
+ uint32_t McEmemArbTimingR2W;
+ /* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
+ uint32_t McEmemArbTimingW2R;
+
+ uint32_t McEmemArbTimingRFCPB;
+
+ /* Specifies the value for MC_EMEM_ARB_DA_TURNS */
+ uint32_t McEmemArbDaTurns;
+ /* Specifies the value for MC_EMEM_ARB_DA_COVERS */
+ uint32_t McEmemArbDaCovers;
+ /* Specifies the value for MC_EMEM_ARB_MISC0 */
+ uint32_t McEmemArbMisc0;
+ /* Specifies the value for MC_EMEM_ARB_MISC1 */
+ uint32_t McEmemArbMisc1;
+ uint32_t McEmemArbMisc2;
+
+ /* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
+ uint32_t McEmemArbRing1Throttle;
+ /* Specifies the value for MC_EMEM_ARB_OVERRIDE */
+ uint32_t McEmemArbOverride;
+ /* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
+ uint32_t McEmemArbOverride1;
+ /* Specifies the value for MC_EMEM_ARB_RSV */
+ uint32_t McEmemArbRsv;
+
+ uint32_t McDaCfg0;
+ uint32_t McEmemArbTimingCcdmw;
+
+ /* Specifies the value for MC_CLKEN_OVERRIDE */
+ uint32_t McClkenOverride;
+
+ /* Specifies the value for MC_STAT_CONTROL */
+ uint32_t McStatControl;
+
+ /* Specifies the value for MC_VIDEO_PROTECT_BOM */
+ uint32_t McVideoProtectBom;
+ /* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
+ uint32_t McVideoProtectBomAdrHi;
+ /* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
+ uint32_t McVideoProtectSizeMb;
+ /* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
+ uint32_t McVideoProtectVprOverride;
+ /* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
+ uint32_t McVideoProtectVprOverride1;
+ /* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
+ uint32_t McVideoProtectGpuOverride0;
+ /* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
+ uint32_t McVideoProtectGpuOverride1;
+ /* Specifies the value for MC_SEC_CARVEOUT_BOM */
+ uint32_t McSecCarveoutBom;
+ /* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
+ uint32_t McSecCarveoutAdrHi;
+ /* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
+ uint32_t McSecCarveoutSizeMb;
+ /* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.
+ VIDEO_PROTECT_WRITEAccess */
+ uint32_t McVideoProtectWriteAccess;
+ /* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.
+ SEC_CARVEOUT_WRITEAccess */
+ uint32_t McSecCarveoutProtectWriteAccess;
+
+ /* Write-Protect Regions (WPR) */
+ uint32_t McGeneralizedCarveout1Bom;
+ uint32_t McGeneralizedCarveout1BomHi;
+ uint32_t McGeneralizedCarveout1Size128kb;
+ uint32_t McGeneralizedCarveout1Access0;
+ uint32_t McGeneralizedCarveout1Access1;
+ uint32_t McGeneralizedCarveout1Access2;
+ uint32_t McGeneralizedCarveout1Access3;
+ uint32_t McGeneralizedCarveout1Access4;
+ uint32_t McGeneralizedCarveout1ForceInternalAccess0;
+ uint32_t McGeneralizedCarveout1ForceInternalAccess1;
+ uint32_t McGeneralizedCarveout1ForceInternalAccess2;
+ uint32_t McGeneralizedCarveout1ForceInternalAccess3;
+ uint32_t McGeneralizedCarveout1ForceInternalAccess4;
+ uint32_t McGeneralizedCarveout1Cfg0;
+
+ uint32_t McGeneralizedCarveout2Bom;
+ uint32_t McGeneralizedCarveout2BomHi;
+ uint32_t McGeneralizedCarveout2Size128kb;
+ uint32_t McGeneralizedCarveout2Access0;
+ uint32_t McGeneralizedCarveout2Access1;
+ uint32_t McGeneralizedCarveout2Access2;
+ uint32_t McGeneralizedCarveout2Access3;
+ uint32_t McGeneralizedCarveout2Access4;
+ uint32_t McGeneralizedCarveout2ForceInternalAccess0;
+ uint32_t McGeneralizedCarveout2ForceInternalAccess1;
+ uint32_t McGeneralizedCarveout2ForceInternalAccess2;
+ uint32_t McGeneralizedCarveout2ForceInternalAccess3;
+ uint32_t McGeneralizedCarveout2ForceInternalAccess4;
+ uint32_t McGeneralizedCarveout2Cfg0;
+
+ uint32_t McGeneralizedCarveout3Bom;
+ uint32_t McGeneralizedCarveout3BomHi;
+ uint32_t McGeneralizedCarveout3Size128kb;
+ uint32_t McGeneralizedCarveout3Access0;
+ uint32_t McGeneralizedCarveout3Access1;
+ uint32_t McGeneralizedCarveout3Access2;
+ uint32_t McGeneralizedCarveout3Access3;
+ uint32_t McGeneralizedCarveout3Access4;
+ uint32_t McGeneralizedCarveout3ForceInternalAccess0;
+ uint32_t McGeneralizedCarveout3ForceInternalAccess1;
+ uint32_t McGeneralizedCarveout3ForceInternalAccess2;
+ uint32_t McGeneralizedCarveout3ForceInternalAccess3;
+ uint32_t McGeneralizedCarveout3ForceInternalAccess4;
+ uint32_t McGeneralizedCarveout3Cfg0;
+
+ uint32_t McGeneralizedCarveout4Bom;
+ uint32_t McGeneralizedCarveout4BomHi;
+ uint32_t McGeneralizedCarveout4Size128kb;
+ uint32_t McGeneralizedCarveout4Access0;
+ uint32_t McGeneralizedCarveout4Access1;
+ uint32_t McGeneralizedCarveout4Access2;
+ uint32_t McGeneralizedCarveout4Access3;
+ uint32_t McGeneralizedCarveout4Access4;
+ uint32_t McGeneralizedCarveout4ForceInternalAccess0;
+ uint32_t McGeneralizedCarveout4ForceInternalAccess1;
+ uint32_t McGeneralizedCarveout4ForceInternalAccess2;
+ uint32_t McGeneralizedCarveout4ForceInternalAccess3;
+ uint32_t McGeneralizedCarveout4ForceInternalAccess4;
+ uint32_t McGeneralizedCarveout4Cfg0;
+
+ uint32_t McGeneralizedCarveout5Bom;
+ uint32_t McGeneralizedCarveout5BomHi;
+ uint32_t McGeneralizedCarveout5Size128kb;
+ uint32_t McGeneralizedCarveout5Access0;
+ uint32_t McGeneralizedCarveout5Access1;
+ uint32_t McGeneralizedCarveout5Access2;
+ uint32_t McGeneralizedCarveout5Access3;
+ uint32_t McGeneralizedCarveout5Access4;
+ uint32_t McGeneralizedCarveout5ForceInternalAccess0;
+ uint32_t McGeneralizedCarveout5ForceInternalAccess1;
+ uint32_t McGeneralizedCarveout5ForceInternalAccess2;
+ uint32_t McGeneralizedCarveout5ForceInternalAccess3;
+ uint32_t McGeneralizedCarveout5ForceInternalAccess4;
+ uint32_t McGeneralizedCarveout5Cfg0;
+
+ /* Specifies enable for CA training */
+ uint32_t EmcCaTrainingEnable;
+
+ /* Set if bit 6 select is greater than bit 7 select; uses aremc.
+ spec packet SWIZZLE_BIT6_GT_BIT7 */
+ uint32_t SwizzleRankByteEncode;
+ /* Specifies enable and offset for patched boot ROM write */
+ uint32_t BootRomPatchControl;
+ /* Specifies data for patched boot ROM write */
+ uint32_t BootRomPatchData;
+
+ /* Specifies the value for MC_MTS_CARVEOUT_BOM */
+ uint32_t McMtsCarveoutBom;
+ /* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
+ uint32_t McMtsCarveoutAdrHi;
+ /* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
+ uint32_t McMtsCarveoutSizeMb;
+ /* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
+ uint32_t McMtsCarveoutRegCtrl;
+
+ /* End */
+};
+
+#endif /* __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__ */
diff --git a/fusee/fusee-primary/src/se.c b/fusee/fusee-primary/src/se.c
index 18e16bd99..d4dbdc498 100644
--- a/fusee/fusee-primary/src/se.c
+++ b/fusee/fusee-primary/src/se.c
@@ -1,7 +1,22 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include "utils.h"
-/*#include "interrupt.h"*/
#include "se.h"
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size);
@@ -24,42 +39,47 @@ void NOINLINE ll_init(volatile se_ll_t *ll, void *buffer, size_t size) {
}
void se_check_error_status_reg(void) {
- if (SECURITY_ENGINE->ERR_STATUS_REG) {
+ if (se_get_regs()->ERR_STATUS_REG) {
generic_panic();
}
}
void se_check_for_error(void) {
- if (SECURITY_ENGINE->INT_STATUS_REG & 0x10000 || SECURITY_ENGINE->FLAGS_REG & 3 || SECURITY_ENGINE->ERR_STATUS_REG) {
+ volatile tegra_se_t *se = se_get_regs();
+ if (se->INT_STATUS_REG & 0x10000 || se->FLAGS_REG & 3 || se->ERR_STATUS_REG) {
generic_panic();
}
}
void se_verify_flags_cleared(void) {
- if (SECURITY_ENGINE->FLAGS_REG & 3) {
+ if (se_get_regs()->FLAGS_REG & 3) {
generic_panic();
}
}
/* Set the flags for an AES keyslot. */
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
/* Misc flags. */
if (flags & ~0x80) {
- SECURITY_ENGINE->AES_KEYSLOT_FLAGS[keyslot] = ~flags;
+ se->AES_KEYSLOT_FLAGS[keyslot] = ~flags;
}
/* Disable keyslot reads. */
if (flags & 0x80) {
- SECURITY_ENGINE->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
+ se->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
}
}
/* Set the flags for an RSA keyslot. */
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_RSA_MAX) {
generic_panic();
}
@@ -67,28 +87,32 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
/* Misc flags. */
if (flags & ~0x80) {
/* TODO: Why are flags assigned this way? */
- SECURITY_ENGINE->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
+ se->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
}
/* Disable keyslot reads. */
if (flags & 0x80) {
- SECURITY_ENGINE->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
+ se->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
}
}
void clear_aes_keyslot(unsigned int keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
/* Zero out the whole keyslot and IV. */
for (unsigned int i = 0; i < 0x10; i++) {
- SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
- SECURITY_ENGINE->AES_KEYTABLE_DATA = 0;
+ se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
+ se->AES_KEYTABLE_DATA = 0;
}
}
void clear_rsa_keyslot(unsigned int keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_RSA_MAX) {
generic_panic();
}
@@ -96,40 +120,44 @@ void clear_rsa_keyslot(unsigned int keyslot) {
/* Zero out the whole keyslot. */
for (unsigned int i = 0; i < 0x40; i++) {
/* Select Keyslot Modulus[i] */
- SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
- SECURITY_ENGINE->RSA_KEYTABLE_DATA = 0;
+ se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40;
+ se->RSA_KEYTABLE_DATA = 0;
}
for (unsigned int i = 0; i < 0x40; i++) {
/* Select Keyslot Expontent[i] */
- SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
- SECURITY_ENGINE->RSA_KEYTABLE_DATA = 0;
+ se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
+ se->RSA_KEYTABLE_DATA = 0;
}
}
void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) {
generic_panic();
}
for (size_t i = 0; i < (key_size >> 2); i++) {
- SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
- SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(key, 4 * i);
+ se->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
+ se->AES_KEYTABLE_DATA = read32le(key, 4 * i);
}
}
void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) {
generic_panic();
}
for (size_t i = 0; i < (modulus_size >> 2); i++) {
- SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i;
- SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4);
+ se->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i;
+ se->RSA_KEYTABLE_DATA = read32be(modulus, (4 * (modulus_size >> 2)) - (4 * i) - 4);
}
for (size_t i = 0; i < (exp_size >> 2); i++) {
- SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
- SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4);
+ se->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
+ se->RSA_KEYTABLE_DATA = read32be(exponent, (4 * (exp_size >> 2)) - (4 * i) - 4);
}
g_se_modulus_sizes[keyslot] = modulus_size;
@@ -137,47 +165,54 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_
}
void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) {
generic_panic();
}
for (size_t i = 0; i < (iv_size >> 2); i++) {
- SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
- SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(iv, 4 * i);
+ se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
+ se->AES_KEYTABLE_DATA = read32le(iv, 4 * i);
}
}
void clear_aes_keyslot_iv(unsigned int keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
for (size_t i = 0; i < (0x10 >> 2); i++) {
- SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
- SECURITY_ENGINE->AES_KEYTABLE_DATA = 0;
+ se->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
+ se->AES_KEYTABLE_DATA = 0;
}
}
void set_se_ctr(const void *ctr) {
for (unsigned int i = 0; i < 4; i++) {
- SECURITY_ENGINE->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4);
+ se_get_regs()->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4);
}
}
void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSLOT_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) {
generic_panic();
}
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB);
- SECURITY_ENGINE->CRYPTO_REG = keyslot_src << 24;
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
- SECURITY_ENGINE->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8;
+ se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB);
+ se->CRYPTO_REG = keyslot_src << 24;
+ se->BLOCK_COUNT_REG = 0;
+ se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8;
trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size);
}
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
+ volatile tegra_se_t *se = se_get_regs();
uint8_t ALIGN(16) stack_buf[KEYSIZE_RSA_MAX];
if (keyslot >= KEYSLOT_RSA_MAX || src_size > KEYSIZE_RSA_MAX || dst_size > KEYSIZE_RSA_MAX) {
@@ -189,11 +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);
}
- SECURITY_ENGINE->CONFIG_REG = (ALG_RSA | DST_RSAREG);
- SECURITY_ENGINE->RSA_CONFIG = keyslot << 24;
- SECURITY_ENGINE->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
- SECURITY_ENGINE->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
-
+ se->CONFIG_REG = (ALG_RSA | DST_RSAREG);
+ se->RSA_CONFIG = keyslot << 24;
+ se->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
+ se->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
trigger_se_blocking_op(OP_START, NULL, 0, stack_buf, src_size);
se_get_exp_mod_output(dst, dst_size);
@@ -201,6 +235,7 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co
void se_get_exp_mod_output(void *buf, size_t size) {
size_t num_dwords = (size >> 2);
+
if (num_dwords < 1) {
return;
}
@@ -210,7 +245,7 @@ void se_get_exp_mod_output(void *buf, size_t size) {
/* Copy endian swapped output. */
while (num_dwords) {
- *p_out = read32be(SECURITY_ENGINE->RSA_OUTPUT, offset);
+ *p_out = read32be(se_get_regs()->RSA_OUTPUT, offset);
offset += 4;
p_out--;
num_dwords--;
@@ -271,6 +306,7 @@ bool se_rsa2048_pss_verify(const void *signature, size_t signature_size, const v
}
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size) {
+ volatile tegra_se_t *se = se_get_regs();
se_ll_t in_ll;
se_ll_t out_ll;
@@ -278,19 +314,18 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v
ll_init(&out_ll, dst, dst_size);
/* Set the LLs. */
- SECURITY_ENGINE->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll);
- SECURITY_ENGINE->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll);
+ se->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll);
+ se->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll);
/* Set registers for operation. */
- SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG;
- SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG;
- SECURITY_ENGINE->OPERATION_REG = op;
+ se->ERR_STATUS_REG = se->ERR_STATUS_REG;
+ se->INT_STATUS_REG = se->INT_STATUS_REG;
+ se->OPERATION_REG = op;
- while (!(SECURITY_ENGINE->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
+ while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
se_check_for_error();
}
-
/* Secure AES Functionality. */
void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, size_t src_size) {
uint8_t block[0x10] = {0};
@@ -305,7 +340,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src,
}
/* Trigger AES operation. */
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se_get_regs()->BLOCK_COUNT_REG = 0;
trigger_se_blocking_op(OP_START, block, sizeof(block), block, sizeof(block));
/* Copy output data into dst. */
@@ -315,21 +350,23 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src,
}
void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) {
generic_panic();
}
unsigned int num_blocks = src_size >> 4;
/* Unknown what this write does, but official code writes it for CTR mode. */
- SECURITY_ENGINE->_0x80C = 1;
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
- SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x91E;
+ se->SPARE_0 = 1;
+ se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
+ se->CRYPTO_REG = (keyslot << 24) | 0x91E;
set_se_ctr(ctr);
/* Handle any aligned blocks. */
size_t aligned_size = (size_t)num_blocks << 4;
if (aligned_size) {
- SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1;
+ se->BLOCK_COUNT_REG = num_blocks - 1;
trigger_se_blocking_op(OP_START, dst, dst_size, src, aligned_size);
}
@@ -344,15 +381,16 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo
}
void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
generic_panic();
}
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
- SECURITY_ENGINE->CRYPTO_REG = keyslot << 24 | 0x100;
+ se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
+ se->CRYPTO_REG = keyslot << 24 | 0x100;
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
-
}
void se_aes_128_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
@@ -363,14 +401,15 @@ void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_si
se_aes_ecb_encrypt_block(keyslot, dst, dst_size, src, src_size, 0x202);
}
-
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
generic_panic();
}
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
- SECURITY_ENGINE->CRYPTO_REG = keyslot << 24;
+ se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
+ se->CRYPTO_REG = keyslot << 24;
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
}
@@ -422,6 +461,8 @@ void aes_128_xts_nintendo_xor_with_tweak(unsigned int keyslot, size_t sector, ui
}
void aes_128_xts_nintendo_crypt_sector(unsigned int keyslot_1, unsigned int keyslot_2, size_t sector, bool encrypt, void *dst, const void *src, size_t size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if ((size & 0xF) || size == 0) {
generic_panic();
}
@@ -431,13 +472,13 @@ void aes_128_xts_nintendo_crypt_sector(unsigned int keyslot_1, unsigned int keys
/* Encrypt/Decrypt. */
if (encrypt) {
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
- SECURITY_ENGINE->CRYPTO_REG = keyslot_1 << 24 | 0x100;
+ se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
+ se->CRYPTO_REG = keyslot_1 << 24 | 0x100;
} else {
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
- SECURITY_ENGINE->CRYPTO_REG = keyslot_1 << 24;
+ se->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
+ se->CRYPTO_REG = keyslot_1 << 24;
}
- SECURITY_ENGINE->BLOCK_COUNT_REG = (size >> 4) - 1;
+ se->BLOCK_COUNT_REG = (size >> 4) - 1;
trigger_se_blocking_op(OP_START, dst, size, src, size);
/* XOR. */
@@ -469,6 +510,8 @@ void se_aes_128_xts_nintendo_decrypt(unsigned int keyslot_1, unsigned int keyslo
}
void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
@@ -481,17 +524,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
shift_left_xor_rb(derived_key);
}
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
- SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | (0x145);
+ se->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
+ se->CRYPTO_REG = (keyslot << 24) | (0x145);
clear_aes_keyslot_iv(keyslot);
-
unsigned int num_blocks = (data_size + 0xF) >> 4;
/* Handle aligned blocks. */
if (num_blocks > 1) {
- SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 2;
+ se->BLOCK_COUNT_REG = num_blocks - 2;
trigger_se_blocking_op(OP_START, NULL, 0, data, data_size);
- SECURITY_ENGINE->CRYPTO_REG |= 0x80;
+ se->CRYPTO_REG |= 0x80;
}
/* Create final block. */
@@ -508,12 +550,12 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
}
/* Perform last operation. */
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->BLOCK_COUNT_REG = 0;
trigger_se_blocking_op(OP_START, NULL, 0, last_block, sizeof(last_block));
/* Copy output CMAC. */
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
- ((uint32_t *)cmac)[i] = read32le(SECURITY_ENGINE->HASH_RESULT_REG, i << 2);
+ ((uint32_t *)cmac)[i] = read32le(se->HASH_RESULT_REG, i << 2);
}
}
@@ -525,42 +567,48 @@ void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size,
}
void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) {
generic_panic();
}
- SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16);
- SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x144;
+ se->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (0x202 << 16);
+ se->CRYPTO_REG = (keyslot << 24) | 0x144;
set_aes_keyslot_iv(keyslot, iv, 0x10);
- SECURITY_ENGINE->BLOCK_COUNT_REG = (src_size >> 4) - 1;
+ se->BLOCK_COUNT_REG = (src_size >> 4) - 1;
trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size);
}
/* SHA256 Implementation. */
void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
+ volatile tegra_se_t *se = se_get_regs();
+
/* Setup config for SHA256, size = BITS(src_size) */
- SECURITY_ENGINE->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
- SECURITY_ENGINE->SHA_CONFIG_REG = 1;
- SECURITY_ENGINE->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3);
- SECURITY_ENGINE->_0x208 = 0;
- SECURITY_ENGINE->_0x20C = 0;
- SECURITY_ENGINE->_0x210 = 0;
- SECURITY_ENGINE->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3);
- SECURITY_ENGINE->_0x218 = 0;
- SECURITY_ENGINE->_0x21C = 0;
- SECURITY_ENGINE->_0x220 = 0;
+ se->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
+ se->SHA_CONFIG_REG = 1;
+ se->SHA_MSG_LENGTH_REG = (uint32_t)(src_size << 3);
+ se->_0x208 = 0;
+ se->_0x20C = 0;
+ se->_0x210 = 0;
+ se->SHA_MSG_LEFT_REG = (uint32_t)(src_size << 3);
+ se->_0x218 = 0;
+ se->_0x21C = 0;
+ se->_0x220 = 0;
/* Trigger the operation. */
trigger_se_blocking_op(OP_START, NULL, 0, src, src_size);
/* Copy output hash. */
for (unsigned int i = 0; i < (0x20 >> 2); i++) {
- ((uint32_t *)dst)[i] = read32be(SECURITY_ENGINE->HASH_RESULT_REG, i << 2);
+ ((uint32_t *)dst)[i] = read32be(se->HASH_RESULT_REG, i << 2);
}
}
/* RNG API */
void se_initialize_rng(unsigned int keyslot) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
@@ -569,32 +617,33 @@ void se_initialize_rng(unsigned int keyslot) {
/* This will be discarded, when done. */
uint8_t ALIGN(16) output_buf[0x10];
- SECURITY_ENGINE->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */
- SECURITY_ENGINE->RNG_RESEED_INTERVAL_REG = 70001;
- SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY);
- SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x108;
- SECURITY_ENGINE->RNG_CONFIG_REG = 5;
- SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
+ se->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */
+ se->RNG_RESEED_INTERVAL_REG = 70001;
+ se->CONFIG_REG = (ALG_RNG | DST_MEMORY);
+ se->CRYPTO_REG = (keyslot << 24) | 0x108;
+ se->RNG_CONFIG_REG = 5;
+ se->BLOCK_COUNT_REG = 0;
trigger_se_blocking_op(OP_START, output_buf, 0x10, NULL, 0);
}
void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
+ volatile tegra_se_t *se = se_get_regs();
+
if (keyslot >= KEYSLOT_AES_MAX) {
generic_panic();
}
uint32_t num_blocks = size >> 4;
size_t aligned_size = num_blocks << 4;
- SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY);
- SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x108;
- SECURITY_ENGINE->RNG_CONFIG_REG = 4;
+ se->CONFIG_REG = (ALG_RNG | DST_MEMORY);
+ se->CRYPTO_REG = (keyslot << 24) | 0x108;
+ se->RNG_CONFIG_REG = 4;
if (num_blocks >= 1) {
- SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1;
+ se->BLOCK_COUNT_REG = num_blocks - 1;
trigger_se_blocking_op(OP_START, dst, aligned_size, NULL, 0);
}
if (size > aligned_size) {
se_perform_aes_block_operation(dst + aligned_size, size - aligned_size, NULL, 0);
}
-
}
diff --git a/fusee/fusee-primary/src/se.h b/fusee/fusee-primary/src/se.h
index a1ef7fa84..64998621a 100644
--- a/fusee/fusee-primary/src/se.h
+++ b/fusee/fusee-primary/src/se.h
@@ -1,7 +1,24 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_SE_H
#define FUSEE_SE_H
-#include
+#define SE_BASE 0x70012000
+#define MAKE_SE_REG(n) MAKE_REG32(SE_BASE + n)
#define KEYSLOT_SWITCH_LP0TZRAMKEY 0x2
#define KEYSLOT_SWITCH_SRKGENKEY 0x8
@@ -17,6 +34,9 @@
#define KEYSLOT_SWITCH_4XNEWCONSOLEKEYGENKEY 0xE
#define KEYSLOT_SWITCH_4XOLDDEVICEKEY 0xF
+/* This keyslot was added in 5.0.0. */
+#define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA
+
#define KEYSLOT_AES_MAX 0x10
#define KEYSLOT_RSA_MAX 0x2
@@ -71,7 +91,7 @@
#define RSA_2048_BYTES 0x100
-typedef struct security_engine {
+typedef struct {
uint32_t _0x0;
uint32_t _0x4;
uint32_t OPERATION_REG;
@@ -98,10 +118,10 @@ typedef struct security_engine {
uint32_t _0x21C;
uint32_t _0x220;
uint32_t _0x224;
- uint8_t _0x228[0x5C];
+ uint8_t _0x228[0x58];
uint32_t AES_KEY_READ_DISABLE_REG;
uint32_t AES_KEYSLOT_FLAGS[0x10];
- uint8_t _0x2C8[0x38];
+ uint8_t _0x2C4[0x3C];
uint32_t _0x300;
uint32_t CRYPTO_REG;
uint32_t CRYPTO_CTR_REG[4];
@@ -131,15 +151,13 @@ typedef struct security_engine {
uint32_t FLAGS_REG;
uint32_t ERR_STATUS_REG;
uint32_t _0x808;
- uint32_t _0x80C;
+ uint32_t SPARE_0;
uint32_t _0x810;
uint32_t _0x814;
uint32_t _0x818;
uint32_t _0x81C;
uint8_t _0x820[0x17E0];
-} security_engine_t;
-
-static_assert(sizeof(security_engine_t) == 0x2000, "Mis-defined Security Engine Registers!");
+} tegra_se_t;
typedef struct {
uint32_t address;
@@ -151,17 +169,10 @@ typedef struct {
se_addr_info_t addr_info; /* This should really be an array...but for our use case it works. */
} se_ll_t;
-
-/* WIP, API subject to change. */
-
-static inline volatile security_engine_t *get_security_engine(void) {
- return (volatile security_engine_t *)0x70012000;
+static inline volatile tegra_se_t *se_get_regs(void) {
+ return (volatile tegra_se_t *)SE_BASE;
}
-#define SECURITY_ENGINE (get_security_engine())
-
-/* This function MUST be registered to fire on the appropriate interrupt. */
-
void se_check_error_status_reg(void);
void se_check_for_error(void);
void se_trigger_interrupt(void);
diff --git a/fusee/fusee-primary/src/stage2.c b/fusee/fusee-primary/src/stage2.c
index 0d933f859..4d1e1d9da 100644
--- a/fusee/fusee-primary/src/stage2.c
+++ b/fusee/fusee-primary/src/stage2.c
@@ -1,14 +1,23 @@
-#include
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
-#include "utils.h"
-#include "display/video_fb.h"
-#include "fs_utils.h"
#include "stage2.h"
#include "chainloader.h"
-#include "lib/printk.h"
-#include "lib/vsprintf.h"
-#include "lib/ini.h"
-#include "lib/fatfs/ff.h"
+#include "fs_utils.h"
+#include "utils.h"
char g_stage2_path[0x100] = {0};
@@ -58,7 +67,7 @@ void load_stage2(const char *bct0) {
}
if (strlen(config.path) + 1 + sizeof(stage2_args_t) > CHAINLOADER_ARG_DATA_MAX_SIZE) {
- printk("Error: Stage2's path name is too big!\n");
+ print(SCREEN_LOG_LEVEL_ERROR, "Stage2's path name is too big!\n");
}
if (!check_32bit_address_loadable(config.entrypoint)) {
@@ -69,10 +78,10 @@ void load_stage2(const char *bct0) {
fatal_error("Stage2's load address is invalid!\n");
}
- printk("[DEBUG] Stage 2 Config:\n");
- printk(" File Path: %s\n", config.path);
- printk(" Load Address: 0x%08x\n", config.load_address);
- printk(" Entrypoint: 0x%p\n", config.entrypoint);
+ print(SCREEN_LOG_LEVEL_DEBUG, "Stage 2 Config:\n");
+ print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " File Path: %s\n", config.path);
+ print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " Load Address: 0x%08x\n", config.load_address);
+ print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " Entrypoint: 0x%p\n", config.entrypoint);
if (f_stat(config.path, &info) != FR_OK) {
fatal_error("Failed to stat stage2 (%s)!\n", config.path);
@@ -110,5 +119,6 @@ void load_stage2(const char *bct0) {
g_chainloader_entries[0].num = 0;
g_chainloader_entrypoint = config.entrypoint;
- strncpy(g_stage2_path, config.path, sizeof(g_stage2_path));
+ strncpy(g_stage2_path, config.path, sizeof(g_stage2_path) - 1);
+ g_stage2_path[sizeof(g_stage2_path) - 1] = '\0';
}
diff --git a/fusee/fusee-primary/src/stage2.h b/fusee/fusee-primary/src/stage2.h
index a2a5f1dbb..e453d159f 100644
--- a/fusee/fusee-primary/src/stage2.h
+++ b/fusee/fusee-primary/src/stage2.h
@@ -1,7 +1,30 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_STAGE2_H
#define FUSEE_STAGE2_H
-#include "sdmmc/sdmmc_core.h"
+#include
+#include
+
+#include "display/video_fb.h"
+#include "lib/log.h"
+#include "lib/vsprintf.h"
+#include "lib/ini.h"
+#include "lib/fatfs/ff.h"
/* TODO: Is there a more concise way to do this? */
#define STAGE2_ARGV_PROGRAM_PATH 0
@@ -21,7 +44,7 @@ typedef struct {
typedef struct {
uint32_t version;
- sdmmc_t sd_sdmmc;
+ ScreenLogLevel log_level;
bool display_initialized;
char bct0[BCTO_MAX_SIZE];
} stage2_args_t;
diff --git a/fusee/fusee-primary/src/start.s b/fusee/fusee-primary/src/start.s
index d4280470f..e417cd80e 100644
--- a/fusee/fusee-primary/src/start.s
+++ b/fusee/fusee-primary/src/start.s
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
.macro CLEAR_GPR_REG_ITER
mov r\@, #0
.endm
diff --git a/fusee/fusee-primary/src/sysctr0.h b/fusee/fusee-primary/src/sysctr0.h
new file mode 100644
index 000000000..f622e70b1
--- /dev/null
+++ b/fusee/fusee-primary/src/sysctr0.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_SYSCTR0_H
+#define FUSEE_SYSCTR0_H
+
+#include
+
+#define SYSCTR0_BASE 0x700F0000
+#define MAKE_SYSCTR0_REG(n) MAKE_REG32(SYSCTR0_BASE + n)
+
+#define SYSCTR0_CNTCR_0 MAKE_SYSCTR0_REG(0x00)
+#define SYSCTR0_CNTSR_0 MAKE_SYSCTR0_REG(0x04)
+#define SYSCTR0_CNTCV0_0 MAKE_SYSCTR0_REG(0x08)
+#define SYSCTR0_CNTCV1_0 MAKE_SYSCTR0_REG(0x0C)
+#define SYSCTR0_CNTFID0_0 MAKE_SYSCTR0_REG(0x20)
+#define SYSCTR0_CNTFID1_0 MAKE_SYSCTR0_REG(0x24)
+#define SYSCTR0_COUNTERID4_0 MAKE_SYSCTR0_REG(0xFD0)
+#define SYSCTR0_COUNTERID5_0 MAKE_SYSCTR0_REG(0xFD4)
+#define SYSCTR0_COUNTERID6_0 MAKE_SYSCTR0_REG(0xFD8)
+#define SYSCTR0_COUNTERID7_0 MAKE_SYSCTR0_REG(0xFDC)
+#define SYSCTR0_COUNTERID0_0 MAKE_SYSCTR0_REG(0xFE0)
+#define SYSCTR0_COUNTERID1_0 MAKE_SYSCTR0_REG(0xFE4)
+#define SYSCTR0_COUNTERID2_0 MAKE_SYSCTR0_REG(0xFE8)
+#define SYSCTR0_COUNTERID3_0 MAKE_SYSCTR0_REG(0xFEC)
+#define SYSCTR0_COUNTERID8_0 MAKE_SYSCTR0_REG(0xFF0)
+#define SYSCTR0_COUNTERID9_0 MAKE_SYSCTR0_REG(0xFF4)
+#define SYSCTR0_COUNTERID10_0 MAKE_SYSCTR0_REG(0xFF8)
+#define SYSCTR0_COUNTERID11_0 MAKE_SYSCTR0_REG(0xFFC)
+
+#endif
diff --git a/fusee/fusee-primary/src/sysreg.h b/fusee/fusee-primary/src/sysreg.h
new file mode 100644
index 000000000..1bc1a8c43
--- /dev/null
+++ b/fusee/fusee-primary/src/sysreg.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_SYSREG_H
+#define FUSEE_SYSREG_H
+
+#include
+
+#define SYSREG_BASE 0x6000C000
+#define SB_BASE (SYSREG_BASE + 0x200)
+#define EXCP_VEC_BASE 0x6000F000
+
+#define MAKE_SYSREG(n) MAKE_REG32(SYSREG_BASE + n)
+#define MAKE_SB_REG(n) MAKE_REG32(SB_BASE + n)
+#define MAKE_EXCP_VEC_REG(n) MAKE_REG32(EXCP_VEC_BASE + n)
+
+#define AHB_ARBITRATION_DISABLE_0 MAKE_SYSREG(0x004)
+#define AHB_ARBITRATION_XBAR_CTRL_0 MAKE_SYSREG(0x0E0)
+#define AHB_AHB_SPARE_REG_0 MAKE_SYSREG(0x110)
+
+#define SB_CSR_0 MAKE_SB_REG(0x00)
+#define SB_PIROM_START_0 MAKE_SB_REG(0x04)
+#define SB_PFCFG_0 MAKE_SB_REG(0x08)
+#define SB_SECURE_SPAREREG_0_0 MAKE_SB_REG(0x0C)
+#define SB_SECURE_SPAREREG_1_0 MAKE_SB_REG(0x10)
+#define SB_SECURE_SPAREREG_2_0 MAKE_SB_REG(0x14)
+#define SB_SECURE_SPAREREG_3_0 MAKE_SB_REG(0x18)
+#define SB_SECURE_SPAREREG_4_0 MAKE_SB_REG(0x1C)
+#define SB_SECURE_SPAREREG_5_0 MAKE_SB_REG(0x20)
+#define SB_SECURE_SPAREREG_6_0 MAKE_SB_REG(0x24)
+#define SB_SECURE_SPAREREG_7_0 MAKE_SB_REG(0x28)
+#define SB_AA64_RESET_LOW_0 MAKE_SB_REG(0x30)
+#define SB_AA64_RESET_HIGH_0 MAKE_SB_REG(0x34)
+
+#endif
diff --git a/fusee/fusee-primary/src/timers.h b/fusee/fusee-primary/src/timers.h
index c951f0427..1c2be85d7 100644
--- a/fusee/fusee-primary/src/timers.h
+++ b/fusee/fusee-primary/src/timers.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_TIMERS_H
#define FUSEE_TIMERS_H
@@ -5,7 +21,18 @@
#define TIMERS_BASE 0x60005000
#define MAKE_TIMERS_REG(n) MAKE_REG32(TIMERS_BASE + n)
-#define TIMERUS_CNTR_1US_0 MAKE_REG32(TIMERS_BASE + 0x10)
+
+#define TIMERUS_CNTR_1US_0 MAKE_TIMERS_REG(0x10)
+#define TIMERUS_USEC_CFG_0 MAKE_TIMERS_REG(0x14)
+#define SHARED_INTR_STATUS_0 MAKE_TIMERS_REG(0x1A0)
+#define SHARED_TIMER_SECURE_CFG_0 MAKE_TIMERS_REG(0x1A4)
+
+#define RTC_BASE 0x7000E000
+#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 {
uint32_t CONFIG;
@@ -16,27 +43,50 @@ typedef struct {
#define GET_WDT(n) ((volatile watchdog_timers_t *)(TIMERS_BASE + 0x100 + 0x20 * n))
#define WDT_REBOOT_PATTERN 0xC45A
-#define GET_WDT_REBOOT_CFG_REG(n) MAKE_REG32(TIMERS_BASE + 0x60 + 0x8*n)
+#define GET_WDT_REBOOT_CFG_REG(n) MAKE_REG32(TIMERS_BASE + 0x60 + 0x8 * n)
void wait(uint32_t microseconds);
-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;
}
+/**
+ * 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() - base;
+ return get_time_us() - base;
}
/**
* Delays for a given number of microseconds.
*/
-static inline void udelay(unsigned usecs) {
- uint32_t start = get_time();
- while (get_time() - start < usecs);
+static inline void udelay(uint32_t usecs) {
+ uint32_t start = get_time_us();
+ 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);
diff --git a/fusee/fusee-primary/src/uart.c b/fusee/fusee-primary/src/uart.c
new file mode 100644
index 000000000..99d3dd848
--- /dev/null
+++ b/fusee/fusee-primary/src/uart.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "uart.h"
+#include "timers.h"
+
+void uart_init(UartDevice dev, uint32_t baud) {
+ volatile tegra_uart_t *uart = uart_get_regs(dev);
+
+ /* Set baud rate. */
+ uint32_t rate = (8 * baud + 408000000) / (16 * baud);
+ uart->UART_LCR = UART_LCR_DLAB; /* Enable DLAB. */
+ uart->UART_THR_DLAB = (uint8_t)rate; /* Divisor latch LSB. */
+ uart->UART_IER_DLAB = (uint8_t)(rate >> 8); /* Divisor latch MSB. */
+ uart->UART_LCR = 0; /* Diable DLAB. */
+
+ /* Setup UART in fifo mode. */
+ uart->UART_IER_DLAB = 0;
+ uart->UART_IIR_FCR = UART_FCR_FCR_EN_FIFO | UART_FCR_RX_CLR | UART_FCR_TX_CLR; /* Enable and clear TX and RX FIFOs. */
+ (void)uart->UART_LSR;
+ udelay(3 * ((baud + 999999) / baud));
+ uart->UART_LCR = UART_LCR_WD_LENGTH_8; /* Set word length 8. */
+ uart->UART_MCR = 0;
+ uart->UART_MSR = 0;
+ uart->UART_IRDA_CSR = 0;
+ uart->UART_RX_FIFO_CFG = 1; /* Set RX_FIFO trigger level */
+ uart->UART_MIE = 0;
+ uart->UART_ASR = 0;
+}
+
+/* This function blocks until the UART device (dev) is in the desired state (status). Make sure the desired state can be reached! */
+void uart_wait_idle(UartDevice dev, UartVendorStatus status) {
+ while (!(uart_get_regs(dev)->UART_VENDOR_STATUS & status)) {
+ /* Wait */
+ }
+}
+
+void uart_send(UartDevice dev, const void *buf, size_t len) {
+ volatile tegra_uart_t *uart = uart_get_regs(dev);
+
+ for (size_t i = 0; i < len; i++) {
+ while (uart->UART_LSR & UART_LSR_TX_FIFO_FULL) {
+ /* Wait until the TX FIFO isn't full */
+ }
+ uart->UART_THR_DLAB = *((const uint8_t *)buf + i);
+ }
+}
+
+void uart_recv(UartDevice dev, void *buf, size_t len) {
+ volatile tegra_uart_t *uart = uart_get_regs(dev);
+
+ for (size_t i = 0; i < len; i++) {
+ while (uart->UART_LSR & UART_LSR_RX_FIFO_EMPTY) {
+ /* Wait until the RX FIFO isn't empty */
+ }
+ *((uint8_t *)buf + i) = uart->UART_THR_DLAB;
+ }
+}
diff --git a/fusee/fusee-primary/src/uart.h b/fusee/fusee-primary/src/uart.h
new file mode 100644
index 000000000..a4402daf4
--- /dev/null
+++ b/fusee/fusee-primary/src/uart.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FUSEE_UART_H
+#define FUSEE_UART_H
+
+#include
+
+#define UART_BASE 0x70006000
+
+#define BAUD_115200 115200
+
+/* UART devices */
+typedef enum {
+ UART_A = 0,
+ UART_B = 1,
+ UART_C = 2,
+ UART_D = 3,
+ UART_E = 4,
+} UartDevice;
+
+/* 36.3.12 UART_VENDOR_STATUS_0_0 */
+typedef enum {
+ UART_VENDOR_STATE_TX_IDLE = 1 << 0,
+ UART_VENDOR_STATE_RX_IDLE = 1 << 1,
+
+ /* This bit is set to 1 when a read is issued to an empty FIFO and gets cleared on register read (sticky bit until read)
+ 0 = NO_UNDERRUN
+ 1 = UNDERRUN
+ */
+ UART_VENDOR_STATE_RX_UNDERRUN = 1 << 2,
+
+ /* This bit is set to 1 when write data is issued to the TX FIFO when it is already full and gets cleared on register read (sticky bit until read)
+ 0 = NO_OVERRUN
+ 1 = OVERRUN
+ */
+ UART_VENDOR_STATE_TX_OVERRUN = 1 << 3,
+
+ UART_VENDOR_STATE_RX_FIFO_COUNTER = 0b111111 << 16, /* reflects number of current entries in RX FIFO */
+ UART_VENDOR_STATE_TX_FIFO_COUNTER = 0b111111 << 24 /* reflects number of current entries in TX FIFO */
+} UartVendorStatus;
+
+/* 36.3.6 UART_LSR_0 */
+typedef enum {
+ UART_LSR_RDR = 1 << 0, /* Receiver Data Ready */
+ UART_LSR_OVRF = 1 << 1, /* Receiver Overrun Error */
+ UART_LSR_PERR = 1 << 2, /* Parity Error */
+ UART_LSR_FERR = 1 << 3, /* Framing Error */
+ UART_LSR_BRK = 1 << 4, /* BREAK condition detected on line */
+ UART_LSR_THRE = 1 << 5, /* Transmit Holding Register is Empty -- OK to write data */
+ UART_LSR_TMTY = 1 << 6, /* Transmit Shift Register empty status */
+ UART_LSR_FIFOE = 1 << 7, /* Receive FIFO Error */
+ UART_LSR_TX_FIFO_FULL = 1 << 8, /* Transmitter FIFO full status */
+ UART_LSR_RX_FIFO_EMPTY = 1 << 9, /* Receiver FIFO empty status */
+} UartLineStatus;
+
+/* 36.3.4 UART_LCR_0 */
+typedef enum {
+ UART_LCR_WD_LENGTH_5 = 0, /* word length 5 */
+ UART_LCR_WD_LENGTH_6 = 1, /* word length 6 */
+ UART_LCR_WD_LENGTH_7 = 2, /* word length 7 */
+ UART_LCR_WD_LENGTH_8 = 3, /* word length 8 */
+
+ /* STOP:
+ 0 = Transmit 1 stop bit
+ 1 = Transmit 2 stop bits (receiver always checks for 1 stop bit)
+ */
+ UART_LCR_STOP = 1 << 2,
+ UART_LCR_PAR = 1 << 3, /* Parity enabled */
+ UART_LCR_EVEN = 1 << 4, /* Even parity format. There will always be an even number of 1s in the binary representation (PAR = 1) */
+ UART_LCR_SET_P = 1 << 5, /* Set (force) parity to value in LCR[4] */
+ UART_LCR_SET_B = 1 << 6, /* Set BREAK condition -- Transmitter sends all zeroes to indicate BREAK */
+ UART_LCR_DLAB = 1 << 7, /* Divisor Latch Access Bit (set to allow programming of the DLH, DLM Divisors) */
+} UartLineControl;
+
+/* 36.3.3 UART_IIR_FCR_0 */
+typedef enum {
+ UART_FCR_FCR_EN_FIFO = 1 << 0, /* Enable the transmit and receive FIFOs. This bit should be enabled */
+ UART_FCR_RX_CLR = 1 << 1, /* Clears the contents of the receive FIFO and resets its counter logic to 0 (the receive shift register is not cleared or altered). This bit returns to 0 after clearing the FIFOs */
+ UART_FCR_TX_CLR = 1 << 2, /* Clears the contents of the transmit FIFO and resets its counter logic to 0 (the transmit shift register is not cleared or altered). This bit returns to 0 after clearing the FIFOs */
+
+ /* DMA:
+ 0 = DMA_MODE_0
+ 1 = DMA_MODE_1
+ */
+ UART_FCR_DMA = 1 << 3,
+
+ /* TX_TRIG
+ 0 = FIFO_COUNT_GREATER_16
+ 1 = FIFO_COUNT_GREATER_8
+ 2 = FIFO_COUNT_GREATER_4
+ 3 = FIFO_COUNT_GREATER_1
+ */
+ UART_FCR_TX_TRIG = 3 << 4,
+ UART_FCR_TX_TRIG_FIFO_COUNT_GREATER_16 = 0 << 4,
+ UART_FCR_TX_TRIG_FIFO_COUNT_GREATER_8 = 1 << 4,
+ UART_FCR_TX_TRIG_FIFO_COUNT_GREATER_4 = 2 << 4,
+ UART_FCR_TX_TRIG_FIFO_COUNT_GREATER_1 = 3 << 4,
+
+ /* RX_TRIG
+ 0 = FIFO_COUNT_GREATER_1
+ 1 = FIFO_COUNT_GREATER_4
+ 2 = FIFO_COUNT_GREATER_8
+ 3 = FIFO_COUNT_GREATER_16
+ */
+ UART_FCR_RX_TRIG = 3 << 6,
+ UART_FCR_RX_TRIG_FIFO_COUNT_GREATER_1 = 0 << 6,
+ UART_FCR_RX_TRIG_FIFO_COUNT_GREATER_4 = 1 << 6,
+ UART_FCR_RX_TRIG_FIFO_COUNT_GREATER_8 = 2 << 6,
+ UART_FCR_RX_TRIG_FIFO_COUNT_GREATER_16 = 3 << 6,
+} UartFifoControl;
+
+/* 36.3.3 UART_IIR_FCR_0 */
+typedef enum {
+ UART_IIR_IS_STA = 1 << 0, /* Interrupt Pending if ZERO */
+ UART_IIR_IS_PRI0 = 1 << 1, /* Encoded Interrupt ID Refer to IIR[3:0] table [36.3.3] */
+ UART_IIR_IS_PRI1 = 1 << 2, /* Encoded Interrupt ID Refer to IIR[3:0] table */
+ UART_IIR_IS_PRI2 = 1 << 3, /* Encoded Interrupt ID Refer to IIR[3:0] table */
+
+ /* FIFO Mode Status
+ 0 = 16450 mode (no FIFO)
+ 1 = 16550 mode (FIFO)
+ */
+ UART_IIR_EN_FIFO = 3 << 6,
+ UART_IIR_MODE_16450 = 0 << 6,
+ UART_IIR_MODE_16550 = 1 << 6,
+} UartInterruptIdentification;
+
+typedef struct {
+ uint32_t UART_THR_DLAB;
+ uint32_t UART_IER_DLAB;
+ uint32_t UART_IIR_FCR;
+ uint32_t UART_LCR;
+ uint32_t UART_MCR;
+ uint32_t UART_LSR;
+ uint32_t UART_MSR;
+ uint32_t UART_SPR;
+ uint32_t UART_IRDA_CSR;
+ uint32_t UART_RX_FIFO_CFG;
+ uint32_t UART_MIE;
+ uint32_t UART_VENDOR_STATUS;
+ uint8_t _0x30[0x0C];
+ uint32_t UART_ASR;
+} tegra_uart_t;
+
+void uart_init(UartDevice dev, uint32_t baud);
+void uart_wait_idle(UartDevice dev, UartVendorStatus status);
+void uart_send(UartDevice dev, const void *buf, size_t len);
+void uart_recv(UartDevice dev, void *buf, size_t len);
+
+static inline volatile tegra_uart_t *uart_get_regs(UartDevice dev) {
+ static const size_t offsets[] = {0, 0x40, 0x200, 0x300, 0x400};
+ return (volatile tegra_uart_t *)(UART_BASE + offsets[dev]);
+}
+
+#endif
diff --git a/fusee/fusee-primary/src/utils.c b/fusee/fusee-primary/src/utils.c
index 1ffe4b249..ac3d7b61f 100644
--- a/fusee/fusee-primary/src/utils.c
+++ b/fusee/fusee-primary/src/utils.c
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include "utils.h"
@@ -7,12 +23,25 @@
#include "timers.h"
#include "panic.h"
#include "car.h"
+#include "btn.h"
-#include "lib/printk.h"
-#include "hwinit/btn.h"
+#include "lib/log.h"
#include
+#define u8 uint8_t
+#define u32 uint32_t
+#include "rebootstub_bin.h"
+#undef u8
+#undef u32
+
+void wait(uint32_t microseconds) {
+ uint32_t old_time = TIMERUS_CNTR_1US_0;
+ while (TIMERUS_CNTR_1US_0 - old_time <= microseconds) {
+ /* Spin-lock. */
+ }
+}
+
__attribute__((noreturn)) void watchdog_reboot(void) {
volatile watchdog_timers_t *wdt = GET_WDT(4);
wdt->PATTERN = WDT_REBOOT_PATTERN;
@@ -36,13 +65,21 @@ __attribute__((noreturn)) void pmc_reboot(uint32_t scratch0) {
}
}
-__attribute__((noreturn)) void car_reboot(void) {
- /* Reset the processor. */
- car_get_regs()->rst_dev_l |= 1<<2;
-
- while (true) {
- /* Wait for reboot. */
+__attribute__((noreturn)) void reboot_to_self(void) {
+ /* Patch SDRAM init to perform an SVC immediately after second write */
+ APBDEV_PMC_SCRATCH45_0 = 0x2E38DFFF;
+ APBDEV_PMC_SCRATCH46_0 = 0x6001DC28;
+ /* Set SVC handler to jump to reboot stub in IRAM. */
+ APBDEV_PMC_SCRATCH33_0 = 0x4003F000;
+ APBDEV_PMC_SCRATCH40_0 = 0x6000F208;
+
+ /* Copy reboot stub into IRAM high. */
+ for (size_t i = 0; i < rebootstub_bin_size; i += sizeof(uint32_t)) {
+ write32le((void *)0x4003F000, i, read32le(rebootstub_bin, i));
}
+
+ /* Trigger warm reboot. */
+ pmc_reboot(1 << 0);
}
__attribute__((noreturn)) void wait_for_button_and_reboot(void) {
@@ -50,7 +87,7 @@ __attribute__((noreturn)) void wait_for_button_and_reboot(void) {
while (true) {
button = btn_read();
if (button & BTN_POWER) {
- car_reboot();
+ reboot_to_self();
}
}
}
@@ -61,11 +98,11 @@ __attribute__ ((noreturn)) void generic_panic(void) {
__attribute__((noreturn)) void fatal_error(const char *fmt, ...) {
va_list args;
- printk("Fatal error: ");
+ print(SCREEN_LOG_LEVEL_ERROR, "Fatal error: ");
va_start(args, fmt);
- vprintk(fmt, args);
+ vprint(SCREEN_LOG_LEVEL_ERROR, fmt, args);
va_end(args);
- printk("\nPress POWER to reboot\n");
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"\nPress POWER to reboot\n");
wait_for_button_and_reboot();
}
@@ -86,27 +123,27 @@ void hexdump(const void* data, size_t size, uintptr_t addrbase) {
for (size_t i = 0; i < size; i++) {
if (i % 16 == 0) {
- printk("%0*" PRIXPTR ": | ", 2 * sizeof(addrbase), addrbase + i);
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "%0*" PRIXPTR ": | ", 2 * sizeof(addrbase), addrbase + i);
}
- printk("%02X ", d[i]);
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "%02X ", d[i]);
if (d[i] >= ' ' && d[i] <= '~') {
ascii[i % 16] = d[i];
} else {
ascii[i % 16] = '.';
}
if ((i+1) % 8 == 0 || i+1 == size) {
- printk(" ");
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, " ");
if ((i+1) % 16 == 0) {
- printk("| %s \n", ascii);
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "| %s \n", ascii);
} else if (i+1 == size) {
ascii[(i+1) % 16] = '\0';
if ((i+1) % 16 <= 8) {
- printk(" ");
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, " ");
}
for (size_t j = (i+1) % 16; j < 16; j++) {
- printk(" ");
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, " ");
}
- printk("| %s \n", ascii);
+ print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "| %s \n", ascii);
}
}
}
diff --git a/fusee/fusee-primary/src/utils.h b/fusee/fusee-primary/src/utils.h
index bb647f47d..58e53bffe 100644
--- a/fusee/fusee-primary/src/utils.h
+++ b/fusee/fusee-primary/src/utils.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2018 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#ifndef FUSEE_UTILS_H
#define FUSEE_UTILS_H
@@ -105,7 +121,7 @@ void hexdump(const void* data, size_t size, uintptr_t addrbase);
__attribute__((noreturn)) void watchdog_reboot(void);
__attribute__((noreturn)) void pmc_reboot(uint32_t scratch0);
-__attribute__((noreturn)) void car_reboot(void);
+__attribute__((noreturn)) void reboot_to_self(void);
__attribute__((noreturn)) void wait_for_button_and_reboot(void);
__attribute__((noreturn)) void generic_panic(void);
diff --git a/fusee/fusee-secondary/Makefile b/fusee/fusee-secondary/Makefile
index b200d0ae7..d4a0c2c91 100644
--- a/fusee/fusee-secondary/Makefile
+++ b/fusee/fusee-secondary/Makefile
@@ -12,6 +12,21 @@ AMS := $(TOPDIR)/../../
include $(DEVKITARM)/base_rules
+AMSBRANCH := $(shell git symbolic-ref --short HEAD)
+AMSHASH := $(shell git rev-parse --short HEAD)
+AMSREV := $(AMSBRANCH)-$(AMSHASH)
+
+ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
+ AMSREV := $(AMSREV)-dirty
+endif
+
+define _bin2o
+ bin2s $< | $(AS) -o $(@)
+ echo "extern const u8" `(echo $( `(echo $(