From 75603b005bb9163810a02376cd33854cd1b16ef9 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 22 Sep 2018 20:09:32 -0400 Subject: process/vm_manager: Amend API to allow reading parameters from NPDM metadata Rather than hard-code the address range to be 36-bit, we can derive the parameters from supplied NPDM metadata if the supplied exectuable supports it. This is the bare minimum necessary for this to be possible. The following commits will rework the memory code further to adjust to this. --- src/core/hle/kernel/process.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/core/hle/kernel/process.cpp') diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 121f741fd..f337f626f 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -8,6 +8,7 @@ #include "common/common_funcs.h" #include "common/logging/log.h" #include "core/core.h" +#include "core/file_sys/program_metadata.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" @@ -34,14 +35,21 @@ SharedPtr Process::Create(KernelCore& kernel, std::string&& name) { process->name = std::move(name); process->flags.raw = 0; process->flags.memory_region.Assign(MemoryRegion::APPLICATION); + process->resource_limit = kernel.ResourceLimitForCategory(ResourceLimitCategory::APPLICATION); process->status = ProcessStatus::Created; process->program_id = 0; process->process_id = kernel.CreateNewProcessID(); + process->svc_access_mask.set(); kernel.AppendNewProcess(process); return process; } +void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { + program_id = metadata.GetTitleID(); + vm_manager.Reset(metadata.GetAddressSpaceType()); +} + void Process::ParseKernelCaps(const u32* kernel_caps, std::size_t len) { for (std::size_t i = 0; i < len; ++i) { u32 descriptor = kernel_caps[i]; -- cgit v1.2.3 From 83377113bfe7791483a1b67e06dd0f51620c04ec Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 24 Sep 2018 20:01:45 -0400 Subject: memory: Dehardcode the use of fixed memory range constants The locations of these can actually vary depending on the address space layout, so we shouldn't be using these when determining where to map memory or be using them as offsets for calculations. This keeps all the memory ranges flexible and malleable based off of the virtual memory manager instance state. --- src/core/hle/kernel/process.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/core/hle/kernel/process.cpp') diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index f337f626f..a8e3098ca 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -127,7 +127,7 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { // TODO(bunnei): This is heap area that should be allocated by the kernel and not mapped as part // of the user address space. vm_manager - .MapMemoryBlock(Memory::STACK_AREA_VADDR_END - stack_size, + .MapMemoryBlock(vm_manager.GetTLSIORegionEndAddress() - stack_size, std::make_shared>(stack_size, 0), 0, stack_size, MemoryState::Mapped) .Unwrap(); @@ -193,6 +193,7 @@ static std::tuple FindFreeThreadLocalSlot( VAddr Process::MarkNextAvailableTLSSlotAsUsed(Thread& thread) { auto [available_page, available_slot, needs_allocation] = FindFreeThreadLocalSlot(tls_slots); + const VAddr tls_begin = vm_manager.GetTLSIORegionBaseAddress(); if (needs_allocation) { tls_slots.emplace_back(0); // The page is completely available at the start @@ -205,18 +206,17 @@ VAddr Process::MarkNextAvailableTLSSlotAsUsed(Thread& thread) { vm_manager.RefreshMemoryBlockMappings(tls_memory.get()); - vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, - tls_memory, 0, Memory::PAGE_SIZE, MemoryState::ThreadLocal); + vm_manager.MapMemoryBlock(tls_begin + available_page * Memory::PAGE_SIZE, tls_memory, 0, + Memory::PAGE_SIZE, MemoryState::ThreadLocal); } tls_slots[available_page].set(available_slot); - return Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE + - available_slot * Memory::TLS_ENTRY_SIZE; + return tls_begin + available_page * Memory::PAGE_SIZE + available_slot * Memory::TLS_ENTRY_SIZE; } void Process::FreeTLSSlot(VAddr tls_address) { - const VAddr tls_base = tls_address - Memory::TLS_AREA_VADDR; + const VAddr tls_base = tls_address - vm_manager.GetTLSIORegionBaseAddress(); const VAddr tls_page = tls_base / Memory::PAGE_SIZE; const VAddr tls_slot = (tls_base % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; @@ -240,8 +240,8 @@ void Process::LoadModule(SharedPtr module_, VAddr base_addr) { } ResultVal Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { - if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || - target + size < target) { + if (target < vm_manager.GetHeapRegionBaseAddress() || + target + size > vm_manager.GetHeapRegionEndAddress() || target + size < target) { return ERR_INVALID_ADDRESS; } @@ -276,8 +276,8 @@ ResultVal Process::HeapAllocate(VAddr target, u64 size, VMAPermission per } ResultCode Process::HeapFree(VAddr target, u32 size) { - if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || - target + size < target) { + if (target < vm_manager.GetHeapRegionBaseAddress() || + target + size > vm_manager.GetHeapRegionEndAddress() || target + size < target) { return ERR_INVALID_ADDRESS; } -- cgit v1.2.3