mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30: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)); |     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) { | 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; | ||||||
|  |  | ||||||
|  | @ -166,6 +166,21 @@ public: | ||||||
|     ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, |     ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, | ||||||
|                                  Memory::MMIORegionPointer mmio_handler); |                                  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.
 |     /// Unmaps a range of addresses, splitting VMAs as necessary.
 | ||||||
|     ResultCode UnmapRange(VAddr target, u32 size); |     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.
 |     /// Updates the pages corresponding to this VMA so they match the VMA's attributes.
 | ||||||
|     void UpdatePageTableForVMA(const VirtualMemoryArea& vma); |     void UpdatePageTableForVMA(const VirtualMemoryArea& vma); | ||||||
| }; | }; | ||||||
| } | } // namespace Kernel
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue