diff --git a/fusee_cpp/program/source/fusee_secure_initialize.cpp b/fusee_cpp/program/source/fusee_secure_initialize.cpp index e4bbbdf03..eadbd333e 100644 --- a/fusee_cpp/program/source/fusee_secure_initialize.cpp +++ b/fusee_cpp/program/source/fusee_secure_initialize.cpp @@ -21,13 +21,15 @@ 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 APB = secmon::MemoryRegionPhysicalDeviceApbMisc.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; + constexpr inline const uintptr_t CLKRST = secmon::MemoryRegionPhysicalDeviceClkRst.GetAddress(); + constexpr inline const uintptr_t PMC = secmon::MemoryRegionPhysicalDevicePmc.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); + constexpr inline const uintptr_t DISP1 = secmon::MemoryRegionPhysicalDeviceDisp1.GetAddress(); + constexpr inline const uintptr_t VIC = secmon::MemoryRegionPhysicalDeviceDsi.GetAddress() + 0x40000; + constexpr inline const uintptr_t TIMER = secmon::MemoryRegionPhysicalDeviceTimer.GetAddress(); + constexpr inline const uintptr_t SYSCTR0 = secmon::MemoryRegionPhysicalDeviceSysCtr0.GetAddress(); void DoRcmWorkaround(const void *sbk, size_t sbk_size) { /* Set the SBK inside the security engine. */ @@ -163,7 +165,72 @@ namespace ams::nxboot { } void InitializeClock() { - /* TODO */ + /* 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)); + + /* Set system counter frequency. */ + reg::Write(SYSCTR0 + SYSCTR0_CNTFID0, 19'200'000); + + /* Restore TIMERUS config to 19.2 MHz. */ + reg::Write(TIMER + TIMERUS_USEC_CFG, TIMER_REG_BITS_VALUE(USEC_CFG_USEC_DIVIDEND, 5 - 1), + TIMER_REG_BITS_VALUE(USEC_CFG_USEC_DIVISOR, 96 - 1)); + + /* Enable the crystal oscillator, and copy the drive strength from pmc. */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_OSC_CTRL, CLK_RST_REG_BITS_ENUM (OSC_CTRL_OSC_FREQ, OSC38P4), + CLK_RST_REG_BITS_ENUM (OSC_CTRL_XOE, ENABLE), + CLK_RST_REG_BITS_VALUE(OSC_CTRL_XOFS, 7)); + + /* Set the crystal oscillator value in PMC. */ + reg::ReadWrite(PMC + APBDEV_PMC_OSC_EDPD_OVER, PMC_REG_BITS_VALUE(OSC_EDPD_OVER_XOFS, 7)); + + /* Configure the crystal oscillator to use PMC value on warmboot. */ + reg::ReadWrite(PMC + APBDEV_PMC_OSC_EDPD_OVER, PMC_REG_BITS_ENUM(OSC_EDPD_OVER_OSC_CTRL_SELECT, PMC)); + + /* Set HOLD_CKE_LOW_EN. */ + reg::ReadWrite(PMC + APBDEV_PMC_CNTRL2, PMC_REG_BITS_ENUM(CNTRL2_HOLD_CKE_LOW_EN, ENABLE)); + + /* Set bit 25 in APBDEV_PMC_SCRATCH188. */ + /* NOTE: This seems like a bug? It doesn't ever get used. */ + reg::ReadWrite(PMC + APBDEV_PMC_SCRATCH188, REG_BITS_VALUE(25, 1, 1)); + + /* Set CLK_SYSTEM_RATE. */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_SYSTEM_RATE, CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_HCLK_DIS, 0), + CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_AHB_RATE, 1), + CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_PCLK_DIS, 0), + CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_APB_RATE, 0)); + + /* Configure PLLMB_BASE. */ + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_PLLMB_BASE, CLK_RST_REG_BITS_ENUM(PLLMB_BASE_PLLMB_ENABLE, DISABLE)); + + /* Configure TSC_MULT. */ + constexpr u32 TscMultValue = 19'200'000 * 16 / 32768; + reg::ReadWrite(PMC + APBDEV_PMC_TSC_MULT, PMC_REG_BITS_VALUE(TSC_MULT_MULT_VAL, TscMultValue)); + + /* Configure SCLK_BURST_POLICY */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_SCLK_BURST_POLICY, CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SYS_STATE, RUN), + CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_COP_AUTO_SWAKEUP_FROM_FIQ, NOP), + CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_CPU_AUTO_SWAKEUP_FROM_FIQ, NOP), + CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_COP_AUTO_SWAKEUP_FROM_IRQ, NOP), + CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_CPU_AUTO_SWAKEUP_FROM_IRQ, NOP), + CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_FIQ_SOURCE, PLLP_OUT2), + CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_IRQ_SOURCE, PLLP_OUT2), + CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE, PLLP_OUT2), + CLK_RST_REG_BITS_ENUM(SCLK_BURST_POLICY_SWAKEUP_IDLE_SOURCE, PLLP_OUT2)); + + /* Configure SUPER_SCLK_DIVIDER */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER, CLK_RST_REG_BITS_ENUM (SUPER_SCLK_DIVIDER_SUPER_SDIV_ENB, ENABLE), + CLK_RST_REG_BITS_ENUM (SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_COP_FIQ, NOP), + CLK_RST_REG_BITS_ENUM (SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_CPU_FIQ, NOP), + CLK_RST_REG_BITS_ENUM (SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_COP_IRQ, NOP), + CLK_RST_REG_BITS_ENUM (SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_CPU_IRQ, NOP), + CLK_RST_REG_BITS_VALUE(SUPER_SCLK_DIVIDER_SUPER_SDIV_DIVIDEND, 0), + CLK_RST_REG_BITS_VALUE(SUPER_SCLK_DIVIDER_SUPER_SDIV_DIVISOR, 0)); + + /* Set CLK_SYSTEM_RATE */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_SYSTEM_RATE, CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_HCLK_DIS, 0), + CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_AHB_RATE, 0), + CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_PCLK_DIS, 0), + CLK_RST_REG_BITS_VALUE(CLK_SYSTEM_RATE_APB_RATE, 2)); } void InitializePinmux(fuse::HardwareType hw_type) { diff --git a/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp b/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp index 7f5fc29d2..738893bcc 100644 --- a/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp +++ b/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp @@ -37,6 +37,8 @@ #define CLK_RST_CONTROLLER_RST_SOURCE (0x000) #define CLK_RST_CONTROLLER_SCLK_BURST_POLICY (0x028) +#define CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER (0x02C) +#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE (0x030) #define CLK_RST_CONTROLLER_MISC_CLK_ENB (0x048) #define CLK_RST_CONTROLLER_OSC_CTRL (0x050) #define CLK_RST_CONTROLLER_PLLD_BASE (0x0D0) @@ -51,6 +53,7 @@ #define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2 (0x388) #define CLK_RST_CONTROLLER_SPARE_REG0 (0x55C) #define CLK_RST_CONTROLLER_PLLC4_BASE (0x5A4) +#define CLK_RST_CONTROLLER_PLLMB_BASE (0x5E8) #define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA (0x0F8) #define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB (0x0FC) @@ -62,11 +65,32 @@ DEFINE_CLK_RST_REG_THREE_BIT_ENUM(SCLK_BURST_POLICY_SWAKEUP_IDLE_SOURCE, 0, CLK DEFINE_CLK_RST_REG_THREE_BIT_ENUM(SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE, 4, CLKM, PLLC_OUT1, PLLC4_OUT3PLLP_OUT4, PLLP_OUT0, PLLP_OUT2, PLLC4_OUT1PLLC_OUT0, CLK_SCLKS, PLLC4_OUT2); DEFINE_CLK_RST_REG_THREE_BIT_ENUM(SCLK_BURST_POLICY_SWAKEUP_IRQ_SOURCE, 8, CLKM, PLLC_OUT1, PLLC4_OUT3PLLP_OUT4, PLLP_OUT0, PLLP_OUT2, PLLC4_OUT1PLLC_OUT0, CLK_SCLKS, PLLC4_OUT2); DEFINE_CLK_RST_REG_THREE_BIT_ENUM(SCLK_BURST_POLICY_SWAKEUP_FIQ_SOURCE, 12, CLKM, PLLC_OUT1, PLLC4_OUT3PLLP_OUT4, PLLP_OUT0, PLLP_OUT2, PLLC4_OUT1PLLC_OUT0, CLK_SCLKS, PLLC4_OUT2); +DEFINE_CLK_RST_REG_BIT_ENUM(SCLK_BURST_POLICY_CPU_AUTO_SWAKEUP_FROM_IRQ, 24, NOP, BURST); +DEFINE_CLK_RST_REG_BIT_ENUM(SCLK_BURST_POLICY_COP_AUTO_SWAKEUP_FROM_IRQ, 25, NOP, BURST); +DEFINE_CLK_RST_REG_BIT_ENUM(SCLK_BURST_POLICY_CPU_AUTO_SWAKEUP_FROM_FIQ, 26, NOP, BURST); +DEFINE_CLK_RST_REG_BIT_ENUM(SCLK_BURST_POLICY_COP_AUTO_SWAKEUP_FROM_FIQ, 27, NOP, BURST); +DEFINE_CLK_RST_REG_FOUR_BIT_ENUM(SCLK_BURST_POLICY_SYS_STATE, 28, STDBY, IDLE, RUN, RSVD3, IRQ, RSVD5, RSVD6, RSVD7, FIQ, RSVD9, RSVD10, RSVD11, RSVD12, RSVD13, RSVD14, RSVD15); + + +DEFINE_CLK_RST_REG(SUPER_SCLK_DIVIDER_SUPER_SDIV_DIVISOR, 0, 8); +DEFINE_CLK_RST_REG(SUPER_SCLK_DIVIDER_SUPER_SDIV_DIVIDEND, 8, 8); +DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_CPU_IRQ, 24, NOP, DISABLE); +DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_COP_IRQ, 25, NOP, DISABLE); +DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_CPU_FIQ, 26, NOP, DISABLE); +DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_SCLK_DIVIDER_SUPER_SDIV_DIS_FROM_COP_FIQ, 27, NOP, DISABLE); +DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_SCLK_DIVIDER_SUPER_SDIV_ENB, 31, DISABLE, ENABLE); + + +DEFINE_CLK_RST_REG(CLK_SYSTEM_RATE_APB_RATE, 0, 2); +DEFINE_CLK_RST_REG(CLK_SYSTEM_RATE_PCLK_DIS, 3, 1); +DEFINE_CLK_RST_REG(CLK_SYSTEM_RATE_AHB_RATE, 4, 2); +DEFINE_CLK_RST_REG(CLK_SYSTEM_RATE_HCLK_DIS, 7, 1); 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_FOUR_BIT_ENUM(OSC_CTRL_OSC_FREQ, 28, OSC13, OSC16P8, RSVD2, RSVD3, OSC19P2, OSC38P4, RSVD6, RSVD7, OSC12, OSC48, RSVD10, RSVD11, OSC26, RSVD13, RSVD14, RSVD15); 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); @@ -99,6 +123,8 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_IDDQ, 18, OFF, ON); DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_LOCK, 27, NOT_LOCK, LOCK_FEQ_AND_PHASE); DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_ENABLE, 30, DISABLE, ENABLE); +DEFINE_CLK_RST_REG_BIT_ENUM(PLLMB_BASE_PLLMB_ENABLE, 30, DISABLE, ENABLE); + /* RST_DEVICES */ #define CLK_RST_CONTROLLER_RST_DEVICES_L (0x004) #define CLK_RST_CONTROLLER_RST_DEVICES_H (0x008) diff --git a/libraries/libvapours/include/vapours/tegra/tegra_pmc.hpp b/libraries/libvapours/include/vapours/tegra/tegra_pmc.hpp index c544fda9c..5c5198bdf 100644 --- a/libraries/libvapours/include/vapours/tegra/tegra_pmc.hpp +++ b/libraries/libvapours/include/vapours/tegra/tegra_pmc.hpp @@ -89,6 +89,7 @@ #define APBDEV_PMC_SEC_DISABLE7 (0x5BC) #define APBDEV_PMC_SEC_DISABLE8 (0x5C0) #define APBDEV_PMC_SCRATCH43 (0x22C) +#define APBDEV_PMC_SCRATCH188 (0x810) #define APBDEV_PMC_SCRATCH190 (0x818) #define APBDEV_PMC_SCRATCH200 (0x840) #define APBDEV_PMC_SEC_DISABLE3 (0x2D8) @@ -244,11 +245,15 @@ DEFINE_PMC_REG_BIT_ENUM(CLAMP_STATUS_VIC, 23, DISABLE, ENABLE); DEFINE_PMC_REG_BIT_ENUM(CLAMP_STATUS_IRAM, 24, DISABLE, ENABLE); DEFINE_PMC_REG(OSC_EDPD_OVER_XOFS, 1, 6); +DEFINE_PMC_REG_BIT_ENUM(OSC_EDPD_OVER_OSC_CTRL_SELECT, 22, CAR, PMC); + +DEFINE_PMC_REG(TSC_MULT_MULT_VAL, 0, 16); DEFINE_PMC_REG_BIT_ENUM(STICKY_BITS_HDA_LPBK_DIS, 0, DISABLE, ENABLE); DEFINE_PMC_REG_BIT_ENUM(STICKY_BITS_JTAG_STS, 6, ENABLE, DISABLE); -DEFINE_PMC_REG_BIT_ENUM(CNTRL2_WAKE_DET_EN, 9, DISABLE, ENABLE); +DEFINE_PMC_REG_BIT_ENUM(CNTRL2_WAKE_DET_EN, 9, DISABLE, ENABLE); +DEFINE_PMC_REG_BIT_ENUM(CNTRL2_HOLD_CKE_LOW_EN, 12, DISABLE, ENABLE); DEFINE_PMC_REG_BIT_ENUM(SEC_DISABLE2_WRITE21, 26, OFF, ON);