summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/arm/arm_interface.h6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp4
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h2
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp4
-rw-r--r--src/core/arm/unicorn/arm_unicorn.h1
-rw-r--r--src/core/hle/kernel/kernel.h4
-rw-r--r--src/core/hle/kernel/process.cpp21
-rw-r--r--src/core/hle/kernel/svc.cpp12
-rw-r--r--src/core/hle/kernel/thread.cpp4
-rw-r--r--src/core/hle/kernel/vm_manager.cpp42
-rw-r--r--src/core/hle/kernel/vm_manager.h38
-rw-r--r--src/core/loader/elf.cpp2
-rw-r--r--src/core/loader/nro.cpp2
-rw-r--r--src/core/loader/nso.cpp2
-rw-r--r--src/core/memory.h48
15 files changed, 110 insertions, 82 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 5ae60214e..6667c7dba 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -39,8 +39,12 @@ public:
Run(1);
}
+ /// Maps a backing memory region for the CPU
virtual void MapBackingMemory(VAddr address, size_t size, u8* memory,
- Kernel::VMAPermission perms) {}
+ Kernel::VMAPermission perms) = 0;
+
+ /// Unmaps a region of memory that was previously mapped using MapBackingMemory
+ virtual void UnmapMemory(VAddr address, size_t size) = 0;
/// Clear all instruction cache
virtual void ClearInstructionCache() = 0;
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 4da07b177..0902c6df3 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -136,6 +136,10 @@ void ARM_Dynarmic::MapBackingMemory(u64 address, size_t size, u8* memory,
inner_unicorn.MapBackingMemory(address, size, memory, perms);
}
+void ARM_Dynarmic::UnmapMemory(u64 address, size_t size) {
+ inner_unicorn.UnmapMemory(address, size);
+}
+
void ARM_Dynarmic::SetPC(u64 pc) {
jit->SetPC(pc);
}
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index 1d9dcf5ff..fd1a44802 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -19,7 +19,7 @@ public:
void MapBackingMemory(VAddr address, size_t size, u8* memory,
Kernel::VMAPermission perms) override;
-
+ void UnmapMemory(u64 address, size_t size) override;
void SetPC(u64 pc) override;
u64 GetPC() const override;
u64 GetReg(int index) const override;
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index 5d2956bfd..162c766fd 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -77,6 +77,10 @@ void ARM_Unicorn::MapBackingMemory(VAddr address, size_t size, u8* memory,
CHECKED(uc_mem_map_ptr(uc, address, size, static_cast<u32>(perms), memory));
}
+void ARM_Unicorn::UnmapMemory(VAddr address, size_t size) {
+ CHECKED(uc_mem_unmap(uc, address, size));
+}
+
void ARM_Unicorn::SetPC(u64 pc) {
CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &pc));
}
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h
index c9a561dec..00b5b1865 100644
--- a/src/core/arm/unicorn/arm_unicorn.h
+++ b/src/core/arm/unicorn/arm_unicorn.h
@@ -14,6 +14,7 @@ public:
~ARM_Unicorn();
void MapBackingMemory(VAddr address, size_t size, u8* memory,
Kernel::VMAPermission perms) override;
+ void UnmapMemory(VAddr address, size_t size) override;
void SetPC(u64 pc) override;
u64 GetPC() const override;
u64 GetReg(int index) const override;
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index c77e58f3c..053bf4e17 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -33,10 +33,6 @@ enum class HandleType : u32 {
ServerSession,
};
-enum {
- DEFAULT_STACK_SIZE = 0x10000,
-};
-
enum class ResetType {
OneShot,
Sticky,
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 9ca2374ea..3694afc60 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -117,11 +117,12 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
}
void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
- // Allocate and map stack
+ // Allocate and map the main thread stack
+ // 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::HEAP_VADDR_END - stack_size,
- std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
- MemoryState::Heap)
+ .MapMemoryBlock(Memory::STACK_VADDR, std::make_shared<std::vector<u8>>(stack_size, 0), 0,
+ stack_size, MemoryState::Mapped)
.Unwrap();
misc_memory_used += stack_size;
memory_region->used += stack_size;
@@ -153,9 +154,9 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
};
// Map CodeSet segments
- MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::Code);
- MapSegment(module_->rodata, VMAPermission::Read, MemoryState::Static);
- MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::Static);
+ MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::CodeStatic);
+ MapSegment(module_->rodata, VMAPermission::Read, MemoryState::CodeMutable);
+ MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable);
}
VAddr Process::GetLinearHeapAreaAddress() const {
@@ -182,6 +183,8 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
// Initialize heap
heap_memory = std::make_shared<std::vector<u8>>();
heap_start = heap_end = target;
+ } else {
+ vm_manager.UnmapRange(heap_start, heap_end - heap_start);
}
// If necessary, expand backing vector to cover new heap extents.
@@ -201,7 +204,7 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
size, MemoryState::Heap));
vm_manager.Reprotect(vma, perms);
- heap_used += size;
+ heap_used = size;
memory_region->used += size;
return MakeResult<VAddr>(heap_end - size);
@@ -288,7 +291,7 @@ ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
CASCADE_RESULT(auto new_vma,
vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size,
- vma->second.meminfo_state));
+ MemoryState::Mapped));
// Protect mirror with permissions from old region
vm_manager.Reprotect(new_vma, vma->second.permissions);
// Remove permissions from old region
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 207583320..118ce3ee5 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -317,13 +317,13 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
*result = Core::CurrentProcess()->allowed_thread_priority_mask;
break;
case GetInfoType::MapRegionBaseAddr:
- *result = vm_manager.GetMapRegionBaseAddr();
+ *result = Memory::MAP_REGION_VADDR;
break;
case GetInfoType::MapRegionSize:
- *result = vm_manager.GetAddressSpaceSize();
+ *result = Memory::MAP_REGION_SIZE;
break;
case GetInfoType::HeapRegionBaseAddr:
- *result = vm_manager.GetNewMapRegionBaseAddr() + vm_manager.GetNewMapRegionSize();
+ *result = Memory::HEAP_VADDR;
break;
case GetInfoType::HeapRegionSize:
*result = Memory::HEAP_SIZE;
@@ -347,10 +347,10 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
*result = vm_manager.GetAddressSpaceSize();
break;
case GetInfoType::NewMapRegionBaseAddr:
- *result = vm_manager.GetNewMapRegionBaseAddr();
+ *result = Memory::NEW_MAP_REGION_VADDR;
break;
case GetInfoType::NewMapRegionSize:
- *result = vm_manager.GetNewMapRegionSize();
+ *result = Memory::NEW_MAP_REGION_SIZE;
break;
case GetInfoType::IsVirtualAddressMemoryEnabled:
*result = Core::CurrentProcess()->is_virtual_address_memory_enabled;
@@ -468,7 +468,7 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
memory_info->base_address = 0;
memory_info->permission = static_cast<u32>(VMAPermission::None);
memory_info->size = 0;
- memory_info->type = static_cast<u32>(MemoryState::Free);
+ memory_info->type = static_cast<u32>(MemoryState::Unmapped);
} else {
memory_info->base_address = vma->second.base;
memory_info->permission = static_cast<u32>(vma->second.permissions);
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 2394620eb..a39c53db5 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -314,7 +314,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
// TODO(Subv): Find the correct MemoryState for this region.
vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
linheap_memory, offset, Memory::PAGE_SIZE,
- MemoryState::ThreadLocalStorage);
+ MemoryState::ThreadLocal);
}
// Mark the slot as used
@@ -357,7 +357,7 @@ SharedPtr<Thread> SetupMainThread(VAddr entry_point, u32 priority,
// Initialize new "main" thread
auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0,
- Memory::HEAP_VADDR_END, owner_process);
+ Memory::STACK_VADDR_END, owner_process);
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index d5b36d71a..1c2f873aa 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -18,8 +18,26 @@ namespace Kernel {
static const char* GetMemoryStateName(MemoryState state) {
static const char* names[] = {
- "Free", "Reserved", "IO", "Static", "Code", "Private",
- "Shared", "Continuous", "Aliased", "Alias", "AliasCode", "Locked",
+ "Unmapped",
+ "Io",
+ "Normal",
+ "CodeStatic",
+ "CodeMutable",
+ "Heap",
+ "Shared",
+ "Unknown1"
+ "ModuleCodeStatic",
+ "ModuleCodeMutable",
+ "IpcBuffer0",
+ "Mapped",
+ "ThreadLocal",
+ "TransferMemoryIsolated",
+ "TransferMemory",
+ "ProcessMemory",
+ "Unknown2"
+ "IpcBuffer1",
+ "IpcBuffer3",
+ "KernelStack",
};
return names[(int)state];
@@ -142,7 +160,7 @@ VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) {
VirtualMemoryArea& vma = vma_handle->second;
vma.type = VMAType::Free;
vma.permissions = VMAPermission::None;
- vma.meminfo_state = MemoryState::Free;
+ vma.meminfo_state = MemoryState::Unmapped;
vma.backing_block = nullptr;
vma.offset = 0;
@@ -166,6 +184,9 @@ ResultCode VMManager::UnmapRange(VAddr target, u64 size) {
}
ASSERT(FindVMA(target)->second.size >= size);
+
+ Core::CPU().UnmapMemory(target, size);
+
return RESULT_SUCCESS;
}
@@ -377,19 +398,4 @@ u64 VMManager::GetAddressSpaceSize() {
return MAX_ADDRESS;
}
-VAddr VMManager::GetMapRegionBaseAddr() {
- LOG_WARNING(Kernel, "(STUBBED) called");
- return Memory::HEAP_VADDR;
-}
-
-VAddr VMManager::GetNewMapRegionBaseAddr() {
- LOG_WARNING(Kernel, "(STUBBED) called");
- return 0x8000000;
-}
-
-u64 VMManager::GetNewMapRegionSize() {
- LOG_WARNING(Kernel, "(STUBBED) called");
- return 0x8000000;
-}
-
} // namespace Kernel
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index 8de704a60..4d66146f6 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -41,15 +41,24 @@ enum class VMAPermission : u8 {
/// Set of values returned in MemoryInfo.state by svcQueryMemory.
enum class MemoryState : u32 {
- Free = 0,
- IO = 1,
- Normal = 2,
- Code = 3,
- Static = 4,
- Heap = 5,
- Shared = 6,
- Mapped = 6,
- ThreadLocalStorage = 12,
+ Unmapped = 0x0,
+ Io = 0x1,
+ Normal = 0x2,
+ CodeStatic = 0x3,
+ CodeMutable = 0x4,
+ Heap = 0x5,
+ Shared = 0x6,
+ ModuleCodeStatic = 0x8,
+ ModuleCodeMutable = 0x9,
+ IpcBuffer0 = 0xA,
+ Mapped = 0xB,
+ ThreadLocal = 0xC,
+ TransferMemoryIsolated = 0xD,
+ TransferMemory = 0xE,
+ ProcessMemory = 0xF,
+ IpcBuffer1 = 0x11,
+ IpcBuffer3 = 0x12,
+ KernelStack = 0x13,
};
/**
@@ -66,7 +75,7 @@ struct VirtualMemoryArea {
VMAType type = VMAType::Free;
VMAPermission permissions = VMAPermission::None;
/// Tag returned by svcQueryMemory. Not otherwise used.
- MemoryState meminfo_state = MemoryState::Free;
+ MemoryState meminfo_state = MemoryState::Unmapped;
// Settings for type = AllocatedMemoryBlock
/// Memory block backing this VMA.
@@ -192,15 +201,6 @@ public:
/// Gets the total address space address size, used by svcGetInfo
u64 GetAddressSpaceSize();
- /// Gets the map region base address, used by svcGetInfo
- VAddr GetMapRegionBaseAddr();
-
- /// Gets the base address for a new memory region, used by svcGetInfo
- VAddr GetNewMapRegionBaseAddr();
-
- /// Gets the size for a new memory region, used by svcGetInfo
- u64 GetNewMapRegionSize();
-
/// Each VMManager has its own page table, which is set as the main one when the owning process
/// is scheduled.
Memory::PageTable page_table;
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 164d52258..0ba8c6fd2 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -414,7 +414,7 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
- process->Run(codeset->entrypoint, 48, Kernel::DEFAULT_STACK_SIZE);
+ process->Run(codeset->entrypoint, 48, Memory::STACK_SIZE);
is_loaded = true;
return ResultStatus::Success;
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 0dc06ccea..6dcd1ce48 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -137,7 +137,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
process->address_mappings = default_address_mappings;
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
- process->Run(base_addr, 48, Kernel::DEFAULT_STACK_SIZE);
+ process->Run(base_addr, 48, Memory::STACK_SIZE);
is_loaded = true;
return ResultStatus::Success;
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index c0eeb95d3..100aa022e 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -165,7 +165,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
process->address_mappings = default_address_mappings;
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
- process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Kernel::DEFAULT_STACK_SIZE);
+ process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Memory::STACK_SIZE);
is_loaded = true;
return ResultStatus::Success;
diff --git a/src/core/memory.h b/src/core/memory.h
index f3ace7a98..f406cc848 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -129,21 +129,6 @@ enum : VAddr {
PROCESS_IMAGE_MAX_SIZE = 0x08000000,
PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE,
- /// Area where IPC buffers are mapped onto.
- IPC_MAPPING_VADDR = 0x04000000,
- IPC_MAPPING_SIZE = 0x04000000,
- IPC_MAPPING_VADDR_END = IPC_MAPPING_VADDR + IPC_MAPPING_SIZE,
-
- /// Application heap (includes stack).
- HEAP_VADDR = 0x108000000,
- HEAP_SIZE = 0xF0000000,
- HEAP_VADDR_END = HEAP_VADDR + HEAP_SIZE,
-
- /// Area where shared memory buffers are mapped onto.
- SHARED_MEMORY_VADDR = 0x10000000,
- SHARED_MEMORY_SIZE = 0x04000000,
- SHARED_MEMORY_VADDR_END = SHARED_MEMORY_VADDR + SHARED_MEMORY_SIZE,
-
/// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical
/// memory.
LINEAR_HEAP_VADDR = 0x14000000,
@@ -176,14 +161,39 @@ enum : VAddr {
SHARED_PAGE_SIZE = 0x00001000,
SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
- /// Area where TLS (Thread-Local Storage) buffers are allocated.
- TLS_AREA_VADDR = 0x228000000,
- TLS_ENTRY_SIZE = 0x200,
-
/// Equivalent to LINEAR_HEAP_VADDR, but expanded to cover the extra memory in the New 3DS.
NEW_LINEAR_HEAP_VADDR = 0x30000000,
NEW_LINEAR_HEAP_SIZE = 0x10000000,
NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE,
+
+ /// Area where TLS (Thread-Local Storage) buffers are allocated.
+ TLS_AREA_VADDR = NEW_LINEAR_HEAP_VADDR_END,
+ TLS_ENTRY_SIZE = 0x200,
+ TLS_AREA_SIZE = 0x10000000,
+ TLS_ADREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE,
+
+ /// Application stack
+ STACK_VADDR = TLS_ADREA_VADDR_END,
+ STACK_SIZE = 0x10000,
+ STACK_VADDR_END = STACK_VADDR + STACK_SIZE,
+
+ /// Application heap
+ /// Size is confirmed to be a static value on fw 3.0.0
+ HEAP_VADDR = 0x108000000,
+ HEAP_SIZE = 0x180000000,
+ HEAP_VADDR_END = HEAP_VADDR + HEAP_SIZE,
+
+ /// New map region
+ /// Size is confirmed to be a static value on fw 3.0.0
+ NEW_MAP_REGION_VADDR = HEAP_VADDR_END,
+ NEW_MAP_REGION_SIZE = 0x80000000,
+ NEW_MAP_REGION_VADDR_END = NEW_MAP_REGION_VADDR + NEW_MAP_REGION_SIZE,
+
+ /// Map region
+ /// Size is confirmed to be a static value on fw 3.0.0
+ MAP_REGION_VADDR = NEW_MAP_REGION_VADDR_END,
+ MAP_REGION_SIZE = 0x1000000000,
+ MAP_REGION_VADDR_END = MAP_REGION_VADDR + MAP_REGION_SIZE,
};
/// Currently active page table