mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2025-06-12 19:37:56 -05:00
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.
This commit is contained in:
@ -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<u32>(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
|
||||
|
Reference in New Issue
Block a user