core: arm: Implement InvalidateCacheRange for CPU cache invalidation.
This commit is contained in:
		
							parent
							
								
									c0870315fd
								
							
						
					
					
						commit
						63fd1bb503
					
				| @ -70,12 +70,19 @@ public: | |||||||
|     /// Clear all instruction cache
 |     /// Clear all instruction cache
 | ||||||
|     virtual void ClearInstructionCache() = 0; |     virtual void ClearInstructionCache() = 0; | ||||||
| 
 | 
 | ||||||
|     /// Notifies CPU emulation that the current page table has changed.
 |     /**
 | ||||||
|     ///
 |      * Clear instruction cache range | ||||||
|     /// @param new_page_table                 The new page table.
 |      * @param addr Start address of the cache range to clear | ||||||
|     /// @param new_address_space_size_in_bits The new usable size of the address space in bits.
 |      * @param size Size of the cache range to clear, starting at addr | ||||||
|     ///                                       This can be either 32, 36, or 39 on official software.
 |      */ | ||||||
|     ///
 |     virtual void InvalidateCacheRange(VAddr addr, std::size_t size) = 0; | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Notifies CPU emulation that the current page table has changed. | ||||||
|  |      *  @param new_page_table                 The new page table. | ||||||
|  |      *  @param new_address_space_size_in_bits The new usable size of the address space in bits. | ||||||
|  |      *                                        This can be either 32, 36, or 39 on official software. | ||||||
|  |      */ | ||||||
|     virtual void PageTableChanged(Common::PageTable& new_page_table, |     virtual void PageTableChanged(Common::PageTable& new_page_table, | ||||||
|                                   std::size_t new_address_space_size_in_bits) = 0; |                                   std::size_t new_address_space_size_in_bits) = 0; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -286,6 +286,13 @@ void ARM_Dynarmic_32::ClearInstructionCache() { | |||||||
|     jit->ClearCache(); |     jit->ClearCache(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void ARM_Dynarmic_32::InvalidateCacheRange(VAddr addr, std::size_t size) { | ||||||
|  |     if (!jit) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     jit->InvalidateCacheRange(static_cast<u32>(addr), size); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ARM_Dynarmic_32::ClearExclusiveState() { | void ARM_Dynarmic_32::ClearExclusiveState() { | ||||||
|     jit->ClearExclusiveState(); |     jit->ClearExclusiveState(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -59,6 +59,7 @@ public: | |||||||
|     void ClearExclusiveState() override; |     void ClearExclusiveState() override; | ||||||
| 
 | 
 | ||||||
|     void ClearInstructionCache() override; |     void ClearInstructionCache() override; | ||||||
|  |     void InvalidateCacheRange(VAddr addr, std::size_t size) override; | ||||||
|     void PageTableChanged(Common::PageTable& new_page_table, |     void PageTableChanged(Common::PageTable& new_page_table, | ||||||
|                           std::size_t new_address_space_size_in_bits) override; |                           std::size_t new_address_space_size_in_bits) override; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -322,6 +322,13 @@ void ARM_Dynarmic_64::ClearInstructionCache() { | |||||||
|     jit->ClearCache(); |     jit->ClearCache(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void ARM_Dynarmic_64::InvalidateCacheRange(VAddr addr, std::size_t size) { | ||||||
|  |     if (!jit) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     jit->InvalidateCacheRange(addr, size); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ARM_Dynarmic_64::ClearExclusiveState() { | void ARM_Dynarmic_64::ClearExclusiveState() { | ||||||
|     jit->ClearExclusiveState(); |     jit->ClearExclusiveState(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -56,6 +56,7 @@ public: | |||||||
|     void ClearExclusiveState() override; |     void ClearExclusiveState() override; | ||||||
| 
 | 
 | ||||||
|     void ClearInstructionCache() override; |     void ClearInstructionCache() override; | ||||||
|  |     void InvalidateCacheRange(VAddr addr, std::size_t size) override; | ||||||
|     void PageTableChanged(Common::PageTable& new_page_table, |     void PageTableChanged(Common::PageTable& new_page_table, | ||||||
|                           std::size_t new_address_space_size_in_bits) override; |                           std::size_t new_address_space_size_in_bits) override; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -457,6 +457,10 @@ void System::InvalidateCpuInstructionCaches() { | |||||||
|     impl->kernel.InvalidateAllInstructionCaches(); |     impl->kernel.InvalidateAllInstructionCaches(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void System::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) { | ||||||
|  |     impl->kernel.InvalidateCpuInstructionCacheRange(addr, size); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void System::Shutdown() { | void System::Shutdown() { | ||||||
|     impl->Shutdown(); |     impl->Shutdown(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -166,6 +166,8 @@ public: | |||||||
|      */ |      */ | ||||||
|     void InvalidateCpuInstructionCaches(); |     void InvalidateCpuInstructionCaches(); | ||||||
| 
 | 
 | ||||||
|  |     void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); | ||||||
|  | 
 | ||||||
|     /// Shutdown the emulated system.
 |     /// Shutdown the emulated system.
 | ||||||
|     void Shutdown(); |     void Shutdown(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -497,12 +497,17 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void KernelCore::InvalidateAllInstructionCaches() { | void KernelCore::InvalidateAllInstructionCaches() { | ||||||
|     if (!IsMulticore()) { |     for (auto& physical_core : impl->cores) { | ||||||
|         for (auto& physical_core : impl->cores) { |         physical_core.ArmInterface().ClearInstructionCache(); | ||||||
|             physical_core.ArmInterface().ClearInstructionCache(); |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void KernelCore::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) { | ||||||
|  |     for (auto& physical_core : impl->cores) { | ||||||
|  |         if (!physical_core.IsInitialized()) { | ||||||
|  |             continue; | ||||||
|         } |         } | ||||||
|     } else { |         physical_core.ArmInterface().InvalidateCacheRange(addr, size); | ||||||
|         UNIMPLEMENTED(); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -156,6 +156,8 @@ public: | |||||||
| 
 | 
 | ||||||
|     void InvalidateAllInstructionCaches(); |     void InvalidateAllInstructionCaches(); | ||||||
| 
 | 
 | ||||||
|  |     void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); | ||||||
|  | 
 | ||||||
|     /// Adds a port to the named port table
 |     /// Adds a port to the named port table
 | ||||||
|     void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port); |     void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -670,6 +670,11 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo | |||||||
|         return RESULT_SUCCESS; |         return RESULT_SUCCESS; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if ((prev_perm & MemoryPermission::Execute) != (perm & MemoryPermission::Execute)) { | ||||||
|  |         // Memory execution state is changing, invalidate CPU cache range
 | ||||||
|  |         system.InvalidateCpuInstructionCacheRange(addr, size); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     const std::size_t num_pages{size / PageSize}; |     const std::size_t num_pages{size / PageSize}; | ||||||
|     const OperationType operation{(perm & MemoryPermission::Execute) != MemoryPermission::None |     const OperationType operation{(perm & MemoryPermission::Execute) != MemoryPermission::None | ||||||
|                                       ? OperationType::ChangePermissionsAndRefresh |                                       ? OperationType::ChangePermissionsAndRefresh | ||||||
|  | |||||||
| @ -58,6 +58,10 @@ public: | |||||||
|     // Shutdown this physical core.
 |     // Shutdown this physical core.
 | ||||||
|     void Shutdown(); |     void Shutdown(); | ||||||
| 
 | 
 | ||||||
|  |     bool IsInitialized() const { | ||||||
|  |         return arm_interface != nullptr; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     Core::ARM_Interface& ArmInterface() { |     Core::ARM_Interface& ArmInterface() { | ||||||
|         return *arm_interface; |         return *arm_interface; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -527,9 +527,6 @@ public: | |||||||
|                                      header.segment_headers[RO_INDEX].memory_size, |                                      header.segment_headers[RO_INDEX].memory_size, | ||||||
|                                      header.segment_headers[DATA_INDEX].memory_size, nro_address}); |                                      header.segment_headers[DATA_INDEX].memory_size, nro_address}); | ||||||
| 
 | 
 | ||||||
|         // Invalidate JIT caches for the newly mapped process code
 |  | ||||||
|         system.InvalidateCpuInstructionCaches(); |  | ||||||
| 
 |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 4}; |         IPC::ResponseBuilder rb{ctx, 4}; | ||||||
|         rb.Push(RESULT_SUCCESS); |         rb.Push(RESULT_SUCCESS); | ||||||
|         rb.Push(*map_result); |         rb.Push(*map_result); | ||||||
| @ -590,8 +587,6 @@ public: | |||||||
| 
 | 
 | ||||||
|         const auto result{UnmapNro(iter->second)}; |         const auto result{UnmapNro(iter->second)}; | ||||||
| 
 | 
 | ||||||
|         system.InvalidateCpuInstructionCaches(); |  | ||||||
| 
 |  | ||||||
|         nro.erase(iter); |         nro.erase(iter); | ||||||
| 
 | 
 | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |         IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei