Merge pull request #232 from bunnei/heap-fixes
Various heap fixes for libtransistor
This commit is contained in:
commit
e7ba2a4447
|
@ -39,8 +39,12 @@ public:
|
||||||
Run(1);
|
Run(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Maps a backing memory region for the CPU
|
||||||
virtual void MapBackingMemory(VAddr address, size_t size, u8* memory,
|
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
|
/// Clear all instruction cache
|
||||||
virtual void ClearInstructionCache() = 0;
|
virtual void ClearInstructionCache() = 0;
|
||||||
|
|
|
@ -136,6 +136,10 @@ void ARM_Dynarmic::MapBackingMemory(u64 address, size_t size, u8* memory,
|
||||||
inner_unicorn.MapBackingMemory(address, size, memory, perms);
|
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) {
|
void ARM_Dynarmic::SetPC(u64 pc) {
|
||||||
jit->SetPC(pc);
|
jit->SetPC(pc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ public:
|
||||||
|
|
||||||
void MapBackingMemory(VAddr address, size_t size, u8* memory,
|
void MapBackingMemory(VAddr address, size_t size, u8* memory,
|
||||||
Kernel::VMAPermission perms) override;
|
Kernel::VMAPermission perms) override;
|
||||||
|
void UnmapMemory(u64 address, size_t size) override;
|
||||||
void SetPC(u64 pc) override;
|
void SetPC(u64 pc) override;
|
||||||
u64 GetPC() const override;
|
u64 GetPC() const override;
|
||||||
u64 GetReg(int index) const override;
|
u64 GetReg(int index) const override;
|
||||||
|
|
|
@ -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));
|
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) {
|
void ARM_Unicorn::SetPC(u64 pc) {
|
||||||
CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &pc));
|
CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &pc));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ public:
|
||||||
~ARM_Unicorn();
|
~ARM_Unicorn();
|
||||||
void MapBackingMemory(VAddr address, size_t size, u8* memory,
|
void MapBackingMemory(VAddr address, size_t size, u8* memory,
|
||||||
Kernel::VMAPermission perms) override;
|
Kernel::VMAPermission perms) override;
|
||||||
|
void UnmapMemory(VAddr address, size_t size) override;
|
||||||
void SetPC(u64 pc) override;
|
void SetPC(u64 pc) override;
|
||||||
u64 GetPC() const override;
|
u64 GetPC() const override;
|
||||||
u64 GetReg(int index) const override;
|
u64 GetReg(int index) const override;
|
||||||
|
|
|
@ -33,10 +33,6 @@ enum class HandleType : u32 {
|
||||||
ServerSession,
|
ServerSession,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
DEFAULT_STACK_SIZE = 0x10000,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ResetType {
|
enum class ResetType {
|
||||||
OneShot,
|
OneShot,
|
||||||
Sticky,
|
Sticky,
|
||||||
|
|
|
@ -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) {
|
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
|
vm_manager
|
||||||
.MapMemoryBlock(Memory::HEAP_VADDR_END - stack_size,
|
.MapMemoryBlock(Memory::STACK_VADDR, std::make_shared<std::vector<u8>>(stack_size, 0), 0,
|
||||||
std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
|
stack_size, MemoryState::Mapped)
|
||||||
MemoryState::Heap)
|
|
||||||
.Unwrap();
|
.Unwrap();
|
||||||
misc_memory_used += stack_size;
|
misc_memory_used += stack_size;
|
||||||
memory_region->used += stack_size;
|
memory_region->used += stack_size;
|
||||||
|
@ -153,9 +154,9 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Map CodeSet segments
|
// Map CodeSet segments
|
||||||
MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::Code);
|
MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::CodeStatic);
|
||||||
MapSegment(module_->rodata, VMAPermission::Read, MemoryState::Static);
|
MapSegment(module_->rodata, VMAPermission::Read, MemoryState::CodeMutable);
|
||||||
MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::Static);
|
MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable);
|
||||||
}
|
}
|
||||||
|
|
||||||
VAddr Process::GetLinearHeapAreaAddress() const {
|
VAddr Process::GetLinearHeapAreaAddress() const {
|
||||||
|
@ -182,6 +183,8 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
|
||||||
// Initialize heap
|
// Initialize heap
|
||||||
heap_memory = std::make_shared<std::vector<u8>>();
|
heap_memory = std::make_shared<std::vector<u8>>();
|
||||||
heap_start = heap_end = target;
|
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.
|
// 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));
|
size, MemoryState::Heap));
|
||||||
vm_manager.Reprotect(vma, perms);
|
vm_manager.Reprotect(vma, perms);
|
||||||
|
|
||||||
heap_used += size;
|
heap_used = size;
|
||||||
memory_region->used += size;
|
memory_region->used += size;
|
||||||
|
|
||||||
return MakeResult<VAddr>(heap_end - 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,
|
CASCADE_RESULT(auto new_vma,
|
||||||
vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size,
|
vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size,
|
||||||
vma->second.meminfo_state));
|
MemoryState::Mapped));
|
||||||
// Protect mirror with permissions from old region
|
// Protect mirror with permissions from old region
|
||||||
vm_manager.Reprotect(new_vma, vma->second.permissions);
|
vm_manager.Reprotect(new_vma, vma->second.permissions);
|
||||||
// Remove permissions from old region
|
// Remove permissions from old region
|
||||||
|
|
|
@ -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;
|
*result = Core::CurrentProcess()->allowed_thread_priority_mask;
|
||||||
break;
|
break;
|
||||||
case GetInfoType::MapRegionBaseAddr:
|
case GetInfoType::MapRegionBaseAddr:
|
||||||
*result = vm_manager.GetMapRegionBaseAddr();
|
*result = Memory::MAP_REGION_VADDR;
|
||||||
break;
|
break;
|
||||||
case GetInfoType::MapRegionSize:
|
case GetInfoType::MapRegionSize:
|
||||||
*result = vm_manager.GetAddressSpaceSize();
|
*result = Memory::MAP_REGION_SIZE;
|
||||||
break;
|
break;
|
||||||
case GetInfoType::HeapRegionBaseAddr:
|
case GetInfoType::HeapRegionBaseAddr:
|
||||||
*result = vm_manager.GetNewMapRegionBaseAddr() + vm_manager.GetNewMapRegionSize();
|
*result = Memory::HEAP_VADDR;
|
||||||
break;
|
break;
|
||||||
case GetInfoType::HeapRegionSize:
|
case GetInfoType::HeapRegionSize:
|
||||||
*result = Memory::HEAP_SIZE;
|
*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();
|
*result = vm_manager.GetAddressSpaceSize();
|
||||||
break;
|
break;
|
||||||
case GetInfoType::NewMapRegionBaseAddr:
|
case GetInfoType::NewMapRegionBaseAddr:
|
||||||
*result = vm_manager.GetNewMapRegionBaseAddr();
|
*result = Memory::NEW_MAP_REGION_VADDR;
|
||||||
break;
|
break;
|
||||||
case GetInfoType::NewMapRegionSize:
|
case GetInfoType::NewMapRegionSize:
|
||||||
*result = vm_manager.GetNewMapRegionSize();
|
*result = Memory::NEW_MAP_REGION_SIZE;
|
||||||
break;
|
break;
|
||||||
case GetInfoType::IsVirtualAddressMemoryEnabled:
|
case GetInfoType::IsVirtualAddressMemoryEnabled:
|
||||||
*result = Core::CurrentProcess()->is_virtual_address_memory_enabled;
|
*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->base_address = 0;
|
||||||
memory_info->permission = static_cast<u32>(VMAPermission::None);
|
memory_info->permission = static_cast<u32>(VMAPermission::None);
|
||||||
memory_info->size = 0;
|
memory_info->size = 0;
|
||||||
memory_info->type = static_cast<u32>(MemoryState::Free);
|
memory_info->type = static_cast<u32>(MemoryState::Unmapped);
|
||||||
} else {
|
} else {
|
||||||
memory_info->base_address = vma->second.base;
|
memory_info->base_address = vma->second.base;
|
||||||
memory_info->permission = static_cast<u32>(vma->second.permissions);
|
memory_info->permission = static_cast<u32>(vma->second.permissions);
|
||||||
|
|
|
@ -314,7 +314,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
|
||||||
// TODO(Subv): Find the correct MemoryState for this region.
|
// TODO(Subv): Find the correct MemoryState for this region.
|
||||||
vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
|
vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
|
||||||
linheap_memory, offset, Memory::PAGE_SIZE,
|
linheap_memory, offset, Memory::PAGE_SIZE,
|
||||||
MemoryState::ThreadLocalStorage);
|
MemoryState::ThreadLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the slot as used
|
// Mark the slot as used
|
||||||
|
@ -357,7 +357,7 @@ SharedPtr<Thread> SetupMainThread(VAddr entry_point, u32 priority,
|
||||||
|
|
||||||
// Initialize new "main" thread
|
// Initialize new "main" thread
|
||||||
auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0,
|
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();
|
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,26 @@ namespace Kernel {
|
||||||
|
|
||||||
static const char* GetMemoryStateName(MemoryState state) {
|
static const char* GetMemoryStateName(MemoryState state) {
|
||||||
static const char* names[] = {
|
static const char* names[] = {
|
||||||
"Free", "Reserved", "IO", "Static", "Code", "Private",
|
"Unmapped",
|
||||||
"Shared", "Continuous", "Aliased", "Alias", "AliasCode", "Locked",
|
"Io",
|
||||||
|
"Normal",
|
||||||
|
"CodeStatic",
|
||||||
|
"CodeMutable",
|
||||||
|
"Heap",
|
||||||
|
"Shared",
|
||||||
|
"Unknown1"
|
||||||
|
"ModuleCodeStatic",
|
||||||
|
"ModuleCodeMutable",
|
||||||
|
"IpcBuffer0",
|
||||||
|
"Mapped",
|
||||||
|
"ThreadLocal",
|
||||||
|
"TransferMemoryIsolated",
|
||||||
|
"TransferMemory",
|
||||||
|
"ProcessMemory",
|
||||||
|
"Unknown2"
|
||||||
|
"IpcBuffer1",
|
||||||
|
"IpcBuffer3",
|
||||||
|
"KernelStack",
|
||||||
};
|
};
|
||||||
|
|
||||||
return names[(int)state];
|
return names[(int)state];
|
||||||
|
@ -142,7 +160,7 @@ VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) {
|
||||||
VirtualMemoryArea& vma = vma_handle->second;
|
VirtualMemoryArea& vma = vma_handle->second;
|
||||||
vma.type = VMAType::Free;
|
vma.type = VMAType::Free;
|
||||||
vma.permissions = VMAPermission::None;
|
vma.permissions = VMAPermission::None;
|
||||||
vma.meminfo_state = MemoryState::Free;
|
vma.meminfo_state = MemoryState::Unmapped;
|
||||||
|
|
||||||
vma.backing_block = nullptr;
|
vma.backing_block = nullptr;
|
||||||
vma.offset = 0;
|
vma.offset = 0;
|
||||||
|
@ -166,6 +184,9 @@ ResultCode VMManager::UnmapRange(VAddr target, u64 size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(FindVMA(target)->second.size >= size);
|
ASSERT(FindVMA(target)->second.size >= size);
|
||||||
|
|
||||||
|
Core::CPU().UnmapMemory(target, size);
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,19 +398,4 @@ u64 VMManager::GetAddressSpaceSize() {
|
||||||
return MAX_ADDRESS;
|
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
|
} // namespace Kernel
|
||||||
|
|
|
@ -41,15 +41,24 @@ enum class VMAPermission : u8 {
|
||||||
|
|
||||||
/// Set of values returned in MemoryInfo.state by svcQueryMemory.
|
/// Set of values returned in MemoryInfo.state by svcQueryMemory.
|
||||||
enum class MemoryState : u32 {
|
enum class MemoryState : u32 {
|
||||||
Free = 0,
|
Unmapped = 0x0,
|
||||||
IO = 1,
|
Io = 0x1,
|
||||||
Normal = 2,
|
Normal = 0x2,
|
||||||
Code = 3,
|
CodeStatic = 0x3,
|
||||||
Static = 4,
|
CodeMutable = 0x4,
|
||||||
Heap = 5,
|
Heap = 0x5,
|
||||||
Shared = 6,
|
Shared = 0x6,
|
||||||
Mapped = 6,
|
ModuleCodeStatic = 0x8,
|
||||||
ThreadLocalStorage = 12,
|
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;
|
VMAType type = VMAType::Free;
|
||||||
VMAPermission permissions = VMAPermission::None;
|
VMAPermission permissions = VMAPermission::None;
|
||||||
/// Tag returned by svcQueryMemory. Not otherwise used.
|
/// Tag returned by svcQueryMemory. Not otherwise used.
|
||||||
MemoryState meminfo_state = MemoryState::Free;
|
MemoryState meminfo_state = MemoryState::Unmapped;
|
||||||
|
|
||||||
// Settings for type = AllocatedMemoryBlock
|
// Settings for type = AllocatedMemoryBlock
|
||||||
/// Memory block backing this VMA.
|
/// Memory block backing this VMA.
|
||||||
|
@ -192,15 +201,6 @@ public:
|
||||||
/// Gets the total address space address size, used by svcGetInfo
|
/// Gets the total address space address size, used by svcGetInfo
|
||||||
u64 GetAddressSpaceSize();
|
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
|
/// Each VMManager has its own page table, which is set as the main one when the owning process
|
||||||
/// is scheduled.
|
/// is scheduled.
|
||||||
Memory::PageTable page_table;
|
Memory::PageTable page_table;
|
||||||
|
|
|
@ -414,7 +414,7 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
|
||||||
process->resource_limit =
|
process->resource_limit =
|
||||||
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
|
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;
|
is_loaded = true;
|
||||||
return ResultStatus::Success;
|
return ResultStatus::Success;
|
||||||
|
|
|
@ -137,7 +137,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
|
||||||
process->address_mappings = default_address_mappings;
|
process->address_mappings = default_address_mappings;
|
||||||
process->resource_limit =
|
process->resource_limit =
|
||||||
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
|
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;
|
is_loaded = true;
|
||||||
return ResultStatus::Success;
|
return ResultStatus::Success;
|
||||||
|
|
|
@ -165,7 +165,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
|
||||||
process->address_mappings = default_address_mappings;
|
process->address_mappings = default_address_mappings;
|
||||||
process->resource_limit =
|
process->resource_limit =
|
||||||
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
|
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;
|
is_loaded = true;
|
||||||
return ResultStatus::Success;
|
return ResultStatus::Success;
|
||||||
|
|
|
@ -129,21 +129,6 @@ enum : VAddr {
|
||||||
PROCESS_IMAGE_MAX_SIZE = 0x08000000,
|
PROCESS_IMAGE_MAX_SIZE = 0x08000000,
|
||||||
PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE,
|
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
|
/// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical
|
||||||
/// memory.
|
/// memory.
|
||||||
LINEAR_HEAP_VADDR = 0x14000000,
|
LINEAR_HEAP_VADDR = 0x14000000,
|
||||||
|
@ -176,14 +161,39 @@ enum : VAddr {
|
||||||
SHARED_PAGE_SIZE = 0x00001000,
|
SHARED_PAGE_SIZE = 0x00001000,
|
||||||
SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
|
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.
|
/// Equivalent to LINEAR_HEAP_VADDR, but expanded to cover the extra memory in the New 3DS.
|
||||||
NEW_LINEAR_HEAP_VADDR = 0x30000000,
|
NEW_LINEAR_HEAP_VADDR = 0x30000000,
|
||||||
NEW_LINEAR_HEAP_SIZE = 0x10000000,
|
NEW_LINEAR_HEAP_SIZE = 0x10000000,
|
||||||
NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE,
|
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
|
/// Currently active page table
|
||||||
|
|
Reference in New Issue