mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-20 13:43:35 +00:00
kern: skeleton legacy lps driver
This commit is contained in:
parent
cc6b8ea4d1
commit
4dc728824f
6 changed files with 144 additions and 13 deletions
|
@ -15,13 +15,32 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* All architectures must define NumBoardDeviceRegions. */
|
/* All architectures must define NumBoardDeviceRegions. */
|
||||||
constexpr inline const auto NumBoardDeviceRegions = 5;
|
constexpr inline const auto NumBoardDeviceRegions = 6;
|
||||||
/* UNUSED: .Derive(NumBoardDeviceRegions, 0); */
|
/* UNUSED: .Derive(NumBoardDeviceRegions, 0); */
|
||||||
constexpr inline const auto KMemoryRegionType_MemoryController = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 1).SetAttribute(KMemoryRegionAttr_NoUserMap);
|
constexpr inline const auto KMemoryRegionType_MemoryController = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 1).SetAttribute(KMemoryRegionAttr_NoUserMap);
|
||||||
constexpr inline const auto KMemoryRegionType_MemoryController1 = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 2).SetAttribute(KMemoryRegionAttr_NoUserMap);
|
constexpr inline const auto KMemoryRegionType_MemoryController1 = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 2).SetAttribute(KMemoryRegionAttr_NoUserMap);
|
||||||
constexpr inline const auto KMemoryRegionType_MemoryController0 = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 3).SetAttribute(KMemoryRegionAttr_NoUserMap);
|
constexpr inline const auto KMemoryRegionType_MemoryController0 = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 3).SetAttribute(KMemoryRegionAttr_NoUserMap);
|
||||||
constexpr inline const auto KMemoryRegionType_PowerManagementController = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 4).DeriveTransition();
|
constexpr inline const auto KMemoryRegionType_PowerManagementController = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 4).DeriveTransition();
|
||||||
|
constexpr inline const auto KMemoryRegionType_LegacyLpsDevices = KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 5);
|
||||||
static_assert(KMemoryRegionType_MemoryController .GetValue() == (0x55 | KMemoryRegionAttr_NoUserMap));
|
static_assert(KMemoryRegionType_MemoryController .GetValue() == (0x55 | KMemoryRegionAttr_NoUserMap));
|
||||||
static_assert(KMemoryRegionType_MemoryController1 .GetValue() == (0x65 | KMemoryRegionAttr_NoUserMap));
|
static_assert(KMemoryRegionType_MemoryController1 .GetValue() == (0x65 | KMemoryRegionAttr_NoUserMap));
|
||||||
static_assert(KMemoryRegionType_MemoryController0 .GetValue() == (0x95 | KMemoryRegionAttr_NoUserMap));
|
static_assert(KMemoryRegionType_MemoryController0 .GetValue() == (0x95 | KMemoryRegionAttr_NoUserMap));
|
||||||
static_assert(KMemoryRegionType_PowerManagementController.GetValue() == (0x1A5));
|
static_assert(KMemoryRegionType_PowerManagementController.GetValue() == (0x1A5));
|
||||||
|
|
||||||
|
static_assert(KMemoryRegionType_LegacyLpsDevices.GetValue() == 0xC5);
|
||||||
|
|
||||||
|
constexpr inline const auto NumLegacyLpsDevices = 7;
|
||||||
|
constexpr inline const auto KMemoryRegionType_LegacyLpsExceptionVectors = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 0);
|
||||||
|
constexpr inline const auto KMemoryRegionType_LegacyLpsIram = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 1);
|
||||||
|
constexpr inline const auto KMemoryRegionType_LegacyLpsFlowController = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 2);
|
||||||
|
constexpr inline const auto KMemoryRegionType_LegacyLpsPrimaryICtlr = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 3);
|
||||||
|
constexpr inline const auto KMemoryRegionType_LegacyLpsSemaphore = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 4);
|
||||||
|
constexpr inline const auto KMemoryRegionType_LegacyLpsAtomics = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 5);
|
||||||
|
constexpr inline const auto KMemoryRegionType_LegacyLpsClkRst = KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 6);
|
||||||
|
static_assert(KMemoryRegionType_LegacyLpsExceptionVectors.GetValue() == 0x3C5);
|
||||||
|
static_assert(KMemoryRegionType_LegacyLpsIram .GetValue() == 0x5C5);
|
||||||
|
static_assert(KMemoryRegionType_LegacyLpsFlowController .GetValue() == 0x6C5);
|
||||||
|
static_assert(KMemoryRegionType_LegacyLpsPrimaryICtlr .GetValue() == 0x9C5);
|
||||||
|
static_assert(KMemoryRegionType_LegacyLpsSemaphore .GetValue() == 0xAC5);
|
||||||
|
static_assert(KMemoryRegionType_LegacyLpsAtomics .GetValue() == 0xCC5);
|
||||||
|
static_assert(KMemoryRegionType_LegacyLpsClkRst .GetValue() == 0x11C5);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <mesosphere.hpp>
|
#include <mesosphere.hpp>
|
||||||
#include "kern_k_sleep_manager.hpp"
|
#include "kern_k_sleep_manager.hpp"
|
||||||
#include "kern_secure_monitor.hpp"
|
#include "kern_secure_monitor.hpp"
|
||||||
|
#include "kern_lps_driver.hpp"
|
||||||
|
|
||||||
namespace ams::kern::board::nintendo::nx {
|
namespace ams::kern::board::nintendo::nx {
|
||||||
|
|
||||||
|
@ -472,6 +473,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
}
|
}
|
||||||
|
|
||||||
void KSleepManager::ProcessRequests(uintptr_t buffer) {
|
void KSleepManager::ProcessRequests(uintptr_t buffer) {
|
||||||
|
const auto target_fw = GetTargetFirmware();
|
||||||
const s32 core_id = GetCurrentCoreId();
|
const s32 core_id = GetCurrentCoreId();
|
||||||
KPhysicalAddress resume_entry_phys_addr = Null<KPhysicalAddress>;
|
KPhysicalAddress resume_entry_phys_addr = Null<KPhysicalAddress>;
|
||||||
|
|
||||||
|
@ -484,6 +486,8 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
const KPhysicalAddress sleep_buffer_phys_addr = g_sleep_buffer_phys_addrs[core_id];
|
const KPhysicalAddress sleep_buffer_phys_addr = g_sleep_buffer_phys_addrs[core_id];
|
||||||
const u64 target_core_mask = (1ul << core_id);
|
const u64 target_core_mask = (1ul << core_id);
|
||||||
|
|
||||||
|
const bool use_legacy_lps_driver = target_fw < TargetFirmware_2_0_0;
|
||||||
|
|
||||||
/* Loop, processing sleep when requested. */
|
/* Loop, processing sleep when requested. */
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Wait for a request. */
|
/* Wait for a request. */
|
||||||
|
@ -494,6 +498,11 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If on core 0, ensure the legacy lps driver is initialized. */
|
||||||
|
if (use_legacy_lps_driver && core_id == 0) {
|
||||||
|
lps::Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform Sleep/Wake sequence. */
|
/* Perform Sleep/Wake sequence. */
|
||||||
{
|
{
|
||||||
/* Disable interrupts. */
|
/* Disable interrupts. */
|
||||||
|
@ -550,6 +559,11 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
/* Wait for all other cores to be powered off. */
|
/* Wait for all other cores to be powered off. */
|
||||||
WaitOtherCpuPowerOff();
|
WaitOtherCpuPowerOff();
|
||||||
|
|
||||||
|
/* If we're using the legacy lps driver, enable suspend. */
|
||||||
|
if (use_legacy_lps_driver) {
|
||||||
|
MESOSPHERE_R_ABORT_UNLESS(lps::EnableSuspend());
|
||||||
|
}
|
||||||
|
|
||||||
/* Log that we're about to enter SC7. */
|
/* Log that we're about to enter SC7. */
|
||||||
MESOSPHERE_LOG("Entering SC7\n");
|
MESOSPHERE_LOG("Entering SC7\n");
|
||||||
|
|
||||||
|
@ -557,7 +571,12 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
KDebugLog::Save();
|
KDebugLog::Save();
|
||||||
|
|
||||||
/* Invoke the sleep handler. */
|
/* Invoke the sleep handler. */
|
||||||
|
if (!use_legacy_lps_driver) {
|
||||||
|
/* When not using the legacy driver, invoke directly. */
|
||||||
CpuSleepHandler(GetInteger(sleep_buffer_phys_addr), GetInteger(resume_entry_phys_addr));
|
CpuSleepHandler(GetInteger(sleep_buffer_phys_addr), GetInteger(resume_entry_phys_addr));
|
||||||
|
} else {
|
||||||
|
lps::InvokeCpuSleepHandler(GetInteger(sleep_buffer_phys_addr), GetInteger(resume_entry_phys_addr));
|
||||||
|
}
|
||||||
|
|
||||||
/* Restore the debug log state. */
|
/* Restore the debug log state. */
|
||||||
KDebugLog::Restore();
|
KDebugLog::Restore();
|
||||||
|
|
|
@ -20,7 +20,6 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
|
|
||||||
class KSleepManager {
|
class KSleepManager {
|
||||||
private:
|
private:
|
||||||
static void CpuSleepHandler(uintptr_t arg, uintptr_t entry);
|
|
||||||
static void ResumeEntry(uintptr_t arg);
|
static void ResumeEntry(uintptr_t arg);
|
||||||
|
|
||||||
static void InvalidateDataCacheForResumeEntry(uintptr_t level);
|
static void InvalidateDataCacheForResumeEntry(uintptr_t level);
|
||||||
|
@ -29,6 +28,8 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
public:
|
public:
|
||||||
static void Initialize();
|
static void Initialize();
|
||||||
static void SleepSystem();
|
static void SleepSystem();
|
||||||
|
public:
|
||||||
|
static void CpuSleepHandler(uintptr_t arg, uintptr_t entry);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
#include "kern_lps_driver.hpp"
|
||||||
|
#include "kern_k_sleep_manager.hpp"
|
||||||
|
|
||||||
|
namespace ams::kern::board::nintendo::nx::lps {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constinit bool g_lps_init_done = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Initialize() {
|
||||||
|
if (!g_lps_init_done) {
|
||||||
|
MESOSPHERE_UNIMPLEMENTED();
|
||||||
|
|
||||||
|
g_lps_init_done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result EnableSuspend() {
|
||||||
|
MESOSPHERE_UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InvokeCpuSleepHandler(uintptr_t arg, uintptr_t entry) {
|
||||||
|
MESOSPHERE_ABORT_UNLESS(g_lps_init_done);
|
||||||
|
MESOSPHERE_ABORT_UNLESS(GetCurrentCoreId() == 0);
|
||||||
|
|
||||||
|
MESOSPHERE_UNIMPLEMENTED();
|
||||||
|
|
||||||
|
/* Invoke the sleep hander. */
|
||||||
|
KSleepManager::CpuSleepHandler(arg, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern::board::nintendo::nx {
|
||||||
|
|
||||||
|
namespace lps {
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
Result EnableSuspend();
|
||||||
|
void InvokeCpuSleepHandler(uintptr_t arg, uintptr_t entry);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -70,9 +70,22 @@ namespace ams::kern {
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50041000, 0x1000, KMemoryRegionType_InterruptDistributor | KMemoryRegionAttr_ShouldKernelMap));
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50041000, 0x1000, KMemoryRegionType_InterruptDistributor | KMemoryRegionAttr_ShouldKernelMap));
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50042000, 0x1000, KMemoryRegionType_InterruptCpuInterface | KMemoryRegionAttr_ShouldKernelMap));
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50042000, 0x1000, KMemoryRegionType_InterruptCpuInterface | KMemoryRegionAttr_ShouldKernelMap));
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50043000, 0x1D000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50043000, 0x1D000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
|
||||||
|
|
||||||
|
/* Map IRAM unconditionally, to support debug-logging-to-iram build config. */
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x40000000, 0x40000, KMemoryRegionType_LegacyLpsIram | KMemoryRegionAttr_ShouldKernelMap));
|
||||||
|
|
||||||
if (GetTargetFirmware() >= TargetFirmware_2_0_0) {
|
if (GetTargetFirmware() >= TargetFirmware_2_0_0) {
|
||||||
|
/* Prevent mapping the bpmp exception vectors or the ipatch region. */
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x6000F000, 0x1000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x6000F000, 0x1000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x6001DC00, 0x400, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x6001DC00, 0x400, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
|
||||||
|
} else {
|
||||||
|
/* Map devices required for legacy lps driver. */
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x6000F000, 0x1000, KMemoryRegionType_LegacyLpsExceptionVectors | KMemoryRegionAttr_ShouldKernelMap));
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60007000, 0x1000, KMemoryRegionType_LegacyLpsFlowController | KMemoryRegionAttr_ShouldKernelMap));
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60004000, 0x1000, KMemoryRegionType_LegacyLpsPrimaryICtlr | KMemoryRegionAttr_ShouldKernelMap));
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60001000, 0x1000, KMemoryRegionType_LegacyLpsSemaphore | KMemoryRegionAttr_ShouldKernelMap));
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70016000, 0x1000, KMemoryRegionType_LegacyLpsAtomics | KMemoryRegionAttr_ShouldKernelMap));
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x60006000, 0x1000, KMemoryRegionType_LegacyLpsClkRst | KMemoryRegionAttr_ShouldKernelMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue