From 40e2d4bbe6375f7fcb34ee6e3125b7cdb98ef164 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 1 Sep 2021 18:10:48 -0700 Subject: [PATCH] fusee_cpp: implement cpu startup --- exosphere/program/source/boot/secmon_main.cpp | 2 + exosphere/program/source/secmon_setup.cpp | 13 +- fusee_cpp/program/source/fusee_cpu.cpp | 181 ++++++++++++++++++ fusee_cpp/program/source/fusee_cpu.hpp | 24 +++ .../program/source/fusee_setup_horizon.cpp | 16 +- fusee_cpp/program/split_bin.py | 17 +- .../libexosphere/include/exosphere/clkrst.hpp | 1 + .../include/exosphere/hw/hw_arm64_cache.hpp | 1 + .../libexosphere/source/clkrst/clkrst_api.cpp | 10 +- .../source/hw/hw_cache.arch.arm64.cpp | 11 ++ .../libexosphere/source/pmic/pmic_api.cpp | 6 +- .../include/vapours/tegra/tegra_clkrst.hpp | 19 ++ 12 files changed, 282 insertions(+), 19 deletions(-) create mode 100644 fusee_cpp/program/source/fusee_cpu.cpp create mode 100644 fusee_cpp/program/source/fusee_cpu.hpp diff --git a/exosphere/program/source/boot/secmon_main.cpp b/exosphere/program/source/boot/secmon_main.cpp index 0c2f82caf..b5c658d2f 100644 --- a/exosphere/program/source/boot/secmon_main.cpp +++ b/exosphere/program/source/boot/secmon_main.cpp @@ -80,6 +80,8 @@ namespace ams::secmon { /* Alert the bootloader that we're initialized. */ secmon_params.secmon_state = pkg1::SecureMonitorState_Initialized; + hw::FlushDataCache(std::addressof(secmon_params.secmon_state), sizeof(secmon_params.secmon_state)); + hw::DataSynchronizationBarrierInnerShareable(); } /* Wait for NX Bootloader to finish loading the BootConfig. */ diff --git a/exosphere/program/source/secmon_setup.cpp b/exosphere/program/source/secmon_setup.cpp index 875c2964e..ca23f16f7 100644 --- a/exosphere/program/source/secmon_setup.cpp +++ b/exosphere/program/source/secmon_setup.cpp @@ -475,8 +475,8 @@ namespace ams::secmon { /* Lock cluster switching, to prevent usage of the A53 cores. */ reg::Write(FLOW_CTLR + FLOW_CTLR_BPMP_CLUSTER_CONTROL, FLOW_REG_BITS_ENUM(BPMP_CLUSTER_CONTROL_ACTIVE_CLUSTER_LOCK, ENABLE), - FLOW_REG_BITS_ENUM(BPMP_CLUSTER_CONTROL_CLUSTER_SWITCH_ENABLE, DISABLE), - FLOW_REG_BITS_ENUM(BPMP_CLUSTER_CONTROL_ACTIVE_CLUSTER, FAST)); + FLOW_REG_BITS_ENUM(BPMP_CLUSTER_CONTROL_CLUSTER_SWITCH_ENABLE, DISABLE), + FLOW_REG_BITS_ENUM(BPMP_CLUSTER_CONTROL_ACTIVE_CLUSTER, FAST)); /* Enable flow controller debug qualifier for legacy FIQs. */ reg::Write(FLOW_CTLR + FLOW_CTLR_FLOW_DBG_QUAL, FLOW_REG_BITS_ENUM(FLOW_DBG_QUAL_FIQ2CCPLEX_ENABLE, ENABLE)); @@ -600,8 +600,8 @@ namespace ams::secmon { g_kernel_carveouts[0].size = 200 * 128_KB; } - /* Configure the two kernel carveouts. */ - SetupKernelCarveouts(); + /* NOTE: Here Nintendo configures the two kernel carveouts; we will do this later, to allow fusee to continue using AVP_CACHE. */ + /* SetupKernelCarveouts(); */ /* Configure slave register security. */ ConfigureSlaveSecurity(); @@ -833,7 +833,7 @@ namespace ams::secmon { #define MC_ENABLE_CLIENT_ACCESS(INDEX, WHICH) MC_REG_BITS_ENUM(CLIENT_ACCESS##INDEX##_##WHICH, ENABLE) constexpr u32 WarmbootCarveoutClientAccess0 = reg::Encode(MC_ENABLE_CLIENT_ACCESS(0, AVPCARM7R), - MC_ENABLE_CLIENT_ACCESS(0, PPCSAHBSLVR)); + MC_ENABLE_CLIENT_ACCESS(0, PPCSAHBSLVR)); constexpr u32 WarmbootCarveoutClientAccess1 = reg::Encode(MC_ENABLE_CLIENT_ACCESS(1, AVPCARM7W)); @@ -1164,6 +1164,9 @@ namespace ams::secmon { /* Setup the GPU carveout. */ SetupGpuCarveout(); + /* Configure the two kernel carveouts. */ + SetupKernelCarveouts(); + /* Disable the ARC. */ DisableArc(); diff --git a/fusee_cpp/program/source/fusee_cpu.cpp b/fusee_cpp/program/source/fusee_cpu.cpp new file mode 100644 index 000000000..0cc2f8757 --- /dev/null +++ b/fusee_cpp/program/source/fusee_cpu.cpp @@ -0,0 +1,181 @@ +/* + * 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_cpu.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 FLOW = secmon::MemoryRegionPhysicalDeviceFlowController.GetAddress(); + constexpr inline const uintptr_t EVP = secmon::MemoryRegionPhysicalDeviceExceptionVectors.GetAddress(); + constexpr inline const uintptr_t SYSTEM = secmon::MemoryRegionPhysicalDeviceSystem.GetAddress(); + + bool IsPartitionPowered(u32 mask) { + return (reg::Read(PMC + APBDEV_PMC_PWRGATE_STATUS) & mask) == mask; + } + + void PowerOnPartition(u32 status_mask, u32 toggle_mask) { + /* Check if the partition is already powered on. */ + if (IsPartitionPowered(status_mask)) { + return; + } + + /* Wait for PWRGATE_TOGGLE to be idle. */ + auto timeout = 5000; + while (true) { + if (reg::HasValue(PMC + APBDEV_PMC_PWRGATE_TOGGLE, PMC_REG_BITS_ENUM(PWRGATE_TOGGLE_START, DISABLE))) { + break; + } + + util::WaitMicroSeconds(1); + if ((--timeout) < 0) { + return; + } + } + + /* Toggle on the desired partition. */ + reg::SetField(toggle_mask, PMC_REG_BITS_ENUM(PWRGATE_TOGGLE_START, ENABLE)); + reg::Write(PMC + APBDEV_PMC_PWRGATE_TOGGLE, toggle_mask); + + /* Wait for the partition to be powered. */ + timeout = 5000; + while (true) { + if (IsPartitionPowered(status_mask)) { + break; + } + + util::WaitMicroSeconds(1); + if ((--timeout) < 0) { + return; + } + } + } + + } + + void SetupCpu(uintptr_t entrypoint) { + /* Set ACTIVE_CLUSTER to FAST. */ + reg::ReadWrite(FLOW + FLOW_CTLR_BPMP_CLUSTER_CONTROL, FLOW_REG_BITS_ENUM(BPMP_CLUSTER_CONTROL_ACTIVE_CLUSTER, FAST)); + + /* Enable VDD_CPU. */ + pmic::EnableVddCpu(fuse::GetRegulator()); + + /* Enable clock to the cpu. */ + { + /* Initialize PllX */ + if (!reg::HasValue(CLKRST + CLK_RST_CONTROLLER_PLLX_BASE, CLK_RST_REG_BITS_ENUM(PLLX_BASE_PLLX_ENABLE, ENABLE))) { + /* Disable IDDQ. */ + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_PLLX_MISC3, CLK_RST_REG_BITS_VALUE(PLLX_MISC3_PLLX_IDDQ, 0)); + + /* Wait two microseconds. */ + util::WaitMicroSeconds(2); + + /* Configure PLLX dividers. */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_PLLX_BASE, 0x80404E02); + reg::Write(CLKRST + CLK_RST_CONTROLLER_PLLX_BASE, 0x00404E02); + + /* Set PLLX_LOCK_ENABLE. */ + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_PLLX_MISC, CLK_RST_REG_BITS_ENUM(PLLX_MISC_PLLX_LOCK_ENABLE, ENABLE)); + + /* Enable PLLX. */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_PLLX_BASE, 0x40404E02); + } + + /* Wait for PLLX to be locked. */ + while (!reg::HasValue(CLKRST + CLK_RST_CONTROLLER_PLLX_BASE, CLK_RST_REG_BITS_ENUM(PLLX_BASE_PLLX_LOCK, LOCK))) { + /* ... */ + } + + /* Select MSELECT clock source as PLLP_OUT0 with divider of 4. */ + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT, CLK_RST_REG_BITS_ENUM (CLK_SOURCE_MSELECT_MSELECT_CLK_SRC, PLLP_OUT0), + CLK_RST_REG_BITS_VALUE(CLK_SOURCE_MSELECT_MSELECT_CLK_DIVISOR, 6)); + + /* Enable clock to MSELECT. */ + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_REG_BITS_ENUM(CLK_OUT_ENB_V_CLK_ENB_MSELECT, ENABLE)); + + /* Configure CCLK_BURST_POLICY. */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_CCLK_BURST_POLICY, CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_IDLE_SOURCE, PLLX_OUT0_LJ), + CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_RUN_SOURCE, PLLX_OUT0_LJ), + CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_IRQ_SOURCE, PLLX_OUT0_LJ), + CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CWAKEUP_FIQ_SOURCE, PLLX_OUT0_LJ), + CLK_RST_REG_BITS_ENUM(CCLK_BURST_POLICY_CPU_STATE, RUN)); + + /* Configure SUPER_CCLK_DIVIDER. */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER, CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_ENB, ENABLE), + CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_COP_FIQ, NO_IMPACT), + CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_CPU_FIQ, NO_IMPACT), + CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_COP_IRQ, NO_IMPACT), + CLK_RST_REG_BITS_ENUM (SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_CPU_IRQ, NO_IMPACT), + CLK_RST_REG_BITS_VALUE(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIVIDEND, 0), + CLK_RST_REG_BITS_VALUE(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIVISOR, 0)); + + + /* Enable CPUG. */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_CLK_ENB_V_SET, CLK_RST_REG_BITS_ENUM(CLK_ENB_V_SET_SET_CLK_ENB_CPUG, ENABLE)); + } + + /* Enable coresight. */ + clkrst::EnableCsiteClock(); + + /* Restore PROD setting to CPU_SOFTRST_CTRL2 by clearing CAR2PMC_CPU_ACK_WIDTH. */ + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2, CLK_RST_REG_BITS_VALUE(CPU_SOFTRST_CTRL2_CAR2PMC_CPU_ACK_WIDTH, 0)); + + /* Power on cpu rails. */ + { + PowerOnPartition(reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_STATUS_CRAIL, ON)), reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_TOGGLE_PARTID, CRAIL))); + PowerOnPartition(reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_STATUS_C0NC, ON)), reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_TOGGLE_PARTID, C0NC))); + PowerOnPartition(reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_STATUS_CE0, ON)), reg::EncodeValue(PMC_REG_BITS_ENUM(PWRGATE_TOGGLE_PARTID, CE0))); + } + + /* Do RAM Repair. */ + { + reg::Write(FLOW + FLOW_CTLR_RAM_REPAIR, FLOW_REG_BITS_ENUM(RAM_REPAIR_REQ, ENABLE)); + + while (!reg::HasValue(FLOW + FLOW_CTLR_RAM_REPAIR, FLOW_REG_BITS_ENUM(RAM_REPAIR_STS, DONE))) { + /* ... */ + } + } + + /* Configure CPU reset vector. */ + reg::Write(EVP + EVP_CPU_RESET_VECTOR, 0); + + reg::Write(SYSTEM + SB_AA64_RESET_LOW, entrypoint | 0x1); + reg::Write(SYSTEM + SB_AA64_RESET_HIGH, 0); + reg::Write(SYSTEM + SB_CSR, SB_REG_BITS_ENUM(CSR_NS_RST_VEC_WR_DIS, DISABLE)); + reg::Read(SYSTEM + SB_CSR); + } + + void StartCpu() { + /* NOTE: Here nintendo sets CPU_STRICT_TZ_APERTURE_CHECK, which we will not set. */ + + /* Clear MSELECT reset. */ + reg::ReadWrite(CLKRST + CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_REG_BITS_ENUM(RST_DEVICES_V_SWR_MSELECT_RST, DISABLE)); + + /* Take non-cpu out of reset. */ + reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR, CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_NONCPURESET, ENABLE)); + + /* Clear cpu reset. */ + + reg::Write(CLKRST + CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR, CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_CPURESET0, ENABLE), + CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_CORERESET0, ENABLE), + CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_PRESETDBG, ENABLE), + CLK_RST_REG_BITS_ENUM(RST_CPUG_CMPLX_CLR_CLR_L2RESET, ENABLE)); + } + +} diff --git a/fusee_cpp/program/source/fusee_cpu.hpp b/fusee_cpp/program/source/fusee_cpu.hpp new file mode 100644 index 000000000..629ef0c06 --- /dev/null +++ b/fusee_cpp/program/source/fusee_cpu.hpp @@ -0,0 +1,24 @@ +/* + * 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 + +namespace ams::nxboot { + + void SetupCpu(uintptr_t entrypoint); + void StartCpu(); + +} diff --git a/fusee_cpp/program/source/fusee_setup_horizon.cpp b/fusee_cpp/program/source/fusee_setup_horizon.cpp index 25dc2696d..5acb0e2b2 100644 --- a/fusee_cpp/program/source/fusee_setup_horizon.cpp +++ b/fusee_cpp/program/source/fusee_setup_horizon.cpp @@ -21,9 +21,11 @@ #include "fusee_ini.hpp" #include "fusee_emummc.hpp" #include "fusee_mmc.hpp" +#include "fusee_cpu.hpp" #include "fusee_fatal.hpp" #include "fusee_package2.hpp" #include "fusee_malloc.hpp" +#include "fusee_secmon_sync.hpp" #include "fs/fusee_fs_api.hpp" namespace ams::nxboot { @@ -736,6 +738,15 @@ namespace ams::nxboot { std::memcpy(mariko_fatal_dst, GetSecondaryArchive().mariko_fatal, sizeof(GetSecondaryArchive().mariko_fatal)); } } + + /* Setup the CPU to boot exosphere. */ + SetupCpu(reinterpret_cast(exosphere_dst)); + + /* Set our bootloader state. */ + SetBootloaderState(pkg1::BootloaderState_LoadedBootConfig); + + /* Ensure that the CPU will see consistent data. */ + hw::FlushEntireDataCache(); } } @@ -770,8 +781,11 @@ namespace ams::nxboot { /* Setup exosphere. */ ConfigureExosphere(soc_type, target_firmware, emummc_enabled); - /* TODO: Start CPU. */ + /* Start CPU. */ /* NOTE: Security Engine unusable past this point. */ + StartCpu(); + + WaitSecureMonitorState(pkg1::SecureMonitorState_Initialized); /* TODO: Build modified package2. */ WaitForReboot(); diff --git a/fusee_cpp/program/split_bin.py b/fusee_cpp/program/split_bin.py index b50247c27..123df8ed8 100644 --- a/fusee_cpp/program/split_bin.py +++ b/fusee_cpp/program/split_bin.py @@ -14,6 +14,7 @@ def read_file(fn): return f.read() def pad(data, size): + assert len(data) <= size return (data + '\x00' * size)[:size] def get_overlay(program, i): @@ -36,20 +37,20 @@ def main(argc, argv): with open('../../fusee-boogaloo%s.bin' % target, 'wb') as f: # TODO: Write header f.write('\xCC'*0x800) - # TODO: Write warmboot - f.write('\xCC'*0x1800) + # Write warmboot + f.write(pad(read_file('../../../../exosphere/warmboot%s.bin' % target), 0x1800)) # Write TSEC Keygen f.write(pad(read_file('../../tsec_keygen/tsec_keygen.bin'), 0x2000)) - # TODO: Write Mariko Fatal - f.write('\xCC'*0x1C000) + # Write Mariko Fatal + f.write(pad(read_file('../../../../exosphere/mariko_fatal%s.bin' % target), 0x1C000)) # Write Erista MTC f.write(get_overlay(data, 1)) # Write Mariko MTC f.write(get_overlay(data, 2)) - # TODO: Write exosphere - f.write('\xCC'*0xE000) - # TODO: Write mesosphere - f.write('\xCC'*0xAA000) + # Write exosphere + f.write(pad(read_file('../../../../exosphere/exosphere%s.bin' % target), 0xE000)) + # Write mesosphere + f.write(pad(read_file('../../../../mesosphere/mesosphere%s.bin' % target), 0xAA000)) # TODO: Write kips f.write('\xCC'*0x300000) # Write Splash Screen diff --git a/libraries/libexosphere/include/exosphere/clkrst.hpp b/libraries/libexosphere/include/exosphere/clkrst.hpp index 3f344b254..dea47c181 100644 --- a/libraries/libexosphere/include/exosphere/clkrst.hpp +++ b/libraries/libexosphere/include/exosphere/clkrst.hpp @@ -31,6 +31,7 @@ namespace ams::clkrst { void EnableSeClock(); void EnableCldvfsClock(); + void EnableCsiteClock(); void EnableTzramClock(); void EnableCache2Clock(); diff --git a/libraries/libexosphere/include/exosphere/hw/hw_arm64_cache.hpp b/libraries/libexosphere/include/exosphere/hw/hw_arm64_cache.hpp index 547014f4f..f489f7395 100644 --- a/libraries/libexosphere/include/exosphere/hw/hw_arm64_cache.hpp +++ b/libraries/libexosphere/include/exosphere/hw/hw_arm64_cache.hpp @@ -53,5 +53,6 @@ namespace ams::hw::arch::arm64 { } void FlushDataCache(const void *ptr, size_t size); + void InvalidateDataCache(const void *ptr, size_t size); } \ 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 30c919499..583f3d7dd 100644 --- a/libraries/libexosphere/source/clkrst/clkrst_api.cpp +++ b/libraries/libexosphere/source/clkrst/clkrst_api.cpp @@ -87,11 +87,13 @@ namespace ams::clkrst { DEFINE_CLOCK_PARAMETERS(SeClock, V, SE, PLLP_OUT0, 0); DEFINE_CLOCK_PARAMETERS(ActmonClock, V, ACTMON, CLK_M, 0); + DEFINE_CLOCK_PARAMETERS(CsiteClock, U, CSITE, PLLP_OUT0, 4); 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(TsecClock, U, TSEC, PLLP_OUT0, 2); + DEFINE_CLOCK_PARAMETERS(Sor1Clock, X, SOR1, PLLP_OUT0, 2); DEFINE_CLOCK_PARAMETERS_WITHOUT_CLKDIV(CldvfsClock, W, DVFS); + DEFINE_CLOCK_PARAMETERS_WITHOUT_CLKDIV(TzramClock, V, TZRAM); DEFINE_CLOCK_PARAMETERS_WITHOUT_CLKDIV(SorSafeClock, Y, SOR_SAFE); @@ -203,6 +205,10 @@ namespace ams::clkrst { EnableClock(CldvfsClock); } + void EnableCsiteClock() { + EnableClock(CsiteClock); + } + void EnableTzramClock() { EnableClock(TzramClock); } diff --git a/libraries/libexosphere/source/hw/hw_cache.arch.arm64.cpp b/libraries/libexosphere/source/hw/hw_cache.arch.arm64.cpp index be19c1183..1ad7a4bd6 100644 --- a/libraries/libexosphere/source/hw/hw_cache.arch.arm64.cpp +++ b/libraries/libexosphere/source/hw/hw_cache.arch.arm64.cpp @@ -26,4 +26,15 @@ namespace ams::hw::arch::arm64 { } } + + + void InvalidateDataCache(const void *ptr, size_t size) { + const uintptr_t start = reinterpret_cast(ptr); + const uintptr_t end = util::AlignUp(start + size, hw::DataCacheLineSize); + + for (uintptr_t cur = start; cur < end; cur += hw::DataCacheLineSize) { + InvalidateDataCacheLine(reinterpret_cast(cur)); + } + } + } \ No newline at end of file diff --git a/libraries/libexosphere/source/pmic/pmic_api.cpp b/libraries/libexosphere/source/pmic/pmic_api.cpp index 47b862443..fdc0809d4 100644 --- a/libraries/libexosphere/source/pmic/pmic_api.cpp +++ b/libraries/libexosphere/source/pmic/pmic_api.cpp @@ -65,13 +65,13 @@ namespace ams::pmic { u8 val; /* Clear the AE for the GPIO */ - if (i2c::Query(std::addressof(val), sizeof(val), i2c::Port_5, I2cAddressEristaMax77621, Max77620RegisterAmeGpio)) { + if (i2c::Query(std::addressof(val), sizeof(val), i2c::Port_5, I2cAddressMax77620Pmic, Max77620RegisterAmeGpio)) { val &= ~(1 << gpio); - i2c::SendByte(i2c::Port_5, I2cAddressEristaMax77621, Max77620RegisterAmeGpio, val); + i2c::SendByte(i2c::Port_5, I2cAddressMax77620Pmic, Max77620RegisterAmeGpio, val); } /* Set GPIO_DRV_PUSHPULL (bit 0), GPIO_OUTPUT_VAL_HIGH (bit 3). */ - i2c::SendByte(i2c::Port_5, I2cAddressEristaMax77621, Max77620RegisterGpio0 + gpio, MAX77620_CNFG_GPIO_DRV_PUSHPULL | MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH); + i2c::SendByte(i2c::Port_5, I2cAddressMax77620Pmic, Max77620RegisterGpio0 + gpio, MAX77620_CNFG_GPIO_DRV_PUSHPULL | MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH); } void SetEnBitErista() { diff --git a/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp b/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp index c34059c52..5911f56fe 100644 --- a/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp +++ b/libraries/libvapours/include/vapours/tegra/tegra_clkrst.hpp @@ -36,6 +36,8 @@ #define CLK_RST_CONTROLLER_RST_SOURCE (0x000) +#define CLK_RST_CONTROLLER_CCLK_BURST_POLICY (0x020) +#define CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER (0x024) #define CLK_RST_CONTROLLER_SCLK_BURST_POLICY (0x028) #define CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER (0x02C) #define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE (0x030) @@ -58,6 +60,9 @@ #define CLK_RST_CONTROLLER_CCLKLP_BURST_POLICY (0x370) #define CLK_RST_CONTROLLER_SUPER_CCLKLP_DIVIDER (0x374) #define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2 (0x388) +#define CLK_RST_CONTROLLER_PLLX_MISC1 (0x510) +#define CLK_RST_CONTROLLER_PLLX_MISC2 (0x514) +#define CLK_RST_CONTROLLER_PLLX_MISC3 (0x518) #define CLK_RST_CONTROLLER_SPARE_REG0 (0x55C) #define CLK_RST_CONTROLLER_PLLC4_BASE (0x5A4) #define CLK_RST_CONTROLLER_PLLC_MISC2 (0x5D0) @@ -125,8 +130,12 @@ 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_LOCK, 27, NOT_LOCK, LOCK); +DEFINE_CLK_RST_REG_BIT_ENUM(PLLX_BASE_PLLX_REF_DIS, 29, REF_ENABLE, REF_DISABLE); DEFINE_CLK_RST_REG_BIT_ENUM(PLLX_BASE_PLLX_ENABLE, 30, DISABLE, ENABLE); +DEFINE_CLK_RST_REG_BIT_ENUM(PLLX_MISC_PLLX_LOCK_ENABLE, 18, DISABLE, ENABLE); + DEFINE_CLK_RST_REG(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIVISOR, 0, 8); DEFINE_CLK_RST_REG(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIVIDEND, 8, 8); DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_CPU_IRQ, 24, NO_IMPACT, DISABLE); @@ -134,6 +143,8 @@ DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_COP_IRQ, 25, DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_CPU_FIQ, 26, NO_IMPACT, DISABLE); DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_CCLK_DIVIDER_SUPER_CDIV_DIS_FROM_COP_FIQ, 27, NO_IMPACT, DISABLE); +DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_CCLK_DIVIDER_SUPER_CDIV_ENB, 31, DISABLE, ENABLE); + DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_CCLKG_DIVIDER_SUPER_CDIV_ENB, 31, DISABLE, ENABLE); DEFINE_CLK_RST_REG_BIT_ENUM(SUPER_CCLKLP_DIVIDER_SUPER_CDIV_ENB, 31, DISABLE, ENABLE); @@ -145,6 +156,8 @@ DEFINE_CLK_RST_REG_FOUR_BIT_ENUM(CCLK_BURST_POLICY_CPU_STATE, 28, STDB DEFINE_CLK_RST_REG(CPU_SOFTRST_CTRL2_CAR2PMC_CPU_ACK_WIDTH, 0, 12); +DEFINE_CLK_RST_REG(PLLX_MISC3_PLLX_IDDQ, 3, 1); + DEFINE_CLK_RST_REG_TWO_BIT_ENUM(SPARE_REG0_CLK_M_DIVISOR, 2, CLK_M_DIVISOR1, CLK_M_DIVISOR2, CLK_M_DIVISOR3, CLK_M_DIVISOR4); DEFINE_CLK_RST_REG_BIT_ENUM(PLLC4_BASE_PLLC4_IDDQ, 18, OFF, ON); @@ -286,6 +299,8 @@ DEFINE_CLK_RST_REG_BIT_ENUM(PLLMB_BASE_PLLMB_ENABLE, 30, DISABLE, ENABLE); #define CLK_RST_CONTROLLER_CLK_ENB_SE_INDEX (0x1F) +#define CLK_RST_CONTROLLER_CLK_ENB_CSITE_INDEX (0x09) + #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) @@ -344,6 +359,8 @@ DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_EMC_EMC_2X_CLK_SRC, 29, PLLM_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_CSITE_CSITE_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC3_OUT0, PLLREFE_OUT1, PLLA1_OUT0, CLK_M, PLLC4_OUT0); + 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); @@ -386,7 +403,9 @@ DEFINE_CLK_RST_REG_BIT_ENUM(RST_CPUG_CMPLX_CLR_CLR_CORERESET0, 16, DISABLE, ENA DEFINE_CLK_RST_REG_BIT_ENUM(RST_CPUG_CMPLX_CLR_CLR_CORERESET1, 17, DISABLE, ENABLE); DEFINE_CLK_RST_REG_BIT_ENUM(RST_CPUG_CMPLX_CLR_CLR_CORERESET2, 18, DISABLE, ENABLE); DEFINE_CLK_RST_REG_BIT_ENUM(RST_CPUG_CMPLX_CLR_CLR_CORERESET3, 19, DISABLE, ENABLE); +DEFINE_CLK_RST_REG_BIT_ENUM(RST_CPUG_CMPLX_CLR_CLR_L2RESET, 24, DISABLE, ENABLE); DEFINE_CLK_RST_REG_BIT_ENUM(RST_CPUG_CMPLX_CLR_CLR_NONCPURESET, 29, DISABLE, ENABLE); +DEFINE_CLK_RST_REG_BIT_ENUM(RST_CPUG_CMPLX_CLR_CLR_PRESETDBG, 30, DISABLE, ENABLE); /* TODO: Actually include all devices. */ #define CLK_RST_FOREACH_DEVICE(HANDLER) \