mirror of
https://github.com/PabloMK7/citra.git
synced 2024-11-25 17:04:04 +00:00
Memory: Added a function to change the memory state of an address range.
This will be useful when implementing memory aliasing operations.
This commit is contained in:
parent
44d07574b1
commit
e4f35f70ac
2 changed files with 49 additions and 1 deletions
|
@ -129,6 +129,39 @@ ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u3
|
|||
return MakeResult<VMAHandle>(MergeAdjacent(vma_handle));
|
||||
}
|
||||
|
||||
ResultCode VMManager::ChangeMemoryState(VAddr target, u32 size, MemoryState expected_state,
|
||||
VMAPermission expected_perms, MemoryState new_state,
|
||||
VMAPermission new_perms) {
|
||||
VAddr target_end = target + size;
|
||||
VMAIter begin_vma = StripIterConstness(FindVMA(target));
|
||||
VMAIter i_end = vma_map.lower_bound(target_end);
|
||||
|
||||
if (begin_vma == vma_map.end())
|
||||
return ERR_INVALID_ADDRESS;
|
||||
|
||||
for (auto i = begin_vma; i != i_end; ++i) {
|
||||
auto& vma = i->second;
|
||||
if (vma.meminfo_state != expected_state) {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
}
|
||||
u32 perms = static_cast<u32>(expected_perms);
|
||||
if ((static_cast<u32>(vma.permissions) & perms) != perms) {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
CASCADE_RESULT(auto vma, CarveVMARange(target, size));
|
||||
ASSERT(vma->second.size == size);
|
||||
|
||||
vma->second.permissions = new_perms;
|
||||
vma->second.meminfo_state = new_state;
|
||||
UpdatePageTableForVMA(vma->second);
|
||||
|
||||
MergeAdjacent(vma);
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) {
|
||||
VirtualMemoryArea& vma = vma_handle->second;
|
||||
vma.type = VMAType::Free;
|
||||
|
|
|
@ -166,6 +166,21 @@ public:
|
|||
ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state,
|
||||
Memory::MMIORegionPointer mmio_handler);
|
||||
|
||||
/**
|
||||
* Updates the memory state and permissions of the specified range. The range's original memory
|
||||
* state and permissions must match the `expected` parameters.
|
||||
*
|
||||
* @param target The guest address of the beginning of the range.
|
||||
* @param size The size of the range
|
||||
* @param expected_state Expected MemoryState of the range.
|
||||
* @param expected_perms Expected VMAPermission of the range.
|
||||
* @param new_state New MemoryState for the range.
|
||||
* @param new_perms New VMAPermission for the range.
|
||||
*/
|
||||
ResultCode ChangeMemoryState(VAddr target, u32 size, MemoryState expected_state,
|
||||
VMAPermission expected_perms, MemoryState new_state,
|
||||
VMAPermission new_perms);
|
||||
|
||||
/// Unmaps a range of addresses, splitting VMAs as necessary.
|
||||
ResultCode UnmapRange(VAddr target, u32 size);
|
||||
|
||||
|
@ -224,4 +239,4 @@ private:
|
|||
/// Updates the pages corresponding to this VMA so they match the VMA's attributes.
|
||||
void UpdatePageTableForVMA(const VirtualMemoryArea& vma);
|
||||
};
|
||||
}
|
||||
} // namespace Kernel
|
||||
|
|
Loading…
Reference in a new issue