kern: finish 1.x lps driver

This commit is contained in:
Michael Scire 2020-08-29 18:50:09 -07:00 committed by SciresM
parent ab2568ddfb
commit 34dc062c11
7 changed files with 96 additions and 30 deletions

View file

@ -17,31 +17,31 @@
#include <mesosphere.hpp>
/* Message Flags */
#define BPMP_MSG_DO_ACK (1 << 0)
#define BPMP_MSG_DO_ACK (1 << 0)
#define BPMP_MSG_RING_DOORBELL (1 << 1)
/* Messages */
#define MRQ_PING 0
#define MRQ_ENABLE_SUSPEND 17
#define MRQ_PING 0
#define MRQ_ENABLE_SUSPEND 17
#define MRQ_CPU_PMIC_SELECT 28
/* BPMP Power states. */
#define TEGRA_BPMP_PM_CC1 9
#define TEGRA_BPMP_PM_CC4 12
#define TEGRA_BPMP_PM_CC6 14
#define TEGRA_BPMP_PM_CC7 15
#define TEGRA_BPMP_PM_SC1 17
#define TEGRA_BPMP_PM_SC2 18
#define TEGRA_BPMP_PM_SC3 19
#define TEGRA_BPMP_PM_SC4 20
#define TEGRA_BPMP_PM_SC7 23
#define TEGRA_BPMP_PM_CC1 9
#define TEGRA_BPMP_PM_CC4 12
#define TEGRA_BPMP_PM_CC6 14
#define TEGRA_BPMP_PM_CC7 15
#define TEGRA_BPMP_PM_SC1 17
#define TEGRA_BPMP_PM_SC2 18
#define TEGRA_BPMP_PM_SC3 19
#define TEGRA_BPMP_PM_SC4 20
#define TEGRA_BPMP_PM_SC7 23
/* Channel states. */
#define CH_MASK(ch) (0x3u << ((ch) * 2))
#define SL_SIGL(ch) (0x0u << ((ch) * 2))
#define SL_QUED(ch) (0x1u << ((ch) * 2))
#define MA_FREE(ch) (0x2u << ((ch) * 2))
#define MA_ACKD(ch) (0x3u << ((ch) * 2))
#define CH_MASK(ch) (0x3u << ((ch) * 2))
#define SL_SIGL(ch) (0x0u << ((ch) * 2))
#define SL_QUED(ch) (0x1u << ((ch) * 2))
#define MA_FREE(ch) (0x2u << ((ch) * 2))
#define MA_ACKD(ch) (0x3u << ((ch) * 2))
constexpr inline int MessageSize = 0x80;
constexpr inline int MessageDataSizeMax = 0x78;

View file

@ -0,0 +1,18 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#define CLK_RST_CONTROLLER_CLK_SOURCE_CSITE 0x1D4

View file

@ -15,11 +15,11 @@
*/
#pragma once
#define ICTLR_REG_BASE(irq) ((((irq) - 32) >> 5) * 0x100)
#define ICTLR_FIR_SET(irq) (ICTLR_REG_BASE(irq) + 0x18)
#define ICTLR_FIR_CLR(irq) (ICTLR_REG_BASE(irq) + 0x1c)
#define FIR_BIT(irq) (1 << ((irq) & 0x1f))
#define ICTLR_REG_BASE(irq) ((((irq) - 32) >> 5) * 0x100)
#define ICTLR_FIR_SET(irq) (ICTLR_REG_BASE(irq) + 0x18)
#define ICTLR_FIR_CLR(irq) (ICTLR_REG_BASE(irq) + 0x1c)
#define FIR_BIT(irq) (1 << ((irq) & 0x1f))
#define INT_GIC_BASE (0)
#define INT_PRI_BASE (INT_GIC_BASE + 32)
#define INT_GIC_BASE (0)
#define INT_PRI_BASE (INT_GIC_BASE + 32)
#define INT_SHR_SEM_OUTBOX_IBF (INT_PRI_BASE + 6)

View file

