diff options
Diffstat (limited to 'src/core/hle/kernel/process.cpp')
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 47b3ac57b..73b85d6f9 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -14,14 +14,14 @@ | |||
| 14 | #include "core/device_memory.h" | 14 | #include "core/device_memory.h" |
| 15 | #include "core/file_sys/program_metadata.h" | 15 | #include "core/file_sys/program_metadata.h" |
| 16 | #include "core/hle/kernel/code_set.h" | 16 | #include "core/hle/kernel/code_set.h" |
| 17 | #include "core/hle/kernel/k_memory_block_manager.h" | ||
| 18 | #include "core/hle/kernel/k_page_table.h" | ||
| 17 | #include "core/hle/kernel/k_resource_limit.h" | 19 | #include "core/hle/kernel/k_resource_limit.h" |
| 18 | #include "core/hle/kernel/k_scheduler.h" | 20 | #include "core/hle/kernel/k_scheduler.h" |
| 19 | #include "core/hle/kernel/k_scoped_resource_reservation.h" | 21 | #include "core/hle/kernel/k_scoped_resource_reservation.h" |
| 22 | #include "core/hle/kernel/k_slab_heap.h" | ||
| 20 | #include "core/hle/kernel/k_thread.h" | 23 | #include "core/hle/kernel/k_thread.h" |
| 21 | #include "core/hle/kernel/kernel.h" | 24 | #include "core/hle/kernel/kernel.h" |
| 22 | #include "core/hle/kernel/memory/memory_block_manager.h" | ||
| 23 | #include "core/hle/kernel/memory/page_table.h" | ||
| 24 | #include "core/hle/kernel/memory/slab_heap.h" | ||
| 25 | #include "core/hle/kernel/process.h" | 25 | #include "core/hle/kernel/process.h" |
| 26 | #include "core/hle/kernel/svc_results.h" | 26 | #include "core/hle/kernel/svc_results.h" |
| 27 | #include "core/hle/lock.h" | 27 | #include "core/hle/lock.h" |
| @@ -274,7 +274,7 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||
| 274 | // Set initial resource limits | 274 | // Set initial resource limits |
| 275 | resource_limit->SetLimitValue( | 275 | resource_limit->SetLimitValue( |
| 276 | LimitableResource::PhysicalMemory, | 276 | LimitableResource::PhysicalMemory, |
| 277 | kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application)); | 277 | kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application)); |
| 278 | KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, | 278 | KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, |
| 279 | code_size + system_resource_size); | 279 | code_size + system_resource_size); |
| 280 | if (!memory_reservation.Succeeded()) { | 280 | if (!memory_reservation.Succeeded()) { |
| @@ -285,15 +285,15 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||
| 285 | // Initialize proces address space | 285 | // Initialize proces address space |
| 286 | if (const ResultCode result{ | 286 | if (const ResultCode result{ |
| 287 | page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, 0x8000000, | 287 | page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, 0x8000000, |
| 288 | code_size, Memory::MemoryManager::Pool::Application)}; | 288 | code_size, KMemoryManager::Pool::Application)}; |
| 289 | result.IsError()) { | 289 | result.IsError()) { |
| 290 | return result; | 290 | return result; |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | // Map process code region | 293 | // Map process code region |
| 294 | if (const ResultCode result{page_table->MapProcessCode( | 294 | if (const ResultCode result{page_table->MapProcessCode(page_table->GetCodeRegionStart(), |
| 295 | page_table->GetCodeRegionStart(), code_size / Memory::PageSize, | 295 | code_size / PageSize, KMemoryState::Code, |
| 296 | Memory::MemoryState::Code, Memory::MemoryPermission::None)}; | 296 | KMemoryPermission::None)}; |
| 297 | result.IsError()) { | 297 | result.IsError()) { |
| 298 | return result; | 298 | return result; |
| 299 | } | 299 | } |
| @@ -323,6 +323,11 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||
| 323 | UNREACHABLE(); | 323 | UNREACHABLE(); |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | // Set initial resource limits | ||
| 327 | resource_limit->SetLimitValue( | ||
| 328 | LimitableResource::PhysicalMemory, | ||
| 329 | kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application)); | ||
| 330 | |||
| 326 | resource_limit->SetLimitValue(LimitableResource::Threads, 608); | 331 | resource_limit->SetLimitValue(LimitableResource::Threads, 608); |
| 327 | resource_limit->SetLimitValue(LimitableResource::Events, 700); | 332 | resource_limit->SetLimitValue(LimitableResource::Events, 700); |
| 328 | resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128); | 333 | resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128); |
| @@ -400,22 +405,22 @@ VAddr Process::CreateTLSRegion() { | |||
| 400 | return *tls_page_iter->ReserveSlot(); | 405 | return *tls_page_iter->ReserveSlot(); |
| 401 | } | 406 | } |
| 402 | 407 | ||
| 403 | Memory::Page* const tls_page_ptr{kernel.GetUserSlabHeapPages().Allocate()}; | 408 | Page* const tls_page_ptr{kernel.GetUserSlabHeapPages().Allocate()}; |
| 404 | ASSERT(tls_page_ptr); | 409 | ASSERT(tls_page_ptr); |
| 405 | 410 | ||
| 406 | const VAddr start{page_table->GetKernelMapRegionStart()}; | 411 | const VAddr start{page_table->GetKernelMapRegionStart()}; |
| 407 | const VAddr size{page_table->GetKernelMapRegionEnd() - start}; | 412 | const VAddr size{page_table->GetKernelMapRegionEnd() - start}; |
| 408 | const PAddr tls_map_addr{system.DeviceMemory().GetPhysicalAddr(tls_page_ptr)}; | 413 | const PAddr tls_map_addr{system.DeviceMemory().GetPhysicalAddr(tls_page_ptr)}; |
| 409 | const VAddr tls_page_addr{ | 414 | const VAddr tls_page_addr{page_table |
| 410 | page_table | 415 | ->AllocateAndMapMemory(1, PageSize, true, start, size / PageSize, |
| 411 | ->AllocateAndMapMemory(1, Memory::PageSize, true, start, size / Memory::PageSize, | 416 | KMemoryState::ThreadLocal, |
| 412 | Memory::MemoryState::ThreadLocal, | 417 | KMemoryPermission::ReadAndWrite, |
| 413 | Memory::MemoryPermission::ReadAndWrite, tls_map_addr) | 418 | tls_map_addr) |
| 414 | .ValueOr(0)}; | 419 | .ValueOr(0)}; |
| 415 | 420 | ||
| 416 | ASSERT(tls_page_addr); | 421 | ASSERT(tls_page_addr); |
| 417 | 422 | ||
| 418 | std::memset(tls_page_ptr, 0, Memory::PageSize); | 423 | std::memset(tls_page_ptr, 0, PageSize); |
| 419 | tls_pages.emplace_back(tls_page_addr); | 424 | tls_pages.emplace_back(tls_page_addr); |
| 420 | 425 | ||
| 421 | const auto reserve_result{tls_pages.back().ReserveSlot()}; | 426 | const auto reserve_result{tls_pages.back().ReserveSlot()}; |
| @@ -442,15 +447,15 @@ void Process::FreeTLSRegion(VAddr tls_address) { | |||
| 442 | void Process::LoadModule(CodeSet code_set, VAddr base_addr) { | 447 | void Process::LoadModule(CodeSet code_set, VAddr base_addr) { |
| 443 | std::lock_guard lock{HLE::g_hle_lock}; | 448 | std::lock_guard lock{HLE::g_hle_lock}; |
| 444 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, | 449 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, |
| 445 | Memory::MemoryPermission permission) { | 450 | KMemoryPermission permission) { |
| 446 | page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); | 451 | page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); |
| 447 | }; | 452 | }; |
| 448 | 453 | ||
| 449 | system.Memory().WriteBlock(*this, base_addr, code_set.memory.data(), code_set.memory.size()); | 454 | system.Memory().WriteBlock(*this, base_addr, code_set.memory.data(), code_set.memory.size()); |
| 450 | 455 | ||
| 451 | ReprotectSegment(code_set.CodeSegment(), Memory::MemoryPermission::ReadAndExecute); | 456 | ReprotectSegment(code_set.CodeSegment(), KMemoryPermission::ReadAndExecute); |
| 452 | ReprotectSegment(code_set.RODataSegment(), Memory::MemoryPermission::Read); | 457 | ReprotectSegment(code_set.RODataSegment(), KMemoryPermission::Read); |
| 453 | ReprotectSegment(code_set.DataSegment(), Memory::MemoryPermission::ReadAndWrite); | 458 | ReprotectSegment(code_set.DataSegment(), KMemoryPermission::ReadAndWrite); |
| 454 | } | 459 | } |
| 455 | 460 | ||
| 456 | bool Process::IsSignaled() const { | 461 | bool Process::IsSignaled() const { |
| @@ -459,9 +464,9 @@ bool Process::IsSignaled() const { | |||
| 459 | } | 464 | } |
| 460 | 465 | ||
| 461 | Process::Process(Core::System& system) | 466 | Process::Process(Core::System& system) |
| 462 | : KSynchronizationObject{system.Kernel()}, | 467 | : KSynchronizationObject{system.Kernel()}, page_table{std::make_unique<KPageTable>(system)}, |
| 463 | page_table{std::make_unique<Memory::PageTable>(system)}, handle_table{system.Kernel()}, | 468 | handle_table{system.Kernel()}, address_arbiter{system}, condition_var{system}, |
| 464 | address_arbiter{system}, condition_var{system}, state_lock{system.Kernel()}, system{system} {} | 469 | state_lock{system.Kernel()}, system{system} {} |
| 465 | 470 | ||
| 466 | Process::~Process() = default; | 471 | Process::~Process() = default; |
| 467 | 472 | ||
| @@ -479,16 +484,15 @@ ResultCode Process::AllocateMainThreadStack(std::size_t stack_size) { | |||
| 479 | ASSERT(stack_size); | 484 | ASSERT(stack_size); |
| 480 | 485 | ||
| 481 | // The kernel always ensures that the given stack size is page aligned. | 486 | // The kernel always ensures that the given stack size is page aligned. |
| 482 | main_thread_stack_size = Common::AlignUp(stack_size, Memory::PageSize); | 487 | main_thread_stack_size = Common::AlignUp(stack_size, PageSize); |
| 483 | 488 | ||
| 484 | const VAddr start{page_table->GetStackRegionStart()}; | 489 | const VAddr start{page_table->GetStackRegionStart()}; |
| 485 | const std::size_t size{page_table->GetStackRegionEnd() - start}; | 490 | const std::size_t size{page_table->GetStackRegionEnd() - start}; |
| 486 | 491 | ||
| 487 | CASCADE_RESULT(main_thread_stack_top, | 492 | CASCADE_RESULT(main_thread_stack_top, |
| 488 | page_table->AllocateAndMapMemory( | 493 | page_table->AllocateAndMapMemory( |
| 489 | main_thread_stack_size / Memory::PageSize, Memory::PageSize, false, start, | 494 | main_thread_stack_size / PageSize, PageSize, false, start, size / PageSize, |
| 490 | size / Memory::PageSize, Memory::MemoryState::Stack, | 495 | KMemoryState::Stack, KMemoryPermission::ReadAndWrite)); |
| 491 | Memory::MemoryPermission::ReadAndWrite)); | ||
| 492 | 496 | ||
| 493 | main_thread_stack_top += main_thread_stack_size; | 497 | main_thread_stack_top += main_thread_stack_size; |
| 494 | 498 | ||