mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
kern: support 2-pool layout on 2.x-4.x instead of modern 4-pool layout
This commit is contained in:
parent
ce95af89ef
commit
e8ffbe630f
7 changed files with 204 additions and 92 deletions
|
@ -34,5 +34,6 @@ namespace ams::kern {
|
||||||
|
|
||||||
u64 GetInitialProcessIdMin();
|
u64 GetInitialProcessIdMin();
|
||||||
u64 GetInitialProcessIdMax();
|
u64 GetInitialProcessIdMax();
|
||||||
|
size_t GetInitialProcessesSecureMemorySize();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -469,7 +469,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
KSleepManager::Initialize();
|
KSleepManager::Initialize();
|
||||||
|
|
||||||
/* Reserve secure applet memory. */
|
/* Reserve secure applet memory. */
|
||||||
{
|
if (GetTargetFirmware() >= TargetFirmware_5_0_0) {
|
||||||
MESOSPHERE_ABORT_UNLESS(g_secure_applet_memory_address == Null<KVirtualAddress>);
|
MESOSPHERE_ABORT_UNLESS(g_secure_applet_memory_address == Null<KVirtualAddress>);
|
||||||
MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_PhysicalMemoryMax, SecureAppletMemorySize));
|
MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_PhysicalMemoryMax, SecureAppletMemorySize));
|
||||||
|
|
||||||
|
@ -486,7 +486,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 KSystemControl::GetInitialProcessBinaryPool() {
|
u32 KSystemControl::GetInitialProcessBinaryPool() {
|
||||||
return KMemoryManager::Pool_Application;
|
return KMemoryManager::Pool_Unsafe;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Privileged Access. */
|
/* Privileged Access. */
|
||||||
|
|
|
@ -38,6 +38,30 @@ namespace ams::kern {
|
||||||
MESOSPHERE_ABORT_UNLESS(header->num_processes <= init::GetSlabResourceCounts().num_KProcess);
|
MESOSPHERE_ABORT_UNLESS(header->num_processes <= init::GetSlabResourceCounts().num_KProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t GetProcessesSecureMemorySize(KVirtualAddress binary_address, const InitialProcessBinaryHeader &header) {
|
||||||
|
u8 *current = GetPointer<u8>(binary_address + sizeof(InitialProcessBinaryHeader));
|
||||||
|
const u8 * const end = GetPointer<u8>(binary_address + header.size - sizeof(KInitialProcessHeader));
|
||||||
|
|
||||||
|
size_t size = 0;
|
||||||
|
const size_t num_processes = header.num_processes;
|
||||||
|
for (size_t i = 0; i < num_processes; i++) {
|
||||||
|
/* Validate that we can read the current KIP. */
|
||||||
|
MESOSPHERE_ABORT_UNLESS(current <= end);
|
||||||
|
KInitialProcessReader reader;
|
||||||
|
MESOSPHERE_ABORT_UNLESS(reader.Attach(current));
|
||||||
|
|
||||||
|
/* If the process uses secure memory, account for that. */
|
||||||
|
if (reader.UsesSecureMemory()) {
|
||||||
|
size += util::AlignUp(reader.GetSize(), PageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance the reader. */
|
||||||
|
current += reader.GetBinarySize();
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
void CreateProcesses(InitialProcessInfo *infos, KVirtualAddress binary_address, const InitialProcessBinaryHeader &header) {
|
void CreateProcesses(InitialProcessInfo *infos, KVirtualAddress binary_address, const InitialProcessBinaryHeader &header) {
|
||||||
u8 *current = GetPointer<u8>(binary_address + sizeof(InitialProcessBinaryHeader));
|
u8 *current = GetPointer<u8>(binary_address + sizeof(InitialProcessBinaryHeader));
|
||||||
const u8 * const end = GetPointer<u8>(binary_address + header.size - sizeof(KInitialProcessHeader));
|
const u8 * const end = GetPointer<u8>(binary_address + header.size - sizeof(KInitialProcessHeader));
|
||||||
|
@ -108,10 +132,10 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KVirtualAddress g_initial_process_binary_address;
|
constinit KVirtualAddress g_initial_process_binary_address = Null<KVirtualAddress>;
|
||||||
InitialProcessBinaryHeader g_initial_process_binary_header;
|
constinit InitialProcessBinaryHeader g_initial_process_binary_header = {};
|
||||||
u64 g_initial_process_id_min = std::numeric_limits<u64>::max();
|
constinit u64 g_initial_process_id_min = std::numeric_limits<u64>::max();
|
||||||
u64 g_initial_process_id_max = std::numeric_limits<u64>::min();
|
constinit u64 g_initial_process_id_max = std::numeric_limits<u64>::min();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +147,12 @@ namespace ams::kern {
|
||||||
return g_initial_process_id_max;
|
return g_initial_process_id_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t GetInitialProcessesSecureMemorySize() {
|
||||||
|
LoadInitialProcessBinaryHeader(&g_initial_process_binary_header);
|
||||||
|
|
||||||
|
return GetProcessesSecureMemorySize(g_initial_process_binary_address != Null<KVirtualAddress> ? g_initial_process_binary_address : GetInitialProcessBinaryAddress(), g_initial_process_binary_header);
|
||||||
|
}
|
||||||
|
|
||||||
void CopyInitialProcessBinaryToKernelMemory() {
|
void CopyInitialProcessBinaryToKernelMemory() {
|
||||||
LoadInitialProcessBinaryHeader(&g_initial_process_binary_header);
|
LoadInitialProcessBinaryHeader(&g_initial_process_binary_header);
|
||||||
|
|
||||||
|
|
|
@ -59,31 +59,58 @@ namespace ams::kern {
|
||||||
|
|
||||||
namespace init {
|
namespace init {
|
||||||
|
|
||||||
namespace {
|
void SetupDevicePhysicalMemoryRegions() {
|
||||||
|
/* TODO: Give these constexpr defines somewhere? */
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(SetupUartPhysicalMemoryRegion());
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(SetupPowerManagementControllerMemoryRegion());
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70019000, 0x1000, KMemoryRegionType_MemoryController | KMemoryRegionAttr_NoUserMap));
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7001C000, 0x1000, KMemoryRegionType_MemoryController0 | KMemoryRegionAttr_NoUserMap));
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7001D000, 0x1000, KMemoryRegionType_MemoryController1 | KMemoryRegionAttr_NoUserMap));
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50040000, 0x1000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
|
||||||
|
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(0x50043000, 0x1D000, 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));
|
||||||
|
}
|
||||||
|
|
||||||
void SetupPoolPartitionMemoryRegionsImpl() {
|
void SetupDramPhysicalMemoryRegions() {
|
||||||
/* Start by identifying the extents of the DRAM memory region. */
|
const size_t intended_memory_size = KSystemControl::Init::GetIntendedMemorySize();
|
||||||
const auto dram_extents = KMemoryLayout::GetMainMemoryPhysicalExtents();
|
const KPhysicalAddress physical_memory_base_address = KSystemControl::Init::GetKernelPhysicalBaseAddress(DramPhysicalAddress);
|
||||||
|
|
||||||
const uintptr_t pool_end = dram_extents.GetEndAddress() - KTraceBufferSize;
|
/* Insert blocks into the tree. */
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(physical_memory_base_address), intended_memory_size, KMemoryRegionType_Dram));
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(physical_memory_base_address), ReservedEarlyDramSize, KMemoryRegionType_DramReservedEarly));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupPoolPartitionMemoryRegions() {
|
||||||
|
/* Start by identifying the extents of the DRAM memory region. */
|
||||||
|
const auto dram_extents = KMemoryLayout::GetMainMemoryPhysicalExtents();
|
||||||
|
|
||||||
|
/* Determine the end of the pool region. */
|
||||||
|
const uintptr_t pool_end = dram_extents.GetEndAddress() - KTraceBufferSize;
|
||||||
|
|
||||||
|
/* Find the start of the kernel DRAM region. */
|
||||||
|
const KMemoryRegion *kernel_dram_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DramKernelBase);
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(kernel_dram_region != nullptr);
|
||||||
|
|
||||||
|
const uintptr_t kernel_dram_start = kernel_dram_region->GetAddress();
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(kernel_dram_start, CarveoutAlignment));
|
||||||
|
|
||||||
|
/* Find the start of the pool partitions region. */
|
||||||
|
const KMemoryRegion *pool_partitions_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindByTypeAndAttribute(KMemoryRegionType_DramPoolPartition, 0);
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(pool_partitions_region != nullptr);
|
||||||
|
const uintptr_t pool_partitions_start = pool_partitions_region->GetAddress();
|
||||||
|
|
||||||
|
/* Setup the pool partition layouts. */
|
||||||
|
if (GetTargetFirmware() >= TargetFirmware_5_0_0) {
|
||||||
|
/* On 5.0.0+, setup modern 4-pool-partition layout. */
|
||||||
|
|
||||||
/* Get Application and Applet pool sizes. */
|
/* Get Application and Applet pool sizes. */
|
||||||
const size_t application_pool_size = KSystemControl::Init::GetApplicationPoolSize();
|
const size_t application_pool_size = KSystemControl::Init::GetApplicationPoolSize();
|
||||||
const size_t applet_pool_size = KSystemControl::Init::GetAppletPoolSize();
|
const size_t applet_pool_size = KSystemControl::Init::GetAppletPoolSize();
|
||||||
const size_t unsafe_system_pool_min_size = KSystemControl::Init::GetMinimumNonSecureSystemPoolSize();
|
const size_t unsafe_system_pool_min_size = KSystemControl::Init::GetMinimumNonSecureSystemPoolSize();
|
||||||
|
|
||||||
/* Find the start of the kernel DRAM region. */
|
|
||||||
const KMemoryRegion *kernel_dram_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DramKernelBase);
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(kernel_dram_region != nullptr);
|
|
||||||
|
|
||||||
const uintptr_t kernel_dram_start = kernel_dram_region->GetAddress();
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(kernel_dram_start, CarveoutAlignment));
|
|
||||||
|
|
||||||
/* Find the start of the pool partitions region. */
|
|
||||||
const KMemoryRegion *pool_partitions_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindByTypeAndAttribute(KMemoryRegionType_DramPoolPartition, 0);
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(pool_partitions_region != nullptr);
|
|
||||||
const uintptr_t pool_partitions_start = pool_partitions_region->GetAddress();
|
|
||||||
|
|
||||||
/* Decide on starting addresses for our pools. */
|
/* Decide on starting addresses for our pools. */
|
||||||
const uintptr_t application_pool_start = pool_end - application_pool_size;
|
const uintptr_t application_pool_start = pool_end - application_pool_size;
|
||||||
const uintptr_t applet_pool_start = application_pool_start - applet_pool_size;
|
const uintptr_t applet_pool_start = application_pool_start - applet_pool_size;
|
||||||
|
@ -124,45 +151,66 @@ namespace ams::kern {
|
||||||
/* Insert the system pool. */
|
/* Insert the system pool. */
|
||||||
const uintptr_t system_pool_size = pool_management_start - pool_partitions_start;
|
const uintptr_t system_pool_size = pool_management_start - pool_partitions_start;
|
||||||
InsertPoolPartitionRegionIntoBothTrees(pool_partitions_start, system_pool_size, KMemoryRegionType_DramSystemPool, KMemoryRegionType_VirtualDramSystemPool, cur_pool_attr);
|
InsertPoolPartitionRegionIntoBothTrees(pool_partitions_start, system_pool_size, KMemoryRegionType_DramSystemPool, KMemoryRegionType_VirtualDramSystemPool, cur_pool_attr);
|
||||||
}
|
} else if (GetTargetFirmware() >= TargetFirmware_2_0_0) {
|
||||||
|
|
||||||
void SetupPoolPartitionMemoryRegionsDeprecatedImpl() {
|
|
||||||
MESOSPHERE_UNIMPLEMENTED();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupDevicePhysicalMemoryRegions() {
|
|
||||||
/* TODO: Give these constexpr defines somewhere? */
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(SetupUartPhysicalMemoryRegion());
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(SetupPowerManagementControllerMemoryRegion());
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70019000, 0x1000, KMemoryRegionType_MemoryController | KMemoryRegionAttr_NoUserMap));
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7001C000, 0x1000, KMemoryRegionType_MemoryController0 | KMemoryRegionAttr_NoUserMap));
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7001D000, 0x1000, KMemoryRegionType_MemoryController1 | KMemoryRegionAttr_NoUserMap));
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x50040000, 0x1000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
|
|
||||||
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(0x50043000, 0x1D000, 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupDramPhysicalMemoryRegions() {
|
|
||||||
const size_t intended_memory_size = KSystemControl::Init::GetIntendedMemorySize();
|
|
||||||
const KPhysicalAddress physical_memory_base_address = KSystemControl::Init::GetKernelPhysicalBaseAddress(DramPhysicalAddress);
|
|
||||||
|
|
||||||
/* Insert blocks into the tree. */
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(physical_memory_base_address), intended_memory_size, KMemoryRegionType_Dram));
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(physical_memory_base_address), ReservedEarlyDramSize, KMemoryRegionType_DramReservedEarly));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupPoolPartitionMemoryRegions() {
|
|
||||||
if (GetTargetFirmware() >= TargetFirmware_5_0_0) {
|
|
||||||
/* On 5.0.0+, setup modern 4-pool-partition layout. */
|
|
||||||
SetupPoolPartitionMemoryRegionsImpl();
|
|
||||||
} else {
|
|
||||||
/* On < 5.0.0, setup a legacy 2-pool layout for backwards compatibility. */
|
/* On < 5.0.0, setup a legacy 2-pool layout for backwards compatibility. */
|
||||||
SetupPoolPartitionMemoryRegionsDeprecatedImpl();
|
|
||||||
|
static_assert(KMemoryManager::Pool_Count == 4);
|
||||||
|
static_assert(KMemoryManager::Pool_Unsafe == KMemoryManager::Pool_Application);
|
||||||
|
static_assert(KMemoryManager::Pool_Secure == KMemoryManager::Pool_System);
|
||||||
|
|
||||||
|
/* Get Secure pool size. */
|
||||||
|
constexpr size_t LegacySecureKernelSize = 6_MB; /* KPageBuffer pages, other small kernel allocations. */
|
||||||
|
constexpr size_t LegacySecureMiscSize = 1_MB; /* Miscellaneous pages for secure process mapping. */
|
||||||
|
constexpr size_t LegacySecureHeapSize = 24_MB; /* Heap pages for secure process mapping (fs). */
|
||||||
|
constexpr size_t LegacySecureEsSize = 1_MB + 232_KB; /* Size for additional secure process (es, 4.0.0+). */
|
||||||
|
|
||||||
|
const size_t secure_pool_size = GetInitialProcessesSecureMemorySize() + LegacySecureKernelSize + LegacySecureHeapSize + LegacySecureMiscSize + (GetTargetFirmware() >= TargetFirmware_4_0_0 ? LegacySecureEsSize : 0);
|
||||||
|
|
||||||
|
/* Calculate the overhead for the secure and (defunct) applet/non-secure-system pools. */
|
||||||
|
size_t total_overhead_size = KMemoryManager::CalculateManagementOverheadSize(secure_pool_size);
|
||||||
|
|
||||||
|
/* Calculate the overhead for (an amount larger than) the unsafe pool. */
|
||||||
|
const size_t approximate_total_overhead_size = total_overhead_size + KMemoryManager::CalculateManagementOverheadSize((pool_end - pool_partitions_start) - secure_pool_size - total_overhead_size) + 2 * PageSize;
|
||||||
|
|
||||||
|
/* Determine the start of the unsafe region. */
|
||||||
|
const uintptr_t unsafe_memory_start = util::AlignUp(pool_partitions_start + secure_pool_size + approximate_total_overhead_size, CarveoutAlignment);
|
||||||
|
|
||||||
|
/* Determine the start of the pool regions. */
|
||||||
|
const uintptr_t application_pool_start = unsafe_memory_start;
|
||||||
|
|
||||||
|
/* Determine the pool sizes. */
|
||||||
|
const size_t application_pool_size = pool_end - application_pool_start;
|
||||||
|
|
||||||
|
/* We want to arrange application pool depending on where the middle of dram is. */
|
||||||
|
const uintptr_t dram_midpoint = (dram_extents.GetAddress() + dram_extents.GetEndAddress()) / 2;
|
||||||
|
u32 cur_pool_attr = 0;
|
||||||
|
if (dram_extents.GetEndAddress() <= dram_midpoint || dram_midpoint <= application_pool_start) {
|
||||||
|
InsertPoolPartitionRegionIntoBothTrees(application_pool_start, application_pool_size, KMemoryRegionType_DramApplicationPool, KMemoryRegionType_VirtualDramApplicationPool, cur_pool_attr);
|
||||||
|
total_overhead_size += KMemoryManager::CalculateManagementOverheadSize(application_pool_size);
|
||||||
|
} else {
|
||||||
|
const size_t first_application_pool_size = dram_midpoint - application_pool_start;
|
||||||
|
const size_t second_application_pool_size = application_pool_start + application_pool_size - dram_midpoint;
|
||||||
|
InsertPoolPartitionRegionIntoBothTrees(application_pool_start, first_application_pool_size, KMemoryRegionType_DramApplicationPool, KMemoryRegionType_VirtualDramApplicationPool, cur_pool_attr);
|
||||||
|
InsertPoolPartitionRegionIntoBothTrees(dram_midpoint, second_application_pool_size, KMemoryRegionType_DramApplicationPool, KMemoryRegionType_VirtualDramApplicationPool, cur_pool_attr);
|
||||||
|
total_overhead_size += KMemoryManager::CalculateManagementOverheadSize(first_application_pool_size);
|
||||||
|
total_overhead_size += KMemoryManager::CalculateManagementOverheadSize(second_application_pool_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert the secure pool. */
|
||||||
|
InsertPoolPartitionRegionIntoBothTrees(pool_partitions_start, secure_pool_size, KMemoryRegionType_DramSystemPool, KMemoryRegionType_VirtualDramSystemPool, cur_pool_attr);
|
||||||
|
|
||||||
|
/* Insert the pool management region. */
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(total_overhead_size <= approximate_total_overhead_size);
|
||||||
|
|
||||||
|
const uintptr_t pool_management_start = pool_partitions_start + secure_pool_size;
|
||||||
|
const size_t pool_management_size = unsafe_memory_start - pool_management_start;
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(total_overhead_size <= pool_management_size);
|
||||||
|
|
||||||
|
u32 pool_management_attr = 0;
|
||||||
|
InsertPoolPartitionRegionIntoBothTrees(pool_management_start, pool_management_size, KMemoryRegionType_DramPoolManagement, KMemoryRegionType_VirtualDramPoolManagement, pool_management_attr);
|
||||||
|
} else {
|
||||||
|
/* TODO: 1.0.0 single-pool layout. */
|
||||||
|
MESOSPHERE_UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,11 +152,17 @@ namespace ams::kern {
|
||||||
PrintMemoryRegion(" PageTableHeap", KMemoryLayout::GetKernelPageTableHeapRegionPhysicalExtents());
|
PrintMemoryRegion(" PageTableHeap", KMemoryLayout::GetKernelPageTableHeapRegionPhysicalExtents());
|
||||||
PrintMemoryRegion(" InitPageTable", KMemoryLayout::GetKernelInitPageTableRegionPhysicalExtents());
|
PrintMemoryRegion(" InitPageTable", KMemoryLayout::GetKernelInitPageTableRegionPhysicalExtents());
|
||||||
PrintMemoryRegion(" MemoryPoolRegion", KMemoryLayout::GetKernelPoolPartitionRegionPhysicalExtents());
|
PrintMemoryRegion(" MemoryPoolRegion", KMemoryLayout::GetKernelPoolPartitionRegionPhysicalExtents());
|
||||||
PrintMemoryRegion(" System", KMemoryLayout::GetKernelSystemPoolRegionPhysicalExtents());
|
if (GetTargetFirmware() >= TargetFirmware_5_0_0) {
|
||||||
PrintMemoryRegion(" Management", KMemoryLayout::GetKernelPoolManagementRegionPhysicalExtents());
|
PrintMemoryRegion(" System", KMemoryLayout::GetKernelSystemPoolRegionPhysicalExtents());
|
||||||
PrintMemoryRegion(" SystemUnsafe", KMemoryLayout::GetKernelSystemNonSecurePoolRegionPhysicalExtents());
|
PrintMemoryRegion(" Management", KMemoryLayout::GetKernelPoolManagementRegionPhysicalExtents());
|
||||||
PrintMemoryRegion(" Applet", KMemoryLayout::GetKernelAppletPoolRegionPhysicalExtents());
|
PrintMemoryRegion(" SystemUnsafe", KMemoryLayout::GetKernelSystemNonSecurePoolRegionPhysicalExtents());
|
||||||
PrintMemoryRegion(" Application", KMemoryLayout::GetKernelApplicationPoolRegionPhysicalExtents());
|
PrintMemoryRegion(" Applet", KMemoryLayout::GetKernelAppletPoolRegionPhysicalExtents());
|
||||||
|
PrintMemoryRegion(" Application", KMemoryLayout::GetKernelApplicationPoolRegionPhysicalExtents());
|
||||||
|
} else {
|
||||||
|
PrintMemoryRegion(" Secure", KMemoryLayout::GetKernelSystemPoolRegionPhysicalExtents());
|
||||||
|
PrintMemoryRegion(" Management", KMemoryLayout::GetKernelPoolManagementRegionPhysicalExtents());
|
||||||
|
PrintMemoryRegion(" Unsafe", KMemoryLayout::GetKernelApplicationPoolRegionPhysicalExtents());
|
||||||
|
}
|
||||||
if constexpr (IsKTraceEnabled) {
|
if constexpr (IsKTraceEnabled) {
|
||||||
MESOSPHERE_LOG(" Debug\n");
|
MESOSPHERE_LOG(" Debug\n");
|
||||||
PrintMemoryRegion(" Trace Buffer", KMemoryLayout::GetKernelTraceBufferRegionPhysicalExtents());
|
PrintMemoryRegion(" Trace Buffer", KMemoryLayout::GetKernelTraceBufferRegionPhysicalExtents());
|
||||||
|
|
|
@ -131,15 +131,16 @@ namespace ams::kern::svc {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate the pool partition. */
|
/* Validate the pool partition. */
|
||||||
/* TODO: 4.0.0 UseSecureMemory flag, pre-4.0.0 behavior. */
|
if (GetTargetFirmware() >= TargetFirmware_5_0_0) {
|
||||||
switch (params.flags & ams::svc::CreateProcessFlag_PoolPartitionMask) {
|
switch (params.flags & ams::svc::CreateProcessFlag_PoolPartitionMask) {
|
||||||
case ams::svc::CreateProcessFlag_PoolPartitionApplication:
|
case ams::svc::CreateProcessFlag_PoolPartitionApplication:
|
||||||
case ams::svc::CreateProcessFlag_PoolPartitionApplet:
|
case ams::svc::CreateProcessFlag_PoolPartitionApplet:
|
||||||
case ams::svc::CreateProcessFlag_PoolPartitionSystem:
|
case ams::svc::CreateProcessFlag_PoolPartitionSystem:
|
||||||
case ams::svc::CreateProcessFlag_PoolPartitionSystemNonSecure:
|
case ams::svc::CreateProcessFlag_PoolPartitionSystemNonSecure:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return svc::ResultInvalidEnumValue();
|
return svc::ResultInvalidEnumValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the code address is aligned. */
|
/* Check that the code address is aligned. */
|
||||||
|
@ -201,23 +202,30 @@ namespace ams::kern::svc {
|
||||||
KResourceLimit *process_resource_limit = resource_limit.IsNotNull() ? resource_limit.GetPointerUnsafe() : std::addressof(Kernel::GetSystemResourceLimit());
|
KResourceLimit *process_resource_limit = resource_limit.IsNotNull() ? resource_limit.GetPointerUnsafe() : std::addressof(Kernel::GetSystemResourceLimit());
|
||||||
|
|
||||||
/* Get the pool for the process. */
|
/* Get the pool for the process. */
|
||||||
/* TODO: 4.0.0 UseSecureMemory flag, pre-4.0.0 behavior. */
|
const auto pool = [] ALWAYS_INLINE_LAMBDA (u32 flags) -> KMemoryManager::Pool {
|
||||||
KMemoryManager::Pool pool;
|
if (GetTargetFirmware() >= TargetFirmware_5_0_0) {
|
||||||
switch (params.flags & ams::svc::CreateProcessFlag_PoolPartitionMask) {
|
switch (flags & ams::svc::CreateProcessFlag_PoolPartitionMask) {
|
||||||
case ams::svc::CreateProcessFlag_PoolPartitionApplication:
|
case ams::svc::CreateProcessFlag_PoolPartitionApplication:
|
||||||
pool = KMemoryManager::Pool_Application;
|
return KMemoryManager::Pool_Application;
|
||||||
break;
|
case ams::svc::CreateProcessFlag_PoolPartitionApplet:
|
||||||
case ams::svc::CreateProcessFlag_PoolPartitionApplet:
|
return KMemoryManager::Pool_Applet;
|
||||||
pool = KMemoryManager::Pool_Applet;
|
case ams::svc::CreateProcessFlag_PoolPartitionSystem:
|
||||||
break;
|
return KMemoryManager::Pool_System;
|
||||||
case ams::svc::CreateProcessFlag_PoolPartitionSystem:
|
case ams::svc::CreateProcessFlag_PoolPartitionSystemNonSecure:
|
||||||
pool = KMemoryManager::Pool_System;
|
default:
|
||||||
break;
|
return KMemoryManager::Pool_SystemNonSecure;
|
||||||
case ams::svc::CreateProcessFlag_PoolPartitionSystemNonSecure:
|
}
|
||||||
default:
|
} else if (GetTargetFirmware() >= TargetFirmware_4_0_0) {
|
||||||
pool = KMemoryManager::Pool_SystemNonSecure;
|
if ((flags & ams::svc::CreateProcessFlag_DeprecatedUseSecureMemory) != 0) {
|
||||||
break;
|
return KMemoryManager::Pool_Secure;
|
||||||
}
|
} else {
|
||||||
|
return KMemoryManager::Pool_Unsafe;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return KMemoryManager::Pool_Unsafe;
|
||||||
|
}
|
||||||
|
}(params.flags);
|
||||||
|
|
||||||
|
|
||||||
/* Initialize the process. */
|
/* Initialize the process. */
|
||||||
R_TRY(process->Initialize(params, user_caps, num_caps, process_resource_limit, pool));
|
R_TRY(process->Initialize(params, user_caps, num_caps, process_resource_limit, pool));
|
||||||
|
|
|
@ -168,6 +168,17 @@ namespace ams::pm::resource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsKTraceEnabled() {
|
||||||
|
if (!svc::IsKernelMesosphere()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 value = 0;
|
||||||
|
R_ABORT_UNLESS(svc::GetInfo(std::addressof(value), svc::InfoType_MesosphereMeta, INVALID_HANDLE, svc::MesosphereMetaInfo_IsKTraceEnabled));
|
||||||
|
|
||||||
|
return value != 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resource API. */
|
/* Resource API. */
|
||||||
|
@ -265,6 +276,14 @@ namespace ams::pm::resource {
|
||||||
g_memory_resource_limits[i][ResourceLimitGroup_System] += extra_memory_size;
|
g_memory_resource_limits[i][ResourceLimitGroup_System] += extra_memory_size;
|
||||||
g_memory_resource_limits[i][src_group] -= extra_memory_size;
|
g_memory_resource_limits[i][src_group] -= extra_memory_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If KTrace is enabled, account for that by subtracting the memory from the applet pool. */
|
||||||
|
if (IsKTraceEnabled()) {
|
||||||
|
constexpr size_t KTraceBufferSize = 16_MB;
|
||||||
|
for (size_t i = 0; i < spl::MemoryArrangement_Count; i++) {
|
||||||
|
g_memory_resource_limits[i][ResourceLimitGroup_Applet] -= KTraceBufferSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Actually set resource limits. */
|
/* Actually set resource limits. */
|
||||||
|
|
Loading…
Reference in a new issue