@ -561,7 +561,7 @@ namespace ams::kern::board::nintendo::nx {
/* If we're using the legacy lps driver, enable suspend. */
if (use_legacy_lps_driver) {
MESOSPHERE_R_ABORT_UNLESS(lps::EnableSuspend());
MESOSPHERE_R_ABORT_UNLESS(lps::EnableSuspend(true));
}
/* Log that we're about to enter SC7. */

View file

@ -19,8 +19,10 @@
#include "kern_bpmp_api.hpp"
#include "kern_atomics_registers.hpp"
#include "kern_ictlr_registers.hpp"
#include "kern_clkrst_registers.hpp"
#include "kern_flow_registers.hpp"
#include "kern_ictlr_registers.hpp"
#include "kern_pmc_registers.hpp"
#include "kern_sema_registers.hpp"
namespace ams::kern::board::nintendo::nx::lps {
@ -43,9 +45,12 @@ namespace ams::kern::board::nintendo::nx::lps {
constinit KVirtualAddress g_sema_address = Null<KVirtualAddress>;
constinit KVirtualAddress g_atomics_address = Null<KVirtualAddress>;
constinit KVirtualAddress g_clkrst_address = Null<KVirtualAddress>;
constinit KVirtualAddress g_pmc_address = Null<KVirtualAddress>;
constinit ChannelData g_channel_area[ChannelCount] = {};
constinit u32 g_csite_clk_source = 0;
ALWAYS_INLINE u32 Read(KVirtualAddress address) {
return *GetPointer<volatile u32>(address);
}
@ -62,6 +67,7 @@ namespace ams::kern::board::nintendo::nx::lps {
g_sema_address = KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_LegacyLpsSemaphore);
g_atomics_address = KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_LegacyLpsAtomics);
g_clkrst_address = KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_LegacyLpsClkRst);
g_pmc_address = KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_PowerManagementController);
}
/* NOTE: linux "do_cc4_init" */
@ -393,15 +399,36 @@ namespace ams::kern::board::nintendo::nx::lps {
}
void InvokeCpuSleepHandler(uintptr_t arg, uintptr_t entry) {
/* Verify that we're allowed to perform suspension. */
MESOSPHERE_ABORT_UNLESS(g_lps_init_done);
MESOSPHERE_ABORT_UNLESS(GetCurrentCoreId() == 0);
MESOSPHERE_UNIMPLEMENTED();
/* Save the CSITE clock source. */
g_csite_clk_source = Read(g_clkrst_address + CLK_RST_CONTROLLER_CLK_SOURCE_CSITE);
/* Configure CSITE clock source as CLK_M. */
Write(g_clkrst_address + CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, (0x6 << 29));
/* Clear the top bit of PMC_SCRATCH4. */
Write(g_pmc_address + APBDEV_PMC_SCRATCH4, Read(g_pmc_address + APBDEV_PMC_SCRATCH4) & 0x7FFFFFFF);
/* Write 1 to PMC_SCRATCH0. This will cause the bootrom to use the warmboot code-path. */
Write(g_pmc_address + APBDEV_PMC_SCRATCH0, 1);
/* Read PMC_SCRATCH0 to be sure our write takes. */
Read(g_pmc_address + APBDEV_PMC_SCRATCH0);
/* Invoke the sleep hander. */
KSleepManager::CpuSleepHandler(arg, entry);
/* TODO: restore saved clkrst reg */
/* Disable deep power down. */
Write(g_pmc_address + APBDEV_PMC_DPD_ENABLE, 0);
/* Restore the saved CSITE clock source. */
Write(g_clkrst_address + CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, g_csite_clk_source);
/* Read the CSITE clock source to ensure our configuration takes. */
Read(g_clkrst_address + CLK_RST_CONTROLLER_CLK_SOURCE_CSITE);
/* Configure CC3/CC4. */
ConfigureCc3AndCc4();

View file

@ -0,0 +1,20 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#define APBDEV_PMC_DPD_ENABLE 0x024
#define APBDEV_PMC_SCRATCH0 0x050
#define APBDEV_PMC_SCRATCH4 0x060

View file

@ -41,10 +41,11 @@ namespace ams::kern {
ALWAYS_INLINE bool SetupPowerManagementControllerMemoryRegion() {
/* For backwards compatibility, the PMC must remain mappable on < 2.0.0. */
const auto restrict_attr = GetTargetFirmware() >= TargetFirmware_2_0_0 ? KMemoryRegionAttr_NoUserMap : static_cast<KMemoryRegionAttr>(0);
const auto rtc_restrict_attr = GetTargetFirmware() >= TargetFirmware_2_0_0 ? KMemoryRegionAttr_NoUserMap : static_cast<KMemoryRegionAttr>(0);
const auto pmc_restrict_attr = GetTargetFirmware() >= TargetFirmware_2_0_0 ? KMemoryRegionAttr_NoUserMap : KMemoryRegionAttr_ShouldKernelMap;
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E000, 0x400, KMemoryRegionType_None | restrict_attr) &&
KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E400, 0xC00, KMemoryRegionType_PowerManagementController | restrict_attr);
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E000, 0x400, KMemoryRegionType_None | rtc_restrict_attr) &&
KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E400, 0xC00, KMemoryRegionType_PowerManagementController | pmc_restrict_attr);
}
void InsertPoolPartitionRegionIntoBothTrees(size_t start, size_t size, KMemoryRegionType phys_type, KMemoryRegionType virt_type, u32 &cur_attr) {