mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-23 19:26:55 -04:00
kern: switch->nx, implement sleep manager init
This commit is contained in:
parent
20b5268e90
commit
2c496e94d5
31 changed files with 378 additions and 59 deletions
|
@ -30,6 +30,7 @@
|
|||
/* Core pre-initialization includes. */
|
||||
#include <mesosphere/kern_select_cpu.hpp>
|
||||
#include <mesosphere/kern_select_system_control.hpp>
|
||||
#include <mesosphere/kern_k_target_system.hpp>
|
||||
|
||||
/* Initialization headers. */
|
||||
#include <mesosphere/init/kern_init_elf.hpp>
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace ams::kern::arch::arm64::cpu {
|
|||
#error "Unknown CPU for cache line sizes"
|
||||
#endif
|
||||
|
||||
#if defined(ATMOSPHERE_BOARD_NINTENDO_SWITCH)
|
||||
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
|
||||
constexpr inline size_t NumCores = 4;
|
||||
#else
|
||||
#error "Unknown Board for cpu::NumCores"
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace ams::kern::arch::arm64 {
|
|||
KInterruptName_PerformanceCounter = 8,
|
||||
|
||||
/* PPIs */
|
||||
#if defined(ATMOSPHERE_BOARD_NINTENDO_SWITCH)
|
||||
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
|
||||
KInterruptName_VirtualMaintenance = 25,
|
||||
KInterruptName_HypervisorTimer = 26,
|
||||
KInterruptName_VirtualTimer = 27,
|
||||
|
@ -38,7 +38,7 @@ namespace ams::kern::arch::arm64 {
|
|||
KInterruptName_LegacyNIrq = 31,
|
||||
#endif
|
||||
|
||||
#if defined(ATMOSPHERE_BOARD_NINTENDO_SWITCH)
|
||||
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
|
||||
KInterruptName_MemoryController = 109,
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace ams::kern::arch::arm64 {
|
|||
BlockType_L3ContiguousBlock,
|
||||
BlockType_L2Block,
|
||||
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_SWITCH
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
|
||||
BlockType_L2TegraSmmuBlock,
|
||||
#endif
|
||||
|
||||
|
@ -48,14 +48,14 @@ namespace ams::kern::arch::arm64 {
|
|||
static_assert(L3BlockSize == PageSize);
|
||||
static constexpr size_t ContiguousPageSize = L3ContiguousBlockSize;
|
||||
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_SWITCH
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
|
||||
static constexpr size_t L2TegraSmmuBlockSize = 2 * L2BlockSize;
|
||||
#endif
|
||||
static constexpr size_t BlockSizes[BlockType_Count] = {
|
||||
[BlockType_L3Block] = L3BlockSize,
|
||||
[BlockType_L3ContiguousBlock] = L3ContiguousBlockSize,
|
||||
[BlockType_L2Block] = L2BlockSize,
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_SWITCH
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
|
||||
[BlockType_L2TegraSmmuBlock] = L2TegraSmmuBlockSize,
|
||||
#endif
|
||||
[BlockType_L2ContiguousBlock] = L2ContiguousBlockSize,
|
||||
|
@ -71,7 +71,7 @@ namespace ams::kern::arch::arm64 {
|
|||
case L3BlockSize: return BlockType_L3Block;
|
||||
case L3ContiguousBlockSize: return BlockType_L3ContiguousBlock;
|
||||
case L2BlockSize: return BlockType_L2Block;
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_SWITCH
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
|
||||
case L2TegraSmmuBlockSize: return BlockType_L2TegraSmmuBlock;
|
||||
#endif
|
||||
case L2ContiguousBlockSize: return BlockType_L2ContiguousBlock;
|
||||
|
|
|
@ -34,43 +34,62 @@ namespace ams::kern::arch::arm64 {
|
|||
static constexpr size_t LevelBits = 9;
|
||||
static_assert(NumLevels > 0);
|
||||
|
||||
static constexpr size_t AddressBits = (NumLevels - 1) * LevelBits + PageBits;
|
||||
static_assert(AddressBits <= BITSIZEOF(u64));
|
||||
static constexpr size_t AddressSpaceSize = (1ull << AddressBits);
|
||||
template<size_t Offset, size_t Count>
|
||||
static constexpr ALWAYS_INLINE u64 GetBits(u64 value) {
|
||||
return (value >> Offset) & ((1ul << Count) - 1);
|
||||
}
|
||||
|
||||
template<size_t Offset, size_t Count>
|
||||
constexpr ALWAYS_INLINE u64 SelectBits(u64 value) {
|
||||
return value & (((1ul << Count) - 1) << Offset);
|
||||
}
|
||||
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetL0Index(KProcessAddress addr) { return GetBits<PageBits + LevelBits * (NumLevels - 0), LevelBits>(GetInteger(addr)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetL1Index(KProcessAddress addr) { return GetBits<PageBits + LevelBits * (NumLevels - 1), LevelBits>(GetInteger(addr)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetL2Index(KProcessAddress addr) { return GetBits<PageBits + LevelBits * (NumLevels - 2), LevelBits>(GetInteger(addr)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetL3Index(KProcessAddress addr) { return GetBits<PageBits + LevelBits * (NumLevels - 3), LevelBits>(GetInteger(addr)); }
|
||||
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetL1Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 1)>(GetInteger(addr)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetL2Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 2)>(GetInteger(addr)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetL3Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 3)>(GetInteger(addr)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetContiguousL1Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 1) + 4>(GetInteger(addr)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetContiguousL2Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 2) + 4>(GetInteger(addr)); }
|
||||
static constexpr ALWAYS_INLINE uintptr_t GetContiguousL3Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 3) + 4>(GetInteger(addr)); }
|
||||
private:
|
||||
L1PageTableEntry *table;
|
||||
bool is_kernel;
|
||||
u32 num_entries;
|
||||
public:
|
||||
ALWAYS_INLINE KVirtualAddress GetTableEntry(KVirtualAddress table, size_t index) {
|
||||
ALWAYS_INLINE KVirtualAddress GetTableEntry(KVirtualAddress table, size_t index) const {
|
||||
return table + index * sizeof(PageTableEntry);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE L1PageTableEntry *GetL1Entry(KProcessAddress address) {
|
||||
return GetPointer<L1PageTableEntry>(GetTableEntry(KVirtualAddress(this->table), (GetInteger(address) >> (PageBits + LevelBits * 2)) & (this->num_entries - 1)));
|
||||
ALWAYS_INLINE L1PageTableEntry *GetL1Entry(KProcessAddress address) const {
|
||||
return GetPointer<L1PageTableEntry>(GetTableEntry(KVirtualAddress(this->table), GetL1Index(address) & (this->num_entries - 1)));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE L2PageTableEntry *GetL2EntryFromTable(KVirtualAddress table, KProcessAddress address) {
|
||||
return GetPointer<L2PageTableEntry>(GetTableEntry(table, (GetInteger(address) >> (PageBits + LevelBits * 1)) & ((1ul << LevelBits) - 1)));
|
||||
ALWAYS_INLINE L2PageTableEntry *GetL2EntryFromTable(KVirtualAddress table, KProcessAddress address) const {
|
||||
return GetPointer<L2PageTableEntry>(GetTableEntry(table, GetL2Index(address)));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE L2PageTableEntry *GetL2Entry(const L1PageTableEntry *entry, KProcessAddress address) {
|
||||
ALWAYS_INLINE L2PageTableEntry *GetL2Entry(const L1PageTableEntry *entry, KProcessAddress address) const {
|
||||
return GetL2EntryFromTable(KMemoryLayout::GetLinearVirtualAddress(entry->GetTable()), address);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE L3PageTableEntry *GetL3EntryFromTable(KVirtualAddress table, KProcessAddress address) {
|
||||
return GetPointer<L3PageTableEntry>(GetTableEntry(table, (GetInteger(address) >> (PageBits + LevelBits * 0)) & ((1ul << LevelBits) - 1)));
|
||||
ALWAYS_INLINE L3PageTableEntry *GetL3EntryFromTable(KVirtualAddress table, KProcessAddress address) const {
|
||||
return GetPointer<L3PageTableEntry>(GetTableEntry(table, GetL3Index(address)));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE L3PageTableEntry *GetL3Entry(const L2PageTableEntry *entry, KProcessAddress address) {
|
||||
ALWAYS_INLINE L3PageTableEntry *GetL3Entry(const L2PageTableEntry *entry, KProcessAddress address) const {
|
||||
return GetL3EntryFromTable(KMemoryLayout::GetLinearVirtualAddress(entry->GetTable()), address);
|
||||
}
|
||||
public:
|
||||
constexpr KPageTableImpl() : table(), is_kernel(), num_entries() { /* ... */ }
|
||||
|
||||
NOINLINE void InitializeForKernel(void *tb, KVirtualAddress start, KVirtualAddress end);
|
||||
|
||||
L1PageTableEntry *Finalize();
|
||||
|
||||
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,10 @@ namespace ams::kern::arch::arm64 {
|
|||
Result MapPages(KProcessAddress *out_addr, size_t num_pages, size_t alignment, KPhysicalAddress phys_addr, KProcessAddress region_start, size_t region_num_pages, KMemoryState state, KMemoryPermission perm) {
|
||||
return this->page_table.MapPages(out_addr, num_pages, alignment, phys_addr, region_start, region_num_pages, state, perm);
|
||||
}
|
||||
|
||||
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const {
|
||||
return this->page_table.GetPhysicalAddress(out, address);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#pragma once
|
||||
#include <mesosphere/kern_common.hpp>
|
||||
|
||||
namespace ams::kern {
|
||||
namespace ams::kern::board::nintendo::nx {
|
||||
|
||||
class KSystemControl {
|
||||
public:
|
||||
|
@ -37,14 +37,16 @@ namespace ams::kern {
|
|||
};
|
||||
public:
|
||||
/* Initialization. */
|
||||
static NOINLINE void Initialize();
|
||||
static NOINLINE void InitializePhase1();
|
||||
static NOINLINE void InitializePhase2();
|
||||
static NOINLINE u32 GetInitialProcessBinaryPool();
|
||||
|
||||
/* Randomness. */
|
||||
static void GenerateRandomBytes(void *dst, size_t size);
|
||||
static u64 GenerateRandomRange(u64 min, u64 max);
|
||||
|
||||
/* Panic. */
|
||||
/* Power management. */
|
||||
static void SleepSystem();
|
||||
static NORETURN void StopSystem();
|
||||
};
|
||||
|
|
@ -32,7 +32,7 @@ namespace ams::kern {
|
|||
|
||||
#ifndef MESOSPHERE_DEBUG_LOG_SELECTED
|
||||
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_SWITCH
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
|
||||
#define MESOSPHERE_DEBUG_LOG_USE_UART_C
|
||||
#else
|
||||
#error "Unknown board for Default Debug Log Source"
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_SWITCH
|
||||
#ifdef ATMOSPHERE_ARCH_ARM64
|
||||
#include <mesosphere/arch/arm64/kern_k_exception_context.hpp>
|
||||
|
||||
namespace ams::kern {
|
||||
using ams::kern::arch::arm64::KExceptionContext;
|
||||
}
|
||||
#else
|
||||
#error "Unknown board for KExceptionContext"
|
||||
#error "Unknown architecture for KExceptionContext"
|
||||
#endif
|
||||
|
|
|
@ -196,6 +196,10 @@ namespace ams::kern {
|
|||
|
||||
NOINLINE Result MapPages(KProcessAddress *out_addr, size_t num_pages, size_t alignment, KPhysicalAddress phys_addr, bool is_pa_valid, KProcessAddress region_start, size_t region_num_pages, KMemoryState state, KMemoryPermission perm);
|
||||
public:
|
||||
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const {
|
||||
return this->GetImpl().GetPhysicalAddress(out, virt_addr);
|
||||
}
|
||||
|
||||
Result MapPages(KProcessAddress *out_addr, size_t num_pages, size_t alignment, KPhysicalAddress phys_addr, KProcessAddress region_start, size_t region_num_pages, KMemoryState state, KMemoryPermission perm) {
|
||||
return this->MapPages(out_addr, num_pages, alignment, phys_addr, true, region_start, region_num_pages, state, perm);
|
||||
}
|
||||
|
|
|
@ -15,11 +15,10 @@
|
|||
*/
|
||||
#pragma once
|
||||
#include <mesosphere/kern_common.hpp>
|
||||
#include <mesosphere/kern_select_system_control.hpp>
|
||||
|
||||
namespace ams::kern {
|
||||
|
||||
class KSystemControl;
|
||||
|
||||
class KTargetSystem {
|
||||
private:
|
||||
friend class KSystemControl;
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_SWITCH
|
||||
#ifdef ATMOSPHERE_ARCH_ARM64
|
||||
#include <mesosphere/arch/arm64/kern_k_thread_context.hpp>
|
||||
|
||||
namespace ams::kern {
|
||||
using ams::kern::arch::arm64::KThreadContext;
|
||||
}
|
||||
#else
|
||||
#error "Unknown board for KThreadContext"
|
||||
#error "Unknown architecture for KThreadContext"
|
||||
#endif
|
||||
|
|
|
@ -15,10 +15,14 @@
|
|||
*/
|
||||
#pragma once
|
||||
#include <mesosphere/kern_common.hpp>
|
||||
#include <mesosphere/kern_k_target_system.hpp>
|
||||
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_SWITCH
|
||||
#include <mesosphere/board/nintendo/switch/kern_k_system_control.hpp>
|
||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
|
||||
#include <mesosphere/board/nintendo/nx/kern_k_system_control.hpp>
|
||||
|
||||
namespace ams::kern {
|
||||
using ams::kern::board::nintendo::nx::KSystemControl;
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Unknown board for KSystemControl"
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue