diff --git a/fusee_cpp/program/source/fusee_secure_initialize.cpp b/fusee_cpp/program/source/fusee_secure_initialize.cpp index eadbd333e..171430f74 100644 --- a/fusee_cpp/program/source/fusee_secure_initialize.cpp +++ b/fusee_cpp/program/source/fusee_secure_initialize.cpp @@ -23,6 +23,7 @@ namespace ams::nxboot { constexpr inline const uintptr_t CLKRST = secmon::MemoryRegionPhysicalDeviceClkRst.GetAddress(); constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.GetAddress(); + constexpr inline const uintptr_t MC = secmon::MemoryRegionPhysicalDeviceMemoryController.GetAddress(); constexpr inline const uintptr_t APB = secmon::MemoryRegionPhysicalDeviceApbMisc.GetAddress(); constexpr inline const uintptr_t AHB = AHB_ARBC(0); constexpr inline const uintptr_t I2S = I2S_REG(0); @@ -164,6 +165,34 @@ namespace ams::nxboot { reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_NVENC, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_NVENC_NVENC_CLK_SRC, PLLP_OUT0)); } + void EnableArc() { + /* Enable clocks for EMC/MC, using PLLP_OUT0. */ + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_EMC, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_EMC_EMC_2X_CLK_SRC, PLLP_OUT0)); + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_H_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_H_CLK_ENB_EMC, ENABLE)); + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_H_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_H_CLK_ENB_MEM, ENABLE)); + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_X_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_X_CLK_ENB_EMC_DLL, ENABLE)); + + /* Clear reset for MEM/EMC. */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_DEV_H_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_H_EMC_RST, ENABLE), + CLK_RST_REG_BITS_ENUM(RST_DEV_H_MEM_RST, ENABLE)); + + /* Wait 5 microseconds for configuration to take. */ + util::WaitMicroSeconds(5); + + /* Enable ARC_CLK_OVR_ON. */ + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD, CLK_RST_REG_BITS_ENUM(LVL2_CLK_GATE_OVRD_ARC_CLK_OVR_ON, ON)); + + /* Enable the ARC. */ + reg::ReadWrite(MC + MC_IRAM_REG_CTRL, MC_REG_BITS_ENUM(IRAM_REG_CTRL_IRAM_CFG_WRITE_ACCESS, ENABLED)); + + /* Set IRAM BOM/TOP to open up access to all mmio. */ + reg::Write(MC + MC_IRAM_BOM, 0x40000000); + reg::Write(MC + MC_IRAM_TOM, 0x80000000); + + /* Read to ensure our configuration takes. */ + reg::Read(MC + MC_IRAM_REG_CTRL); + } + void InitializeClock() { /* Set SPARE_REG0 clock divisor 2. */ reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_SPARE_REG0, CLK_RST_REG_BITS_ENUM(SPARE_REG0_CLK_M_DIVISOR, CLK_M_DIVISOR2)); @@ -248,8 +277,6 @@ namespace ams::nxboot { pinmux::SetupHomeButton(); } - - } void SecureInitialize(bool enable_log) { @@ -269,6 +296,21 @@ namespace ams::nxboot { DoMbistWorkaround(); } + /* Initialize security engine clock. */ + clkrst::EnableSeClock(); + + /* Set fuse visibility. */ + clkrst::SetFuseVisibility(true); + + /* Disable fuse programming. */ + fuse::Lockout(); + + /* Initialize the security engine. */ + se::Initialize(); + + /* Enable the arc. */ + EnableArc(); + /* Setup initial clocks. */ InitializeClock(); diff --git a/libraries/libexosphere/include/exosphere/clkrst.hpp b/libraries/libexosphere/include/exosphere/clkrst.hpp index 3299197a0..95303bcb0 100644 --- a/libraries/libexosphere/include/exosphere/clkrst.hpp +++ b/libraries/libexosphere/include/exosphere/clkrst.hpp @@ -29,6 +29,7 @@ namespace ams::clkrst { void EnableI2c1Clock(); void EnableI2c5Clock(); + void EnableSeClock(); void EnableCldvfsClock(); void EnableTzramClock(); diff --git a/libraries/libexosphere/source/clkrst/clkrst_api.cpp b/libraries/libexosphere/source/clkrst/clkrst_api.cpp index 3227a3210..fe2aa455f 100644 --- a/libraries/libexosphere/source/clkrst/clkrst_api.cpp +++ b/libraries/libexosphere/source/clkrst/clkrst_api.cpp @@ -82,6 +82,7 @@ namespace ams::clkrst { DEFINE_CLOCK_PARAMETERS(UartCClock, H, UARTC, PLLP_OUT0, 0); DEFINE_CLOCK_PARAMETERS(I2c1Clock, L, I2C1, CLK_M, 0); DEFINE_CLOCK_PARAMETERS(I2c5Clock, H, I2C5, CLK_M, 0); + DEFINE_CLOCK_PARAMETERS(SeClock, V, SE, PLLP_OUT0, 0); DEFINE_CLOCK_PARAMETERS(ActmonClock, V, ACTMON, CLK_M, 0); DEFINE_CLOCK_PARAMETERS(Host1xClock, L, HOST1X, PLLP_OUT0, 3); @@ -129,6 +130,13 @@ namespace ams::clkrst { EnableClock(I2c5Clock); } + void EnableSeClock() { + EnableClock(SeClock); + if (fuse::GetSocType() == fuse::SocType_Mariko) { + reg::ReadWrite(g_register_address + CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_RST_REG_BITS_ENUM(CLK_SOURCE_SE_CLK_LOCK, ENABLE)); + } + } + void EnableCldvfsClock() { EnableClock(CldvfsClock); } diff --git a/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp b/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp index 738893bcc..6d7fc51e6 100644 --- a/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp +++ b/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp @@ -156,6 +156,7 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLMB_BASE_PLLMB_ENABLE, 30, DISABLE, ENABLE); #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_EMC (0x19C) #define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC (0x1A0) #define CLK_RST_CONTROLLER_CLK_SOURCE_I2C3 (0x1B8) #define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 (0x1BC) @@ -165,6 +166,7 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLMB_BASE_PLLMB_ENABLE, 30, DISABLE, ENABLE); #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_SE (0x42C) #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) @@ -245,6 +247,8 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLMB_BASE_PLLMB_ENABLE, 30, DISABLE, ENABLE); #define CLK_RST_CONTROLLER_CLK_ENB_TZRAM_INDEX (0x1E) +#define CLK_RST_CONTROLLER_CLK_ENB_SE_INDEX (0x1F) + #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) @@ -298,10 +302,15 @@ DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_VI_VI_CLK_SRC, 29, RESERVED0, PLLC2 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_EMC_EMC_2X_CLK_SRC, 29, PLLM_OUT0, PLLC_OUT0, PLLP_OUT0, CLK_M, PLLM_UD, PLLMB_UD, PLLMB_OUT0, PLLP_UD); + 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_THREE_BIT_ENUM(CLK_SOURCE_SE_SE_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC3_OUT0, RSVD4, PLLA1_OUT0, CLK_M, PLLC4_OUT0); +DEFINE_CLK_RST_REG_BIT_ENUM(CLK_SOURCE_SE_CLK_LOCK, 8, DISABLE, ENABLE); + 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);