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 ++ src/core/hle/kernel/process.h | 12 +++ src/core/hle/kernel/vm_manager.cpp | 154 +++++++++++++++++++++++++++++++++++-- src/core/hle/kernel/vm_manager.h | 84 +++++++++++++++++++- 4 files changed, 248 insertions(+), 10 deletions(-) (limited to 'src/core/hle/kernel') 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]; diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 04d74e572..adb03c228 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -17,6 +17,10 @@ #include "core/hle/kernel/thread.h" #include "core/hle/kernel/vm_manager.h" +namespace FileSys { +class ProgramMetadata; +} + namespace Kernel { class KernelCore; @@ -141,6 +145,14 @@ public: return process_id; } + /** + * Loads process-specifics configuration info with metadata provided + * by an executable. + * + * @param metadata The provided metadata to load process specific info. + */ + void LoadFromMetadata(const FileSys::ProgramMetadata& metadata); + /// Title ID corresponding to the process u64 program_id; diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 608cbd57b..337f17b7b 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -9,6 +9,7 @@ #include "common/logging/log.h" #include "core/arm/arm_interface.h" #include "core/core.h" +#include "core/file_sys/program_metadata.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/vm_manager.h" #include "core/memory.h" @@ -54,25 +55,24 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { } VMManager::VMManager() { - Reset(); + // Default to assuming a 39-bit address space. This way we have a sane + // starting point with executables that don't provide metadata. + Reset(FileSys::ProgramAddressSpaceType::Is39Bit); } VMManager::~VMManager() { - Reset(); + Reset(FileSys::ProgramAddressSpaceType::Is39Bit); } -void VMManager::Reset() { - vma_map.clear(); +void VMManager::Reset(FileSys::ProgramAddressSpaceType type) { + Clear(); + InitializeMemoryRegionRanges(type); // Initialize the map with a single free region covering the entire managed space. VirtualMemoryArea initial_vma; initial_vma.size = MAX_ADDRESS; vma_map.emplace(initial_vma.base, initial_vma); - page_table.pointers.fill(nullptr); - page_table.special_regions.clear(); - page_table.attributes.fill(Memory::PageType::Unmapped); - UpdatePageTableForVMA(initial_vma); } @@ -382,6 +382,84 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { } } +void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType type) { + u64 map_region_size = 0; + u64 heap_region_size = 0; + u64 new_map_region_size = 0; + u64 tls_io_region_size = 0; + + switch (type) { + case FileSys::ProgramAddressSpaceType::Is32Bit: + address_space_width = 32; + code_region_base = 0x200000; + code_region_end = code_region_base + 0x3FE00000; + map_region_size = 0x40000000; + heap_region_size = 0x40000000; + break; + case FileSys::ProgramAddressSpaceType::Is36Bit: + address_space_width = 36; + code_region_base = 0x8000000; + code_region_end = code_region_base + 0x78000000; + map_region_size = 0x180000000; + heap_region_size = 0x180000000; + break; + case FileSys::ProgramAddressSpaceType::Is32BitNoMap: + address_space_width = 32; + code_region_base = 0x200000; + code_region_end = code_region_base + 0x3FE00000; + map_region_size = 0; + heap_region_size = 0x80000000; + break; + case FileSys::ProgramAddressSpaceType::Is39Bit: + address_space_width = 39; + code_region_base = 0x8000000; + code_region_end = code_region_base + 0x80000000; + map_region_size = 0x1000000000; + heap_region_size = 0x180000000; + new_map_region_size = 0x80000000; + tls_io_region_size = 0x1000000000; + break; + default: + UNREACHABLE_MSG("Invalid address space type specified: {}", static_cast(type)); + return; + } + + address_space_base = 0; + address_space_end = 1ULL << address_space_width; + + map_region_base = code_region_end; + map_region_end = map_region_base + map_region_size; + + heap_region_base = map_region_end; + heap_region_end = heap_region_base + heap_region_size; + + new_map_region_base = heap_region_end; + new_map_region_end = new_map_region_base + new_map_region_size; + + tls_io_region_base = new_map_region_end; + tls_io_region_end = tls_io_region_base + tls_io_region_size; + + if (new_map_region_size == 0) { + new_map_region_base = address_space_base; + new_map_region_end = address_space_end; + } +} + +void VMManager::Clear() { + ClearVMAMap(); + ClearPageTable(); +} + +void VMManager::ClearVMAMap() { + vma_map.clear(); +} + +void VMManager::ClearPageTable() { + page_table.pointers.fill(nullptr); + page_table.special_regions.clear(); + page_table.attributes.fill(Memory::PageType::Unmapped); +} + u64 VMManager::GetTotalMemoryUsage() const { LOG_WARNING(Kernel, "(STUBBED) called"); return 0xF8000000; @@ -402,4 +480,64 @@ u64 VMManager::GetAddressSpaceSize() const { return MAX_ADDRESS; } +VAddr VMManager::GetCodeRegionBaseAddress() const { + return code_region_base; +} + +VAddr VMManager::GetCodeRegionEndAddress() const { + return code_region_end; +} + +u64 VMManager::GetCodeRegionSize() const { + return code_region_end - code_region_base; +} + +VAddr VMManager::GetHeapRegionBaseAddress() const { + return heap_region_base; +} + +VAddr VMManager::GetHeapRegionEndAddress() const { + return heap_region_end; +} + +u64 VMManager::GetHeapRegionSize() const { + return heap_region_end - heap_region_base; +} + +VAddr VMManager::GetMapRegionBaseAddress() const { + return map_region_base; +} + +VAddr VMManager::GetMapRegionEndAddress() const { + return map_region_end; +} + +u64 VMManager::GetMapRegionSize() const { + return map_region_end - map_region_base; +} + +VAddr VMManager::GetNewMapRegionBaseAddress() const { + return new_map_region_base; +} + +VAddr VMManager::GetNewMapRegionEndAddress() const { + return new_map_region_end; +} + +u64 VMManager::GetNewMapRegionSize() const { + return new_map_region_end - new_map_region_base; +} + +VAddr VMManager::GetTLSIORegionBaseAddress() const { + return tls_io_region_base; +} + +VAddr VMManager::GetTLSIORegionEndAddress() const { + return tls_io_region_end; +} + +u64 VMManager::GetTLSIORegionSize() const { + return tls_io_region_end - tls_io_region_base; +} + } // namespace Kernel diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index de75036c0..0ce240126 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -12,6 +12,10 @@ #include "core/memory.h" #include "core/memory_hook.h" +namespace FileSys { +enum class ProgramAddressSpaceType : u8; +} + namespace Kernel { enum class VMAType : u8 { @@ -130,7 +134,7 @@ public: ~VMManager(); /// Clears the address space map, re-initializing with a single free area. - void Reset(); + void Reset(FileSys::ProgramAddressSpaceType type); /// Finds the VMA in which the given address is included in, or `vma_map.end()`. VMAHandle FindVMA(VAddr target) const; @@ -195,12 +199,57 @@ public: /// Gets the total heap usage, used by svcGetInfo u64 GetTotalHeapUsage() const; - /// Gets the total address space base address, used by svcGetInfo + /// Gets the address space base address, used by svcGetInfo VAddr GetAddressSpaceBaseAddr() const; /// Gets the total address space address size, used by svcGetInfo u64 GetAddressSpaceSize() const; + /// Gets the base address of the code region. + VAddr GetCodeRegionBaseAddress() const; + + /// Gets the end address of the code region. + VAddr GetCodeRegionEndAddress() const; + + /// Gets the total size of the code region in bytes. + u64 GetCodeRegionSize() const; + + /// Gets the base address of the heap region. + VAddr GetHeapRegionBaseAddress() const; + + /// Gets the end address of the heap region; + VAddr GetHeapRegionEndAddress() const; + + /// Gets the total size of the heap region in bytes. + u64 GetHeapRegionSize() const; + + /// Gets the base address of the map region. + VAddr GetMapRegionBaseAddress() const; + + /// Gets the end address of the map region. + VAddr GetMapRegionEndAddress() const; + + /// Gets the total size of the map region in bytes. + u64 GetMapRegionSize() const; + + /// Gets the base address of the new map region. + VAddr GetNewMapRegionBaseAddress() const; + + /// Gets the end address of the new map region. + VAddr GetNewMapRegionEndAddress() const; + + /// Gets the total size of the new map region in bytes. + u64 GetNewMapRegionSize() const; + + /// Gets the base address of the TLS IO region. + VAddr GetTLSIORegionBaseAddress() const; + + /// Gets the end address of the TLS IO region. + VAddr GetTLSIORegionEndAddress() const; + + /// Gets the total size of the TLS IO region in bytes. + u64 GetTLSIORegionSize() const; + /// Each VMManager has its own page table, which is set as the main one when the owning process /// is scheduled. Memory::PageTable page_table; @@ -240,5 +289,36 @@ private: /// Updates the pages corresponding to this VMA so they match the VMA's attributes. void UpdatePageTableForVMA(const VirtualMemoryArea& vma); + + /// Initializes memory region ranges to adhere to a given address space type. + void InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType type); + + /// Clears the underlying map and page table. + void Clear(); + + /// Clears out the VMA map, unmapping any previously mapped ranges. + void ClearVMAMap(); + + /// Clears out the page table + void ClearPageTable(); + + u32 address_space_width = 0; + VAddr address_space_base = 0; + VAddr address_space_end = 0; + + VAddr code_region_base = 0; + VAddr code_region_end = 0; + + VAddr heap_region_base = 0; + VAddr heap_region_end = 0; + + VAddr map_region_base = 0; + VAddr map_region_end = 0; + + VAddr new_map_region_base = 0; + VAddr new_map_region_end = 0; + + VAddr tls_io_region_base = 0; + VAddr tls_io_region_end = 0; }; } // namespace Kernel -- cgit v1.2.3 From 7fd598636e819d4e86874b20081945936a05c5f1 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 24 Sep 2018 10:29:56 -0400 Subject: memory: Dehardcode the use of a 36-bit address space Given games can also request a 32-bit or 39-bit address space, we shouldn't be hardcoding the address space range as 36-bit. --- src/core/hle/kernel/vm_manager.cpp | 18 +++++++++++++----- src/core/hle/kernel/vm_manager.h | 3 +++ 2 files changed, 16 insertions(+), 5 deletions(-) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 337f17b7b..20d06f000 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -66,18 +66,21 @@ VMManager::~VMManager() { void VMManager::Reset(FileSys::ProgramAddressSpaceType type) { Clear(); + InitializeMemoryRegionRanges(type); + page_table.Resize(address_space_width); + // Initialize the map with a single free region covering the entire managed space. VirtualMemoryArea initial_vma; - initial_vma.size = MAX_ADDRESS; + initial_vma.size = address_space_end; vma_map.emplace(initial_vma.base, initial_vma); UpdatePageTableForVMA(initial_vma); } VMManager::VMAHandle VMManager::FindVMA(VAddr target) const { - if (target >= MAX_ADDRESS) { + if (target >= address_space_end) { return vma_map.end(); } else { return std::prev(vma_map.upper_bound(target)); @@ -291,7 +294,7 @@ ResultVal VMManager::CarveVMARange(VAddr target, u64 size) { const VAddr target_end = target + size; ASSERT(target_end >= target); - ASSERT(target_end <= MAX_ADDRESS); + ASSERT(target_end <= address_space_end); ASSERT(size > 0); VMAIter begin_vma = StripIterConstness(FindVMA(target)); @@ -455,9 +458,10 @@ void VMManager::ClearVMAMap() { } void VMManager::ClearPageTable() { - page_table.pointers.fill(nullptr); + std::fill(page_table.pointers.begin(), page_table.pointers.end(), nullptr); page_table.special_regions.clear(); - page_table.attributes.fill(Memory::PageType::Unmapped); + std::fill(page_table.attributes.begin(), page_table.attributes.end(), + Memory::PageType::Unmapped); } u64 VMManager::GetTotalMemoryUsage() const { @@ -480,6 +484,10 @@ u64 VMManager::GetAddressSpaceSize() const { return MAX_ADDRESS; } +u64 VMManager::GetAddressSpaceWidth() const { + return address_space_width; +} + VAddr VMManager::GetCodeRegionBaseAddress() const { return code_region_base; } diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 0ce240126..581bf3d00 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -205,6 +205,9 @@ public: /// Gets the total address space address size, used by svcGetInfo u64 GetAddressSpaceSize() const; + /// Gets the address space width in bits. + u64 GetAddressSpaceWidth() const; + /// Gets the base address of the code region. VAddr GetCodeRegionBaseAddress() const; -- cgit v1.2.3 From 6c6f95d071b25f2743fcb6652f4389c9e25a7506 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 24 Sep 2018 11:16:17 -0400 Subject: svc: Report correct memory-related values within some of the cases in svcGetInfo() Previously, these were reporting hardcoded values, but given the regions can change depending on the requested address spaces, these need to report the values that the memory manager contains. --- src/core/hle/kernel/svc.cpp | 42 +++++++++++++++++++++++++------------- src/core/hle/kernel/vm_manager.cpp | 12 ++++++----- src/core/hle/kernel/vm_manager.h | 15 ++++++-------- 3 files changed, 41 insertions(+), 28 deletions(-) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 0bc407098..e0f5e3f39 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -325,26 +325,27 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, info_sub_id, handle); - const auto& vm_manager = Core::CurrentProcess()->vm_manager; + const auto& current_process = Core::CurrentProcess(); + const auto& vm_manager = current_process->vm_manager; switch (static_cast(info_id)) { case GetInfoType::AllowedCpuIdBitmask: - *result = Core::CurrentProcess()->allowed_processor_mask; + *result = current_process->allowed_processor_mask; break; case GetInfoType::AllowedThreadPrioBitmask: - *result = Core::CurrentProcess()->allowed_thread_priority_mask; + *result = current_process->allowed_thread_priority_mask; break; case GetInfoType::MapRegionBaseAddr: - *result = Memory::MAP_REGION_VADDR; + *result = vm_manager.GetMapRegionBaseAddress(); break; case GetInfoType::MapRegionSize: - *result = Memory::MAP_REGION_SIZE; + *result = vm_manager.GetMapRegionSize(); break; case GetInfoType::HeapRegionBaseAddr: - *result = Memory::HEAP_VADDR; + *result = vm_manager.GetHeapRegionBaseAddress(); break; case GetInfoType::HeapRegionSize: - *result = Memory::HEAP_SIZE; + *result = vm_manager.GetHeapRegionSize(); break; case GetInfoType::TotalMemoryUsage: *result = vm_manager.GetTotalMemoryUsage(); @@ -359,22 +360,35 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) *result = 0; break; case GetInfoType::AddressSpaceBaseAddr: - *result = vm_manager.GetAddressSpaceBaseAddr(); + *result = vm_manager.GetCodeRegionBaseAddress(); break; - case GetInfoType::AddressSpaceSize: - *result = vm_manager.GetAddressSpaceSize(); + case GetInfoType::AddressSpaceSize: { + const u64 width = vm_manager.GetAddressSpaceWidth(); + + switch (width) { + case 32: + *result = 0xFFE00000; + break; + case 36: + *result = 0xFF8000000; + break; + case 39: + *result = 0x7FF8000000; + break; + } break; + } case GetInfoType::NewMapRegionBaseAddr: - *result = Memory::NEW_MAP_REGION_VADDR; + *result = vm_manager.GetNewMapRegionBaseAddress(); break; case GetInfoType::NewMapRegionSize: - *result = Memory::NEW_MAP_REGION_SIZE; + *result = vm_manager.GetNewMapRegionSize(); break; case GetInfoType::IsVirtualAddressMemoryEnabled: - *result = Core::CurrentProcess()->is_virtual_address_memory_enabled; + *result = current_process->is_virtual_address_memory_enabled; break; case GetInfoType::TitleId: - *result = Core::CurrentProcess()->program_id; + *result = current_process->program_id; break; case GetInfoType::PrivilegedProcessId: LOG_WARNING(Kernel_SVC, diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 20d06f000..e412309fd 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -474,14 +474,16 @@ u64 VMManager::GetTotalHeapUsage() const { return 0x0; } -VAddr VMManager::GetAddressSpaceBaseAddr() const { - LOG_WARNING(Kernel, "(STUBBED) called"); - return 0x8000000; +VAddr VMManager::GetAddressSpaceBaseAddress() const { + return address_space_base; +} + +VAddr VMManager::GetAddressSpaceEndAddress() const { + return address_space_end; } u64 VMManager::GetAddressSpaceSize() const { - LOG_WARNING(Kernel, "(STUBBED) called"); - return MAX_ADDRESS; + return address_space_end - address_space_base; } u64 VMManager::GetAddressSpaceWidth() const { diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 581bf3d00..015559a64 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -114,12 +114,6 @@ struct VirtualMemoryArea { */ class VMManager final { public: - /** - * The maximum amount of address space managed by the kernel. - * @todo This was selected arbitrarily, and should be verified for Switch OS. - */ - static constexpr VAddr MAX_ADDRESS{0x1000000000ULL}; - /** * A map covering the entirety of the managed address space, keyed by the `base` field of each * VMA. It must always be modified by splitting or merging VMAs, so that the invariant @@ -199,10 +193,13 @@ public: /// Gets the total heap usage, used by svcGetInfo u64 GetTotalHeapUsage() const; - /// Gets the address space base address, used by svcGetInfo - VAddr GetAddressSpaceBaseAddr() const; + /// Gets the address space base address + VAddr GetAddressSpaceBaseAddress() const; + + /// Gets the address space end address + VAddr GetAddressSpaceEndAddress() const; - /// Gets the total address space address size, used by svcGetInfo + /// Gets the total address space address size in bytes u64 GetAddressSpaceSize() const; /// Gets the address space width in bits. -- 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 ++++++++++---------- src/core/hle/kernel/shared_memory.cpp | 4 +++- src/core/hle/kernel/svc.cpp | 3 ++- src/core/hle/kernel/thread.cpp | 3 ++- 4 files changed, 17 insertions(+), 13 deletions(-) (limited to 'src/core/hle/kernel') 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; } diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index abb1d09cd..9b78c8cb5 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -8,6 +8,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/hle/kernel/errors.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/shared_memory.h" #include "core/memory.h" @@ -71,7 +72,8 @@ SharedPtr SharedMemory::CreateForApplet( shared_memory->other_permissions = other_permissions; shared_memory->backing_block = std::move(heap_block); shared_memory->backing_block_offset = offset; - shared_memory->base_address = Memory::HEAP_VADDR + offset; + shared_memory->base_address = + kernel.CurrentProcess()->vm_manager.GetHeapRegionBaseAddress() + offset; return shared_memory; } diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index e0f5e3f39..c2b77eb49 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -51,8 +51,9 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { } auto& process = *Core::CurrentProcess(); + const VAddr heap_base = process.vm_manager.GetHeapRegionBaseAddress(); CASCADE_RESULT(*heap_addr, - process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite)); + process.HeapAllocate(heap_base, heap_size, VMAPermission::ReadWrite)); return RESULT_SUCCESS; } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 315f65338..064ed908d 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -262,8 +262,9 @@ SharedPtr SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 pri SetCurrentPageTable(&owner_process.vm_manager.page_table); // Initialize new "main" thread + const VAddr stack_top = owner_process.vm_manager.GetTLSIORegionEndAddress(); auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0, - Memory::STACK_AREA_VADDR_END, &owner_process); + stack_top, &owner_process); SharedPtr thread = std::move(thread_res).Unwrap(); -- cgit v1.2.3