diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 41 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 24 |
2 files changed, 27 insertions, 38 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 8fd990577..f7d3f218a 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -67,8 +67,13 @@ struct KernelCore::Impl { | |||
| 67 | is_phantom_mode_for_singlecore = false; | 67 | is_phantom_mode_for_singlecore = false; |
| 68 | 68 | ||
| 69 | InitializePhysicalCores(); | 69 | InitializePhysicalCores(); |
| 70 | InitializeSystemResourceLimit(kernel, system); | 70 | |
| 71 | InitializeMemoryLayout(); | 71 | // Derive the initial memory layout from the emulated board |
| 72 | KMemoryLayout memory_layout; | ||
| 73 | DeriveInitialMemoryLayout(memory_layout); | ||
| 74 | InitializeMemoryLayout(memory_layout); | ||
| 75 | InitializeSystemResourceLimit(kernel, system, memory_layout); | ||
| 76 | InitializeSlabHeaps(); | ||
| 72 | InitializeSchedulers(); | 77 | InitializeSchedulers(); |
| 73 | InitializeSuspendThreads(); | 78 | InitializeSuspendThreads(); |
| 74 | InitializePreemption(kernel); | 79 | InitializePreemption(kernel); |
| @@ -137,27 +142,32 @@ struct KernelCore::Impl { | |||
| 137 | } | 142 | } |
| 138 | 143 | ||
| 139 | // Creates the default system resource limit | 144 | // Creates the default system resource limit |
| 140 | void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) { | 145 | void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system, |
| 146 | const KMemoryLayout& memory_layout) { | ||
| 141 | system_resource_limit = std::make_shared<KResourceLimit>(kernel, system); | 147 | system_resource_limit = std::make_shared<KResourceLimit>(kernel, system); |
| 148 | const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes(); | ||
| 142 | 149 | ||
| 143 | // If setting the default system values fails, then something seriously wrong has occurred. | 150 | // If setting the default system values fails, then something seriously wrong has occurred. |
| 144 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000) | 151 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size) |
| 145 | .IsSuccess()); | 152 | .IsSuccess()); |
| 146 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); | 153 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); |
| 147 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess()); | 154 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess()); |
| 148 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200) | 155 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200) |
| 149 | .IsSuccess()); | 156 | .IsSuccess()); |
| 150 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess()); | 157 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess()); |
| 158 | system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size); | ||
| 151 | 159 | ||
| 152 | // Derived from recent software updates. The kernel reserves 27MB | ||
| 153 | constexpr u64 kernel_size{0x1b00000}; | ||
| 154 | if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size)) { | ||
| 155 | UNREACHABLE(); | ||
| 156 | } | ||
| 157 | // Reserve secure applet memory, introduced in firmware 5.0.0 | 160 | // Reserve secure applet memory, introduced in firmware 5.0.0 |
| 158 | constexpr u64 secure_applet_memory_size{0x400000}; | 161 | constexpr u64 secure_applet_memory_size{Common::Size_4_MB}; |
| 159 | ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory, | 162 | ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory, |
| 160 | secure_applet_memory_size)); | 163 | secure_applet_memory_size)); |
| 164 | |||
| 165 | // This memory seems to be reserved on hardware, but is not reserved/used by yuzu. | ||
| 166 | // Likely Horizon OS reserved memory | ||
| 167 | // TODO(ameerj): Derive the memory rather than hardcode it. | ||
| 168 | constexpr u64 unknown_reserved_memory{0x2f896000}; | ||
| 169 | ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory, | ||
| 170 | unknown_reserved_memory)); | ||
| 161 | } | 171 | } |
| 162 | 172 | ||
| 163 | void InitializePreemption(KernelCore& kernel) { | 173 | void InitializePreemption(KernelCore& kernel) { |
| @@ -531,11 +541,7 @@ struct KernelCore::Impl { | |||
| 531 | linear_region_start); | 541 | linear_region_start); |
| 532 | } | 542 | } |
| 533 | 543 | ||
| 534 | void InitializeMemoryLayout() { | 544 | void InitializeMemoryLayout(const KMemoryLayout& memory_layout) { |
| 535 | // Derive the initial memory layout from the emulated board | ||
| 536 | KMemoryLayout memory_layout; | ||
| 537 | DeriveInitialMemoryLayout(memory_layout); | ||
| 538 | |||
| 539 | const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents(); | 545 | const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents(); |
| 540 | const auto applet_pool = memory_layout.GetKernelAppletPoolRegionPhysicalExtents(); | 546 | const auto applet_pool = memory_layout.GetKernelAppletPoolRegionPhysicalExtents(); |
| 541 | const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents(); | 547 | const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents(); |
| @@ -578,11 +584,14 @@ struct KernelCore::Impl { | |||
| 578 | system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize}, | 584 | system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize}, |
| 579 | KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size, | 585 | KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size, |
| 580 | "Time:SharedMemory"); | 586 | "Time:SharedMemory"); |
| 587 | } | ||
| 581 | 588 | ||
| 589 | void InitializeSlabHeaps() { | ||
| 582 | // Allocate slab heaps | 590 | // Allocate slab heaps |
| 583 | user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>(); | 591 | user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>(); |
| 584 | 592 | ||
| 585 | constexpr u64 user_slab_heap_size{0x1ef000}; | 593 | // TODO(ameerj): This should be derived, not hardcoded within the kernel |
| 594 | constexpr u64 user_slab_heap_size{0x3de000}; | ||
| 586 | // Reserve slab heaps | 595 | // Reserve slab heaps |
| 587 | ASSERT( | 596 | ASSERT( |
| 588 | system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size)); | 597 | system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size)); |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 9d5956ead..dd01f3924 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -120,9 +120,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name, | |||
| 120 | std::shared_ptr<Process> process = std::make_shared<Process>(system); | 120 | std::shared_ptr<Process> process = std::make_shared<Process>(system); |
| 121 | process->name = std::move(name); | 121 | process->name = std::move(name); |
| 122 | 122 | ||
| 123 | // TODO: This is inaccurate | 123 | process->resource_limit = kernel.GetSystemResourceLimit(); |
| 124 | // The process should hold a reference to the kernel-wide resource limit. | ||
| 125 | process->resource_limit = std::make_shared<KResourceLimit>(kernel, system); | ||
| 126 | process->status = ProcessStatus::Created; | 124 | process->status = ProcessStatus::Created; |
| 127 | process->program_id = 0; | 125 | process->program_id = 0; |
| 128 | process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() | 126 | process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() |
| @@ -160,17 +158,13 @@ void Process::DecrementThreadCount() { | |||
| 160 | } | 158 | } |
| 161 | 159 | ||
| 162 | u64 Process::GetTotalPhysicalMemoryAvailable() const { | 160 | u64 Process::GetTotalPhysicalMemoryAvailable() const { |
| 163 | // TODO: This is expected to always return the application memory pool size after accurately | ||
| 164 | // reserving kernel resources. The current workaround uses a process-local resource limit of | ||
| 165 | // application memory pool size, which is inaccurate. | ||
| 166 | const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + | 161 | const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + |
| 167 | page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + | 162 | page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + |
| 168 | main_thread_stack_size}; | 163 | main_thread_stack_size}; |
| 169 | 164 | ASSERT(capacity == kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application)); | |
| 170 | if (capacity < memory_usage_capacity) { | 165 | if (capacity < memory_usage_capacity) { |
| 171 | return capacity; | 166 | return capacity; |
| 172 | } | 167 | } |
| 173 | |||
| 174 | return memory_usage_capacity; | 168 | return memory_usage_capacity; |
| 175 | } | 169 | } |
| 176 | 170 | ||
| @@ -272,10 +266,6 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||
| 272 | system_resource_size = metadata.GetSystemResourceSize(); | 266 | system_resource_size = metadata.GetSystemResourceSize(); |
| 273 | image_size = code_size; | 267 | image_size = code_size; |
| 274 | 268 | ||
| 275 | // Set initial resource limits | ||
| 276 | resource_limit->SetLimitValue( | ||
| 277 | LimitableResource::PhysicalMemory, | ||
| 278 | kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application)); | ||
| 279 | KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, | 269 | KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, |
| 280 | code_size + system_resource_size); | 270 | code_size + system_resource_size); |
| 281 | if (!memory_reservation.Succeeded()) { | 271 | if (!memory_reservation.Succeeded()) { |
| @@ -324,16 +314,6 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||
| 324 | UNREACHABLE(); | 314 | UNREACHABLE(); |
| 325 | } | 315 | } |
| 326 | 316 | ||
| 327 | // Set initial resource limits | ||
| 328 | resource_limit->SetLimitValue( | ||
| 329 | LimitableResource::PhysicalMemory, | ||
| 330 | kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application)); | ||
| 331 | |||
| 332 | resource_limit->SetLimitValue(LimitableResource::Threads, 608); | ||
| 333 | resource_limit->SetLimitValue(LimitableResource::Events, 700); | ||
| 334 | resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128); | ||
| 335 | resource_limit->SetLimitValue(LimitableResource::Sessions, 894); | ||
| 336 | |||
| 337 | // Create TLS region | 317 | // Create TLS region |
| 338 | tls_region_address = CreateTLSRegion(); | 318 | tls_region_address = CreateTLSRegion(); |
| 339 | memory_reservation.Commit(); | 319 | memory_reservation.Commit(); |