diff --git a/fusee_cpp/program/Makefile b/fusee_cpp/program/Makefile
index f87cead16..7eb6c1985 100644
--- a/fusee_cpp/program/Makefile
+++ b/fusee_cpp/program/Makefile
@@ -76,7 +76,7 @@ check_libexo_$(strip $1):
clean-$(strip $1):
@echo clean $(strip $1) ...
- @rm -fr $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) $$(OUTPUT_BASE)$(strip $2).bin $$(OUTPUT_BASE)$(strip $2).elf
+ @rm -fr $$(ATMOSPHERE_BUILD_DIR)/$(strip $1) $$(OUTPUT_BASE)$(strip $2).bin $$(OUTPUT_BASE)$(strip $2).lz4 $$(OUTPUT_BASE)$(strip $2).elf
endef
diff --git a/fusee_cpp/program/lz4_compress.py b/fusee_cpp/program/lz4_compress.py
index 2bf17a64d..8283044f4 100644
--- a/fusee_cpp/program/lz4_compress.py
+++ b/fusee_cpp/program/lz4_compress.py
@@ -16,7 +16,7 @@ def main(argc, argv):
with open(argv[1], 'rb') as f:
data = f.read()
with open(argv[2], 'wb') as f:
- f.write(lz4_compress(data))
+ f.write(lz4_compress(data[:0x2B000 + 0x11000]))
return 0
if __name__ == '__main__':
diff --git a/fusee_cpp/program/program.ld b/fusee_cpp/program/program.ld
index 5a6ea3adf..53c7167a1 100644
--- a/fusee_cpp/program/program.ld
+++ b/fusee_cpp/program/program.ld
@@ -1,17 +1,10 @@
OUTPUT_ARCH(arm)
ENTRY(_ZN3ams6nxboot5StartEv)
-MEMORY
-{
- NULL : ORIGIN = 0, LENGTH = 4K
- main : ORIGIN = 0x40001000, LENGTH = 0x2B000
- ovl : ORIGIN = 0x4002C000, LENGTH = 0x14000
-}
-
-
SECTIONS
{
/* =========== CODE section =========== */
+
PROVIDE(__start__ = ORIGIN(main));
. = __start__;
__main_start__ = . ;
@@ -20,7 +13,7 @@ SECTIONS
{
KEEP (*(.crt0 .crt0.*))
. = ALIGN(8);
- } >main
+ } >main AT>glob
.text :
{
@@ -30,26 +23,26 @@ SECTIONS
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
. = ALIGN(8);
- } >main
+ } >main AT>glob
.init :
{
KEEP( *(.init) )
. = ALIGN(8);
- } >main
+ } >main AT>glob
.plt :
{
*(.plt)
*(.iplt)
. = ALIGN(8);
- } >main
+ } >main AT>glob
.fini :
{
KEEP( *(.fini) )
. = ALIGN(8);
- } >main
+ } >main AT>glob
/* =========== RODATA section =========== */
@@ -60,30 +53,30 @@ SECTIONS
{
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(8);
- } >main
+ } >main AT>glob
- .eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } >main
- .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main
- .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >main
- .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } >main
+ .eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } >main AT>glob
+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main AT>glob
+ .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >main AT>glob
+ .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } >main AT>glob
- .hash : { *(.hash) } >main
+ .hash : { *(.hash) } >main AT>glob
/* =========== DATA section =========== */
. = ALIGN(8);
__data_start = . ;
- .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main
- .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >main
- .gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } >main
- .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } >main
+ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } >main AT>glob
+ .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >main AT>glob
+ .gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } >main AT>glob
+ .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } >main AT>glob
.preinit_array ALIGN(8) :
{
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
- } >main
+ } >main AT>glob
.init_array ALIGN(8) :
{
@@ -91,7 +84,7 @@ SECTIONS
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
- } >main
+ } >main AT>glob
.fini_array ALIGN(8) :
{
@@ -99,7 +92,7 @@ SECTIONS
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE (__fini_array_end = .);
- } >main
+ } >main AT>glob
.ctors ALIGN(8) :
{
@@ -107,7 +100,7 @@ SECTIONS
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
- } >main
+ } >main AT>glob
.dtors ALIGN(8) :
{
@@ -115,7 +108,7 @@ SECTIONS
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
- } >main
+ } >main AT>glob
__got_start__ = .;
@@ -128,7 +121,7 @@ SECTIONS
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
- } >main
+ } >main AT>glob
__bss_start__ = .;
.bss ALIGN(8) :
@@ -137,11 +130,17 @@ SECTIONS
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(16);
- } >main
- __bss_end__ = .;
+ } >main AT>glob
+ __bss_end__ = .;
__main_end__ = ABSOLUTE(.) ;
+ .main.fill : {
+ FILL(0x00000000)
+ . = ORIGIN(main) + LENGTH(main) - 1;
+ BYTE(0x00);
+ } >main AT>glob
+
/* ==================
==== Metadata ====
================== */
diff --git a/fusee_cpp/program/program.specs b/fusee_cpp/program/program.specs
index 7d174b721..6940a62b1 100644
--- a/fusee_cpp/program/program.specs
+++ b/fusee_cpp/program/program.specs
@@ -1,4 +1,4 @@
%rename link old_link
*link:
-%(old_link) -T %:getenv(TOPDIR /program.ld) --gc-sections --nmagic
\ No newline at end of file
+%(old_link) -T %:getenv(TOPDIR /program_ovl.ld) -T %:getenv(TOPDIR /program.ld) --gc-sections --nmagic
\ No newline at end of file
diff --git a/fusee_cpp/program/program_ovl.ld b/fusee_cpp/program/program_ovl.ld
new file mode 100644
index 000000000..acda8eb77
--- /dev/null
+++ b/fusee_cpp/program/program_ovl.ld
@@ -0,0 +1,22 @@
+MEMORY
+{
+ NULL : ORIGIN = 0, LENGTH = 4K
+ glob : ORIGIN = 0x40001000, LENGTH = 0x3F000
+ main : ORIGIN = 0x40001000, LENGTH = 0x2B000
+ ovl : ORIGIN = 0x4002C000, LENGTH = 0x14000
+}
+
+SECTIONS {
+ OVERLAY : NOCROSSREFS {
+ .ovl_sein {
+ fusee_secure_initialize.o(.text*);
+ fusee_secure_initialize.o(.rodata*);
+ fusee_secure_initialize.o(.data*);
+ fusee_secure_initialize.o(.bss*);
+ FILL(0x00000000)
+ . = ORIGIN(ovl) + LENGTH(ovl) - 1;
+ BYTE(0x00);
+ }
+ } >ovl AT>glob
+}
+INSERT AFTER .main.fill
\ No newline at end of file
diff --git a/fusee_cpp/program/source/fusee_main.cpp b/fusee_cpp/program/source/fusee_main.cpp
index f57175850..8e7c6d595 100644
--- a/fusee_cpp/program/source/fusee_main.cpp
+++ b/fusee_cpp/program/source/fusee_main.cpp
@@ -14,10 +14,14 @@
* along with this program. If not, see .
*/
#include
+#include "fusee_secure_initialize.hpp"
namespace ams::nxboot {
void Main() {
+ /* Perform secure hardware initialization. */
+ SecureInitialize();
+
/* TODO */
AMS_INFINITE_LOOP();
}
diff --git a/fusee_cpp/program/source/fusee_registers_di.hpp b/fusee_cpp/program/source/fusee_registers_di.hpp
new file mode 100644
index 000000000..92d834eff
--- /dev/null
+++ b/fusee_cpp/program/source/fusee_registers_di.hpp
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2018 naehrwert
+ * Copyright (C) 2018 CTCaer
+ * Copyright (c) 2018-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+#include
+
+#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_STATUS 0x37
+#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_SD_BL_PARAMETERS 0x4D7
+#define DC_DISP_SD_BL_CONTROL 0x4DC
+#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 SCAN_COLUMN (1 << 4)
+#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 LINE_STRIDE(x) (x)
+#define UV_LINE_STRIDE(x) (((x) & 0xffff) << 16)
+#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
+#define PITCH (0 << 0)
+#define TILED (1 << 0)
+#define BLOCK (2 << 0)
+#define BLOCK_HEIGHT(x) (((x) & 0x7) << 4)
+
+/*! Display serial interface registers. */
+#define _DSIREG(reg) ((reg) * 4)
+
+#define DSI_INCR_SYNCPT_CNTRL 0x1
+
+#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
+#define DSI_PAD_CONTROL_5_MARIKO 0x53
+#define DSI_PAD_CONTROL_6_MARIKO 0x54
+#define DSI_PAD_CONTROL_7_MARIKO 0x55
+#define DSI_INIT_SEQ_DATA_15 0x5F
+
+#define DSI_INIT_SEQ_DATA_15_MARIKO 0x62
+
+#define NV_PVIC_THI_SLCG_OVERRIDE_LOW_A 0x8C
diff --git a/fusee_cpp/program/source/fusee_secure_initialize.cpp b/fusee_cpp/program/source/fusee_secure_initialize.cpp
new file mode 100644
index 000000000..24d12d372
--- /dev/null
+++ b/fusee_cpp/program/source/fusee_secure_initialize.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2018-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#include
+#include "fusee_secure_initialize.hpp"
+#include "fusee_registers_di.hpp"
+
+namespace ams::nxboot {
+
+ namespace {
+
+ constexpr inline const uintptr_t CLKRST = secmon::MemoryRegionPhysicalDeviceClkRst.GetAddress();
+ constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress();
+ constexpr inline const uintptr_t AHB = AHB_ARBC(0);
+ constexpr inline const uintptr_t I2S = I2S_REG(0);
+ constexpr inline const uintptr_t DISP1 = secmon::MemoryRegionPhysicalDeviceDisp1.GetAddress();
+ constexpr inline const uintptr_t VIC = secmon::MemoryRegionPhysicalDeviceDsi.GetAddress() + 0x40000;
+
+ void DoRcmWorkaround(const void *sbk, size_t sbk_size) {
+ /* Set the SBK inside the security engine. */
+ se::SetAesKey(pkg1::AesKeySlot_SecureBoot, sbk, sbk_size);
+
+ /* Lock the SBK/SSK as unreadable. */
+ se::LockAesKeySlot(pkg1::AesKeySlot_SecureBoot, se::KeySlotLockFlags_KeyRead);
+ se::LockAesKeySlot(pkg1::AesKeySlot_SecureStorage, se::KeySlotLockFlags_KeyRead);
+
+ /* Clear TZRAM. */
+ std::memset(secmon::MemoryRegionPhysicalTzram.GetPointer(), 0, secmon::MemoryRegionPhysicalTzram.GetSize());
+
+ /* Clear APBDEV_PMC_CRYPTO_OP. */
+ reg::Write(PMC + APBDEV_PMC_CRYPTO_OP, 0);
+
+ /* Clear the boot reason. */
+ reg::Write(PMC + APBDEV_PMC_SCRATCH200, 0);
+ reg::Write(PMC + APBDEV_PMC_CRYPTO_OP, 0);
+
+ /* Clear OBS_OVERRIDE/APB2JTAG_OVERRIDE */
+ reg::ReadWrite(AHB + AHB_AHB_SPARE_REG, AHB_REG_BITS_ENUM(AHB_SPARE_REG_OBS_OVERRIDE_EN, DISABLE),
+ AHB_REG_BITS_ENUM(AHB_SPARE_REG_APB2JTAG_OVERRIDE_EN, DISABLE));
+
+ /* Clear low bits of APBDEV_PMC_SCRATCH49 */
+ reg::ClearBits(PMC + APBDEV_PMC_SCRATCH49, 0x3);
+ }
+
+ void DoMbistWorkaround() {
+ /* Configure CLK_RST_CONTROLLER_CLK_SOURCE_SOR1. */
+ reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_SOR1_SOR1_CLK_SEL0, MUX),
+ CLK_RST_REG_BITS_ENUM(CLK_SOURCE_SOR1_SOR1_CLK_SEL1, SOR1_CLOCK_SWITCH));
+
+ /* Set CSI clock source as PLLD. */
+ reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_PLLD_BASE, CLK_RST_REG_BITS_ENUM(PLLD_BASE_PLLD_ENABLE, ENABLE),
+ CLK_RST_REG_BITS_ENUM(PLLD_BASE_CSI_CLK_SRC, PLL_D));
+
+ /* Clear APE, VIC, HOST1X, DISP1 reset. */
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_Y_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_Y_APE_RST, ENABLE));
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_X_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_X_VIC_RST, ENABLE));
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_L_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_L_DISP1_RST, ENABLE), CLK_RST_REG_BITS_ENUM(RST_DEV_L_HOST1X_RST, ENABLE));
+
+ /* Wait two microseconds for the devices to come out of reset. */
+ util::WaitMicroSeconds(2);
+
+ /* Set I2S_CTRL.MASTER and clear I2S_CG.SCLG_ENABLE for all I2S registers. */
+ reg::ReadWrite(I2S + I2S0_I2S_CTRL, I2S_REG_BITS_ENUM(I2S_CTRL_MASTER, ENABLE));
+ reg::ReadWrite(I2S + I2S0_I2S_CG, I2S_REG_BITS_ENUM(I2S_CG_SLCG_ENABLE, FALSE));
+ reg::ReadWrite(I2S + I2S1_I2S_CTRL, I2S_REG_BITS_ENUM(I2S_CTRL_MASTER, ENABLE));
+ reg::ReadWrite(I2S + I2S1_I2S_CG, I2S_REG_BITS_ENUM(I2S_CG_SLCG_ENABLE, FALSE));
+ reg::ReadWrite(I2S + I2S2_I2S_CTRL, I2S_REG_BITS_ENUM(I2S_CTRL_MASTER, ENABLE));
+ reg::ReadWrite(I2S + I2S2_I2S_CG, I2S_REG_BITS_ENUM(I2S_CG_SLCG_ENABLE, FALSE));
+ reg::ReadWrite(I2S + I2S3_I2S_CTRL, I2S_REG_BITS_ENUM(I2S_CTRL_MASTER, ENABLE));
+ reg::ReadWrite(I2S + I2S3_I2S_CG, I2S_REG_BITS_ENUM(I2S_CG_SLCG_ENABLE, FALSE));
+ reg::ReadWrite(I2S + I2S4_I2S_CTRL, I2S_REG_BITS_ENUM(I2S_CTRL_MASTER, ENABLE));
+ reg::ReadWrite(I2S + I2S4_I2S_CG, I2S_REG_BITS_ENUM(I2S_CG_SLCG_ENABLE, FALSE));
+
+ /* Set DC_COM_DSC_TOP_CTL.DSC_SLG_OVERRIDE */
+ reg::SetBits(DISP1 + DC_COM_DSC_TOP_CTL * sizeof(u32), 0x4);
+
+ /* Set NV_PVIC_THI_SLCG_OVERRIDE_LOW_A */
+ reg::SetBits(VIC + NV_PVIC_THI_SLCG_OVERRIDE_LOW_A, 0xFFFFFFFF);
+
+ /* Wait two microseconds for configuration to take. */
+ util::WaitMicroSeconds(2);
+
+ /* Set APE, VIC, HOST1X, DISP1 reset. */
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_Y_SET, CLK_RST_REG_BITS_ENUM(RST_DEV_Y_APE_RST, ENABLE));
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_L_SET, CLK_RST_REG_BITS_ENUM(RST_DEV_L_DISP1_RST, ENABLE), CLK_RST_REG_BITS_ENUM(RST_DEV_L_HOST1X_RST, ENABLE));
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_X_SET, CLK_RST_REG_BITS_ENUM(RST_DEV_X_VIC_RST, ENABLE));
+
+ /* Set clock enable for a select few devices. */
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_REG_BITS_ENUM(CLK_ENB_H_CLK_ENB_FUSE, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_H_CLK_ENB_PMC, ENABLE));
+
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_REG_BITS_ENUM(CLK_ENB_L_CLK_ENB_CACHE2, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_L_CLK_ENB_GPIO, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_L_CLK_ENB_TMR, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_L_CLK_ENB_RTC, ENABLE));
+
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_CRAM2, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_IRAMD, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_IRAMC, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_IRAMB, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_IRAMA, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_U_CLK_ENB_CSITE, ENABLE));
+
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_REG_BITS_ENUM(CLK_ENB_V_CLK_ENB_SE, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_V_CLK_ENB_SPDIF_DOUBLER, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_V_CLK_ENB_APB2APE, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_V_CLK_ENB_MSELECT, ENABLE));
+
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_MC1, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_ENTROPY, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX5, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX4, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX3, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX2, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX1, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_W_CLK_ENB_PCIERX0, ENABLE));
+
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_PLLG_REF, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_DBGAPB, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_GPU, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_MC_BBC, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_MC_CPU, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_MC_CBPA, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_MC_CAPA, ENABLE));
+
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_REG_BITS_ENUM(CLK_ENB_Y_CLK_ENB_MC_CDPA, ENABLE),
+ CLK_RST_REG_BITS_ENUM(CLK_ENB_Y_CLK_ENB_MC_CCPA, ENABLE));
+
+ /* Clear all LVL2 clock gate overrides to zero. */
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA, 0);
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB, 0);
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC, 0);
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD, 0);
+ reg::Write(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE, 0);
+
+ /* Reset CSI clock source. */
+ reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_PLLD_BASE, CLK_RST_REG_BITS_ENUM(PLLD_BASE_PLLD_BYPASS, DISABLE),
+ CLK_RST_REG_BITS_ENUM(PLLD_BASE_PLLD_ENABLE, DISABLE),
+ CLK_RST_REG_BITS_ENUM(PLLD_BASE_PLLD_REF_DIS, REF_ENABLE),
+ CLK_RST_REG_BITS_ENUM(PLLD_BASE_CSI_CLK_SRC, BRICK));
+
+ /* Configure CLK_RST_CONTROLLER_CLK_SOURCE_SOR1. */
+ reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_SOR1_SOR1_CLK_SEL0, MUX),
+ CLK_RST_REG_BITS_ENUM(CLK_SOURCE_SOR1_SOR1_CLK_SEL1, SAFE_CLOCK));
+
+ /* Configure VI, HOST1X, NVENC clock sources. */
+ reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_VI, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_VI_VI_CLK_SRC, PLLP_OUT0));
+ reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_HOST1X_HOST1X_CLK_SRC, PLLP_OUT0));
+ reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_NVENC, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_NVENC_NVENC_CLK_SRC, PLLP_OUT0));
+ }
+
+ }
+
+ void SecureInitialize() {
+ /* Get SoC type. */
+ const auto soc_type = fuse::GetSocType();
+
+ /* If Erista, perform bootrom logic (to compensate for RCM exploit) and MBIST workaround. */
+ if (soc_type == fuse::SocType_Erista) {
+ /* Potentially perform bootrom compensation. */
+ {
+ u32 sbk[4];
+ if (fuse::GetSecureBootKey(sbk)) {
+ DoRcmWorkaround(sbk, sizeof(sbk));
+ }
+ }
+ DoMbistWorkaround();
+ }
+
+ /* TODO */
+ }
+
+}
diff --git a/fusee_cpp/program/source/fusee_secure_initialize.hpp b/fusee_cpp/program/source/fusee_secure_initialize.hpp
new file mode 100644
index 000000000..0c3563b87
--- /dev/null
+++ b/fusee_cpp/program/source/fusee_secure_initialize.hpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#include
+#pragma once
+
+namespace ams::nxboot {
+
+ void SecureInitialize();
+
+}
\ No newline at end of file
diff --git a/libraries/libexosphere/include/exosphere/clkrst.hpp b/libraries/libexosphere/include/exosphere/clkrst.hpp
index 2ee681490..2935eb2c1 100644
--- a/libraries/libexosphere/include/exosphere/clkrst.hpp
+++ b/libraries/libexosphere/include/exosphere/clkrst.hpp
@@ -29,6 +29,21 @@ namespace ams::clkrst {
void EnableI2c1Clock();
void EnableI2c5Clock();
+
+ void EnableHost1xClock();
+ void EnableTsecClock();
+ void EnableSorSafeClock();
+ void EnableSor0Clock();
+ void EnableSor1Clock();
+ void EnableKfuseClock();
+
void DisableI2c1Clock();
+ void DisableHost1xClock();
+ void DisableTsecClock();
+ void DisableSorSafeClock();
+ void DisableSor0Clock();
+ void DisableSor1Clock();
+ void DisableKfuseClock();
+
}
\ No newline at end of file
diff --git a/libraries/libexosphere/include/exosphere/fuse.hpp b/libraries/libexosphere/include/exosphere/fuse.hpp
index 3c042db84..7e841ff36 100644
--- a/libraries/libexosphere/include/exosphere/fuse.hpp
+++ b/libraries/libexosphere/include/exosphere/fuse.hpp
@@ -100,6 +100,8 @@ namespace ams::fuse {
DramId GetDramId();
+ bool GetSecureBootKey(void *dst);
+
void GetEcid(br::BootEcid *out);
HardwareType GetHardwareType();
HardwareState GetHardwareState();
diff --git a/libraries/libexosphere/include/exosphere/tsec.hpp b/libraries/libexosphere/include/exosphere/tsec.hpp
index 454da2efe..0ae458f6f 100644
--- a/libraries/libexosphere/include/exosphere/tsec.hpp
+++ b/libraries/libexosphere/include/exosphere/tsec.hpp
@@ -18,6 +18,8 @@
namespace ams::tsec {
+ bool RunTsecFirmware(const void *fw, size_t fw_size);
+
void Lock();
}
\ No newline at end of file
diff --git a/libraries/libexosphere/source/clkrst/clkrst_api.cpp b/libraries/libexosphere/source/clkrst/clkrst_api.cpp
index 8b3967804..b0f7f7820 100644
--- a/libraries/libexosphere/source/clkrst/clkrst_api.cpp
+++ b/libraries/libexosphere/source/clkrst/clkrst_api.cpp
@@ -62,11 +62,21 @@ namespace ams::clkrst {
.reset_offset = CLK_RST_CONTROLLER_RST_DEVICES_##_REG_, \
.clk_enb_offset = CLK_RST_CONTROLLER_CLK_OUT_ENB_##_REG_, \
.clk_src_offset = CLK_RST_CONTROLLER_CLK_SOURCE_##_NAME_, \
- .index = CLK_RST_CONTROLLER_CLK_ENB_##_NAME_##_INDEX, \
+ .index = CLK_RST_CONTROLLER_CLK_ENB_##_NAME_##_INDEX, \
.clk_src = CLK_RST_CONTROLLER_CLK_SOURCE_##_NAME_##_##_NAME_##_CLK_SRC_##_CLK_, \
.clk_div = _DIV_, \
}
+ #define DEFINE_CLOCK_PARAMETERS_WITHOUT_CLKDIV(_VARNAME_, _REG_, _NAME_) \
+ constexpr inline const ClockParameters _VARNAME_ = { \
+ .reset_offset = CLK_RST_CONTROLLER_RST_DEVICES_##_REG_, \
+ .clk_enb_offset = CLK_RST_CONTROLLER_CLK_OUT_ENB_##_REG_, \
+ .clk_src_offset = 0, \
+ .index = CLK_RST_CONTROLLER_CLK_ENB_##_NAME_##_INDEX, \
+ .clk_src = 0, \
+ .clk_div = 0, \
+ }
+
DEFINE_CLOCK_PARAMETERS(UartAClock, L, UARTA, PLLP_OUT0, 0);
DEFINE_CLOCK_PARAMETERS(UartBClock, L, UARTB, PLLP_OUT0, 0);
DEFINE_CLOCK_PARAMETERS(UartCClock, H, UARTC, PLLP_OUT0, 0);
@@ -74,6 +84,14 @@ namespace ams::clkrst {
DEFINE_CLOCK_PARAMETERS(I2c5Clock, H, I2C5, CLK_M, 0);
DEFINE_CLOCK_PARAMETERS(ActmonClock, V, ACTMON, CLK_M, 0);
+ DEFINE_CLOCK_PARAMETERS(Host1xClock, L, HOST1X, PLLP_OUT0, 3);
+ DEFINE_CLOCK_PARAMETERS(TsecClock, U, TSEC, PLLP_OUT0, 2);
+ DEFINE_CLOCK_PARAMETERS(Sor1Clock, X, SOR1, PLLP_OUT0, 2);
+
+ DEFINE_CLOCK_PARAMETERS_WITHOUT_CLKDIV(SorSafeClock, Y, SOR_SAFE);
+ DEFINE_CLOCK_PARAMETERS_WITHOUT_CLKDIV(Sor0Clock, X, SOR0);
+ DEFINE_CLOCK_PARAMETERS_WITHOUT_CLKDIV(KfuseClock, H, KFUSE);
+
}
void SetRegisterAddress(uintptr_t address) {
@@ -108,8 +126,56 @@ namespace ams::clkrst {
EnableClock(I2c5Clock);
}
+ void EnableHost1xClock() {
+ EnableClock(Host1xClock);
+ }
+
+ void EnableTsecClock() {
+ EnableClock(TsecClock);
+ }
+
+ void EnableSorSafeClock() {
+ EnableClock(SorSafeClock);
+ }
+
+ void EnableSor0Clock() {
+ EnableClock(Sor0Clock);
+ }
+
+ void EnableSor1Clock() {
+ EnableClock(Sor1Clock);
+ }
+
+ void EnableKfuseClock() {
+ EnableClock(KfuseClock);
+ }
+
void DisableI2c1Clock() {
DisableClock(I2c1Clock);
}
+ void DisableHost1xClock() {
+ DisableClock(Host1xClock);
+ }
+
+ void DisableTsecClock() {
+ DisableClock(TsecClock);
+ }
+
+ void DisableSorSafeClock() {
+ DisableClock(SorSafeClock);
+ }
+
+ void DisableSor0Clock() {
+ DisableClock(Sor0Clock);
+ }
+
+ void DisableSor1Clock() {
+ DisableClock(Sor1Clock);
+ }
+
+ void DisableKfuseClock() {
+ DisableClock(KfuseClock);
+ }
+
}
diff --git a/libraries/libexosphere/source/fuse/fuse_api.cpp b/libraries/libexosphere/source/fuse/fuse_api.cpp
index ba9157643..c7543c1d6 100644
--- a/libraries/libexosphere/source/fuse/fuse_api.cpp
+++ b/libraries/libexosphere/source/fuse/fuse_api.cpp
@@ -432,6 +432,19 @@ namespace ams::fuse {
return reg::HasValue(GetChipRegistersCommon().FUSE_SECURITY_MODE, FUSE_REG_BITS_ENUM(SECURITY_MODE_SECURITY_MODE, ENABLED));
}
+ bool GetSecureBootKey(void *dst) {
+ /* Get the sbk from fuse data. */
+ bool valid = false;
+ for (size_t i = 0; i < 4; ++i) {
+ const u32 key_word = GetChipRegistersCommon().FUSE_PRIVATE_KEY[i];
+
+ static_cast(dst)[i] = key_word;
+ valid |= key_word != 0xFFFFFFFF;
+ }
+
+ return valid;
+ }
+
void ConfigureFuseBypass() {
/* Make the fuse registers visible. */
clkrst::SetFuseVisibility(true);
diff --git a/libraries/libexosphere/source/tsec/tsec_api.cpp b/libraries/libexosphere/source/tsec/tsec_api.cpp
index b8994ebc4..a251b91f2 100644
--- a/libraries/libexosphere/source/tsec/tsec_api.cpp
+++ b/libraries/libexosphere/source/tsec/tsec_api.cpp
@@ -19,8 +19,41 @@ namespace ams::tsec {
namespace {
+ enum TsecResult {
+ TsecResult_Success = 0xB0B0B0B0,
+ TsecResult_Failure = 0xD0D0D0D0,
+ };
+ bool RunFirmwareImpl(const void *fw, size_t fw_size) {
+ /* Enable relevant clocks. */
+ clkrst::EnableHost1xClock();
+ clkrst::EnableTsecClock();
+ clkrst::EnableSorSafeClock();
+ clkrst::EnableSor0Clock();
+ clkrst::EnableSor1Clock();
+ clkrst::EnableKfuseClock();
+ /* Disable clocks once we're done. */
+ ON_SCOPE_EXIT {
+ clkrst::DisableHost1xClock();
+ clkrst::DisableTsecClock();
+ clkrst::DisableSorSafeClock();
+ clkrst::DisableSor0Clock();
+ clkrst::DisableSor1Clock();
+ clkrst::DisableKfuseClock();
+ };
+
+ /* TODO */
+ AMS_UNUSED(fw, fw_size);
+ return true;
+ }
+
+ }
+
+ bool RunTsecFirmware(const void *fw, size_t fw_size) {
+ /* TODO */
+ AMS_UNUSED(fw, fw_size);
+ return RunFirmwareImpl(fw, fw_size);
}
void Lock() {
diff --git a/libraries/libvapours/include/vapours/tegra.hpp b/libraries/libvapours/include/vapours/tegra.hpp
index ac69ce1b2..e8887310f 100644
--- a/libraries/libvapours/include/vapours/tegra.hpp
+++ b/libraries/libvapours/include/vapours/tegra.hpp
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp b/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp
index 212000363..8287db38f 100644
--- a/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp
+++ b/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp
@@ -62,6 +62,11 @@ DEFINE_CLK_RST_REG(MISC_CLK_ENB_CFG_ALL_VISIBLE, 28, 1);
DEFINE_CLK_RST_REG_BIT_ENUM(OSC_CTRL_XOE, 0, DISABLE, ENABLE);
DEFINE_CLK_RST_REG(OSC_CTRL_XOFS, 4, 6);
+DEFINE_CLK_RST_REG_BIT_ENUM(PLLD_BASE_CSI_CLK_SRC, 23, BRICK, PLL_D);
+DEFINE_CLK_RST_REG_BIT_ENUM(PLLD_BASE_PLLD_REF_DIS, 29, REF_ENABLE, REF_DISABLE);
+DEFINE_CLK_RST_REG_BIT_ENUM(PLLD_BASE_PLLD_ENABLE, 30, DISABLE, ENABLE);
+DEFINE_CLK_RST_REG_BIT_ENUM(PLLD_BASE_PLLD_BYPASS, 31, DISABLE, ENABLE);
+
DEFINE_CLK_RST_REG_BIT_ENUM(PLLX_BASE_PLLX_ENABLE, 30, DISABLE, ENABLE);
DEFINE_CLK_RST_REG(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIVISOR, 0, 8);
@@ -111,37 +116,48 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_ENABLE, 30, DISABLE, ENABLE);
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C1 (0x124)
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C5 (0x128)
#define CLK_RST_CONTROLLER_CLK_SOURCE_DISP1 (0x138)
+#define CLK_RST_CONTROLLER_CLK_SOURCE_VI (0x148)
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1 (0x150)
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2 (0x154)
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4 (0x164)
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA (0x178)
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB (0x17C)
+#define CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X (0x180)
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C2 (0x198)
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC (0x1A0)
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C3 (0x1B8)
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 (0x1BC)
#define CLK_RST_CONTROLLER_CLK_SOURCE_CSITE (0x1D4)
+#define CLK_RST_CONTROLLER_CLK_SOURCE_TSEC (0x1F4)
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT (0x3B4)
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C4 (0x3C4)
#define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON (0x3E8)
+#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 (0x410)
#define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP (0x620)
#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_REF (0x62C)
#define CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_SOC (0x630)
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 (0x65C)
#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL (0x66C)
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM (0x694)
+#define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC (0x6A4)
/* RST_DEV_*_SET */
#define CLK_RST_CONTROLLER_RST_DEV_L_SET (0x300)
#define CLK_RST_CONTROLLER_RST_DEV_H_SET (0x308)
#define CLK_RST_CONTROLLER_RST_DEV_U_SET (0x310)
#define CLK_RST_CONTROLLER_RST_DEV_V_SET (0x430)
+#define CLK_RST_CONTROLLER_RST_DEV_W_SET (0x438)
+#define CLK_RST_CONTROLLER_RST_DEV_X_SET (0x290)
+#define CLK_RST_CONTROLLER_RST_DEV_Y_SET (0x2A8)
/* RST_DEV_*_CLR */
#define CLK_RST_CONTROLLER_RST_DEV_L_CLR (0x304)
#define CLK_RST_CONTROLLER_RST_DEV_H_CLR (0x30C)
#define CLK_RST_CONTROLLER_RST_DEV_U_CLR (0x314)
#define CLK_RST_CONTROLLER_RST_DEV_V_CLR (0x434)
+#define CLK_RST_CONTROLLER_RST_DEV_W_CLR (0x43C)
+#define CLK_RST_CONTROLLER_RST_DEV_X_CLR (0x294)
+#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR (0x2AC)
/* CLK_ENB_*_SET */
#define CLK_RST_CONTROLLER_CLK_ENB_L_SET (0x320)
@@ -193,6 +209,13 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_ENABLE, 30, DISABLE, ENABLE);
#define CLK_RST_CONTROLLER_CLK_ENB_ACTMON_INDEX (0x17)
+#define CLK_RST_CONTROLLER_CLK_ENB_HOST1X_INDEX (0x1C)
+#define CLK_RST_CONTROLLER_CLK_ENB_TSEC_INDEX (0x13)
+#define CLK_RST_CONTROLLER_CLK_ENB_SOR0_INDEX (0x16)
+#define CLK_RST_CONTROLLER_CLK_ENB_SOR1_INDEX (0x17)
+#define CLK_RST_CONTROLLER_CLK_ENB_SOR_SAFE_INDEX (0x1E)
+#define CLK_RST_CONTROLLER_CLK_ENB_KFUSE_INDEX (0x08)
+
/* RST_CPUG_CMPLX_* */
#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET (0x450)
#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR (0x454)
@@ -235,6 +258,19 @@ DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_UARTA_UARTA_CLK_SRC, 29, PLLP_OUT0,
DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_UARTB_UARTB_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT0, RESERVED4, PLLC4_OUT1, CLK_M, PLLC4_OUT2);
DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_UARTC_UARTC_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT0, RESERVED4, PLLC4_OUT1, CLK_M, PLLC4_OUT2);
+DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_VI_VI_CLK_SRC, 29, RESERVED0, PLLC2_OUT0, PLLC_OUT, PLLC3_OUT0, PLLP_OUT0, CLK_M, PLLA1_OUT0, PLLC4_OUT0);
+
+DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_HOST1X_HOST1X_CLK_SRC, 29, PLLC4_OUT1, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT2, PLLP_OUT0, CLK_M, PLLA_OUT0, PLLC4_OUT0);
+
+DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_NVENC_NVENC_CLK_SRC, 29, RESERVED0, PLLC2_OUT0, PLLC_OUT0, PLLC3_OUT0, PLLP_OUT0, RESERVED5, PLLA1_OUT0, CLK_M);
+
+DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_TSEC_TSEC_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC3_OUT0, RESERVED4, PLLA1_OUT0, CLK_M, PLLC4_OUT0);
+
+DEFINE_CLK_RST_REG_BIT_ENUM(CLK_SOURCE_SOR1_SOR1_CLK_SEL0, 14, MUX, SOR1_BRICK_OUTPUT);
+DEFINE_CLK_RST_REG_BIT_ENUM(CLK_SOURCE_SOR1_SOR1_CLK_SEL1, 15, SAFE_CLOCK, SOR1_CLOCK_SWITCH);
+
+DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_SOR1_SOR1_CLK_SRC, 29, PLLP_OUT0, RESERVED1, PLLD_OUT0, RESERVED3, RESERVED4, PLLD2_OUT0, CLK_M, RESERVED7);
+
DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_MSELECT_MSELECT_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT2, PLLC4_OUT1, CLK_S, CLK_M, PLLC4_OUT0);
DEFINE_CLK_RST_REG(CLK_SOURCE_MSELECT_MSELECT_CLK_DIVISOR, 0, 8);
@@ -302,6 +338,7 @@ DEFINE_CLK_RST_REG_BIT_ENUM(RST_CPUG_CMPLX_CLR_CLR_NONCPURESET, 29, DISABLE, ENA
HANDLER(U, CRAM2, 2, 24) \
HANDLER(V, CPUG, 3, 0) \
HANDLER(V, MSELECT, 3, 3) \
+ HANDLER(V, APB2APE, 3, 11) \
HANDLER(V, SPDIF_DOUBLER, 3, 22) \
HANDLER(V, ACTMON, 3, 23) \
HANDLER(V, TZRAM, 3, 30) \
@@ -322,10 +359,12 @@ DEFINE_CLK_RST_REG_BIT_ENUM(RST_CPUG_CMPLX_CLR_CLR_NONCPURESET, 29, DISABLE, ENA
HANDLER(X, MC_BBC, 5, 10) \
HANDLER(X, EMC_DLL, 5, 14) \
HANDLER(X, UART_FST_MIPI_CAL, 5, 17) \
+ HANDLER(X, VIC, 5, 18) \
HANDLER(X, GPU, 5, 24) \
HANDLER(X, DBGAPB, 5, 25) \
HANDLER(X, PLLG_REF, 5, 29) \
HANDLER(Y, LEGACY_TM, 6, 1) \
+ HANDLER(Y, APE, 6, 6) \
HANDLER(Y, MC_CCPA, 6, 8) \
HANDLER(Y, MC_CDPA, 6, 9) \
HANDLER(Y, PLLP_OUT_CPU, 6, 31)
diff --git a/libraries/libvapours/include/vapours/tegra/tegra_i2s.hpp b/libraries/libvapours/include/vapours/tegra/tegra_i2s.hpp
new file mode 100644
index 000000000..c967d24b3
--- /dev/null
+++ b/libraries/libvapours/include/vapours/tegra/tegra_i2s.hpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define I2S_REG(x) (0x702d1000 + x)
+
+
+#define I2S0_I2S_CG (0x088)
+#define I2S0_I2S_CTRL (0x0A0)
+#define I2S1_I2S_CG (0x188)
+#define I2S1_I2S_CTRL (0x1A0)
+#define I2S2_I2S_CG (0x288)
+#define I2S2_I2S_CTRL (0x2A0)
+#define I2S3_I2S_CG (0x388)
+#define I2S3_I2S_CTRL (0x3A0)
+#define I2S4_I2S_CG (0x488)
+#define I2S4_I2S_CTRL (0x4A0)
+
+#define I2S_REG_BITS_MASK(NAME) REG_NAMED_BITS_MASK (I2S, NAME)
+#define I2S_REG_BITS_VALUE(NAME, VALUE) REG_NAMED_BITS_VALUE (I2S, NAME, VALUE)
+#define I2S_REG_BITS_ENUM(NAME, ENUM) REG_NAMED_BITS_ENUM (I2S, NAME, ENUM)
+#define I2S_REG_BITS_ENUM_SEL(NAME, __COND__, TRUE_ENUM, FALSE_ENUM) REG_NAMED_BITS_ENUM_SEL(I2S, NAME, __COND__, TRUE_ENUM, FALSE_ENUM)
+
+#define DEFINE_I2S_REG(NAME, __OFFSET__, __WIDTH__) REG_DEFINE_NAMED_REG (I2S, NAME, __OFFSET__, __WIDTH__)
+#define DEFINE_I2S_REG_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE) REG_DEFINE_NAMED_BIT_ENUM (I2S, NAME, __OFFSET__, ZERO, ONE)
+#define DEFINE_I2S_REG_TWO_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE) REG_DEFINE_NAMED_TWO_BIT_ENUM (I2S, NAME, __OFFSET__, ZERO, ONE, TWO, THREE)
+#define DEFINE_I2S_REG_THREE_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN) REG_DEFINE_NAMED_THREE_BIT_ENUM(I2S, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN)
+#define DEFINE_I2S_REG_FOUR_BIT_ENUM(NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN) REG_DEFINE_NAMED_FOUR_BIT_ENUM (I2S, NAME, __OFFSET__, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN)
+
+
+DEFINE_I2S_REG_BIT_ENUM(I2S_CG_SLCG_ENABLE, 0, FALSE, TRUE);
+
+DEFINE_I2S_REG_BIT_ENUM(I2S_CTRL_MASTER, 10, DISABLE, ENABLE);
\ No newline at end of file
diff --git a/libraries/libvapours/include/vapours/tegra/tegra_pmc.hpp b/libraries/libvapours/include/vapours/tegra/tegra_pmc.hpp
index 17a35201b..561d44f13 100644
--- a/libraries/libvapours/include/vapours/tegra/tegra_pmc.hpp
+++ b/libraries/libvapours/include/vapours/tegra/tegra_pmc.hpp
@@ -58,6 +58,7 @@
#define APBDEV_PMC_AUTO_WAKE2_LVL_MASK (0x170)
#define APBDEV_PMC_OSC_EDPD_OVER (0x1A4)
#define APBDEV_PMC_CLK_OUT_CNTRL (0x1A8)
+#define APBDEV_PMC_RST_STATUS (0x1B4)
#define APBDEV_PMC_IO_DPD_REQ (0x1B8)
#define APBDEV_PMC_IO_DPD_STATUS (0x1BC)
#define APBDEV_PMC_IO_DPD2_REQ (0x1C0)
@@ -65,6 +66,7 @@
#define APBDEV_PMC_SEL_DPD_TIM (0x1C8)
#define APBDEV_PMC_SCRATCH45 (0x234)
#define APBDEV_PMC_SCRATCH46 (0x238)
+#define APBDEV_PMC_SCRATCH49 (0x244)
#define APBDEV_PMC_TSC_MULT (0x2B4)
#define APBDEV_PMC_STICKY_BITS (0x2C0)
#define APBDEV_PMC_WEAK_BIAS (0x2C8)