mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-31 18:54:14 +01:00 
			
		
		
		
	Address more review comments
This commit is contained in:
		
							parent
							
								
									d040b27a35
								
							
						
					
					
						commit
						9ff8d0f3e6
					
				| @ -82,8 +82,8 @@ abstract class SettingsItem( | |||||||
|                     IntSetting.CPU_BACKEND, |                     IntSetting.CPU_BACKEND, | ||||||
|                     R.string.cpu_backend, |                     R.string.cpu_backend, | ||||||
|                     0, |                     0, | ||||||
|                     R.array.cpuBackendNames, |                     R.array.cpuBackendArm64Names, | ||||||
|                     R.array.cpuBackendValues |                     R.array.cpuBackendArm64Values | ||||||
|                 ) |                 ) | ||||||
|             ) |             ) | ||||||
|             put( |             put( | ||||||
|  | |||||||
| @ -175,16 +175,24 @@ | |||||||
|         <item>2</item> |         <item>2</item> | ||||||
|     </integer-array> |     </integer-array> | ||||||
| 
 | 
 | ||||||
|     <string-array name="cpuBackendNames"> |     <string-array name="cpuBackendArm64Names"> | ||||||
|         <item>@string/cpu_backend_dynarmic</item> |         <item>@string/cpu_backend_dynarmic</item> | ||||||
|         <item>@string/cpu_backend_nce</item> |         <item>@string/cpu_backend_nce</item> | ||||||
|     </string-array> |     </string-array> | ||||||
| 
 | 
 | ||||||
|     <integer-array name="cpuBackendValues"> |     <integer-array name="cpuBackendArm64Values"> | ||||||
|         <item>0</item> |         <item>0</item> | ||||||
|         <item>1</item> |         <item>1</item> | ||||||
|     </integer-array> |     </integer-array> | ||||||
| 
 | 
 | ||||||
|  |     <string-array name="cpuBackendX86Names"> | ||||||
|  |         <item>@string/cpu_backend_dynarmic</item> | ||||||
|  |     </string-array> | ||||||
|  | 
 | ||||||
|  |     <integer-array name="cpuBackendX86Values"> | ||||||
|  |         <item>0</item> | ||||||
|  |     </integer-array> | ||||||
|  | 
 | ||||||
|     <string-array name="cpuAccuracyNames"> |     <string-array name="cpuAccuracyNames"> | ||||||
|         <item>@string/auto</item> |         <item>@string/auto</item> | ||||||
|         <item>@string/cpu_accuracy_accurate</item> |         <item>@string/cpu_accuracy_accurate</item> | ||||||
|  | |||||||
| @ -185,7 +185,7 @@ | |||||||
|     <string name="frame_limit_enable_description">Limits emulation speed to a specified percentage of normal speed.</string> |     <string name="frame_limit_enable_description">Limits emulation speed to a specified percentage of normal speed.</string> | ||||||
|     <string name="frame_limit_slider">Limit speed percent</string> |     <string name="frame_limit_slider">Limit speed percent</string> | ||||||
|     <string name="frame_limit_slider_description">Specifies the percentage to limit emulation speed. 100% is the normal speed. Values higher or lower will increase or decrease the speed limit.</string> |     <string name="frame_limit_slider_description">Specifies the percentage to limit emulation speed. 100% is the normal speed. Values higher or lower will increase or decrease the speed limit.</string> | ||||||
|     <string name="cpu_backend">CPU Backend</string> |     <string name="cpu_backend">CPU backend</string> | ||||||
|     <string name="cpu_accuracy">CPU accuracy</string> |     <string name="cpu_accuracy">CPU accuracy</string> | ||||||
|     <string name="value_with_units">%1$s%2$s</string> |     <string name="value_with_units">%1$s%2$s</string> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -90,6 +90,10 @@ void Patcher::PatchText(const Kernel::PhysicalMemory& program_image, | |||||||
|             WriteMsrHandler(AddRelocations(), oaknut::XReg{static_cast<int>(msr.GetRt())}); |             WriteMsrHandler(AddRelocations(), oaknut::XReg{static_cast<int>(msr.GetRt())}); | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         if (auto exclusive = Exclusive{inst}; exclusive.Verify()) { | ||||||
|  |             m_exclusives.push_back(i); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Determine patching mode for the final relocation step
 |     // Determine patching mode for the final relocation step
 | ||||||
| @ -163,11 +167,9 @@ void Patcher::RelocateAndCopy(Common::ProcessAddress load_base, | |||||||
| 
 | 
 | ||||||
|     // Cortex-A57 seems to treat all exclusives as ordered, but newer processors do not.
 |     // Cortex-A57 seems to treat all exclusives as ordered, but newer processors do not.
 | ||||||
|     // Convert to ordered to preserve this assumption.
 |     // Convert to ordered to preserve this assumption.
 | ||||||
|     for (u32 i = ModuleCodeIndex; i < static_cast<u32>(text_words.size()); i++) { |     for (const ModuleTextAddress i : m_exclusives) { | ||||||
|         const u32 inst = text_words[i]; |         auto exclusive = Exclusive{text_words[i]}; | ||||||
|         if (auto exclusive = Exclusive{inst}; exclusive.Verify()) { |         text_words[i] = exclusive.AsOrdered(); | ||||||
|             text_words[i] = exclusive.AsOrdered(); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Copy to program image
 |     // Copy to program image
 | ||||||
|  | |||||||
| @ -93,6 +93,7 @@ private: | |||||||
|     std::vector<Relocation> m_branch_to_patch_relocations{}; |     std::vector<Relocation> m_branch_to_patch_relocations{}; | ||||||
|     std::vector<Relocation> m_branch_to_module_relocations{}; |     std::vector<Relocation> m_branch_to_module_relocations{}; | ||||||
|     std::vector<Relocation> m_write_module_pc_relocations{}; |     std::vector<Relocation> m_write_module_pc_relocations{}; | ||||||
|  |     std::vector<ModuleTextAddress> m_exclusives{}; | ||||||
|     oaknut::Label m_save_context{}; |     oaknut::Label m_save_context{}; | ||||||
|     oaknut::Label m_load_context{}; |     oaknut::Label m_load_context{}; | ||||||
|     PatchMode mode{PatchMode::None}; |     PatchMode mode{PatchMode::None}; | ||||||
|  | |||||||
| @ -5678,15 +5678,8 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a | |||||||
|     case OperationType::ChangePermissions: |     case OperationType::ChangePermissions: | ||||||
|     case OperationType::ChangePermissionsAndRefresh: |     case OperationType::ChangePermissionsAndRefresh: | ||||||
|     case OperationType::ChangePermissionsAndRefreshAndFlush: { |     case OperationType::ChangePermissionsAndRefreshAndFlush: { | ||||||
|         const bool read = True(properties.perm & Kernel::KMemoryPermission::UserRead); |         m_memory->ProtectRegion(*m_impl, virt_addr, num_pages * PageSize, | ||||||
|         const bool write = True(properties.perm & Kernel::KMemoryPermission::UserWrite); |                                 ConvertToMemoryPermission(properties.perm)); | ||||||
|         // todo: this doesn't really belong here and should go into m_memory to handle rasterizer
 |  | ||||||
|         // access todo: ignore exec on non-direct-mapped case
 |  | ||||||
|         const bool exec = True(properties.perm & Kernel::KMemoryPermission::UserExecute); |  | ||||||
|         if (Settings::IsFastmemEnabled()) { |  | ||||||
|             m_system.DeviceMemory().buffer.Protect(GetInteger(virt_addr), num_pages * PageSize, |  | ||||||
|                                                    read, write, exec); |  | ||||||
|         } |  | ||||||
|         R_SUCCEED(); |         R_SUCCEED(); | ||||||
|     } |     } | ||||||
|     default: |     default: | ||||||
|  | |||||||
| @ -78,6 +78,51 @@ struct Memory::Impl { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void ProtectRegion(Common::PageTable& page_table, VAddr vaddr, u64 size, | ||||||
|  |                        Common::MemoryPermission perms) { | ||||||
|  |         ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size); | ||||||
|  |         ASSERT_MSG((vaddr & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", vaddr); | ||||||
|  | 
 | ||||||
|  |         if (!Settings::IsFastmemEnabled()) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const bool is_r = True(perms & Common::MemoryPermission::Read); | ||||||
|  |         const bool is_w = True(perms & Common::MemoryPermission::Write); | ||||||
|  |         const bool is_x = | ||||||
|  |             True(perms & Common::MemoryPermission::Execute) && Settings::IsNceEnabled(); | ||||||
|  | 
 | ||||||
|  |         if (!current_page_table) { | ||||||
|  |             system.DeviceMemory().buffer.Protect(vaddr, size, is_r, is_w, is_x); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         u64 protect_bytes{}; | ||||||
|  |         u64 protect_begin{}; | ||||||
|  |         for (u64 addr = vaddr; addr < vaddr + size; addr += YUZU_PAGESIZE) { | ||||||
|  |             const Common::PageType page_type{ | ||||||
|  |                 current_page_table->pointers[addr >> YUZU_PAGEBITS].Type()}; | ||||||
|  |             switch (page_type) { | ||||||
|  |             case Common::PageType::RasterizerCachedMemory: | ||||||
|  |                 if (protect_bytes > 0) { | ||||||
|  |                     system.DeviceMemory().buffer.Protect(protect_begin, protect_bytes, is_r, is_w, | ||||||
|  |                                                          is_x); | ||||||
|  |                     protect_bytes = 0; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 if (protect_bytes == 0) { | ||||||
|  |                     protect_begin = addr; | ||||||
|  |                 } | ||||||
|  |                 protect_bytes += YUZU_PAGESIZE; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (protect_bytes > 0) { | ||||||
|  |             system.DeviceMemory().buffer.Protect(protect_begin, protect_bytes, is_r, is_w, is_x); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     [[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(u64 vaddr) const { |     [[nodiscard]] u8* GetPointerFromRasterizerCachedMemory(u64 vaddr) const { | ||||||
|         const Common::PhysicalAddress paddr{ |         const Common::PhysicalAddress paddr{ | ||||||
|             current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]}; |             current_page_table->backing_addr[vaddr >> YUZU_PAGEBITS]}; | ||||||
| @ -839,6 +884,11 @@ void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress b | |||||||
|     impl->UnmapRegion(page_table, base, size); |     impl->UnmapRegion(page_table, base, size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Memory::ProtectRegion(Common::PageTable& page_table, Common::ProcessAddress vaddr, u64 size, | ||||||
|  |                            Common::MemoryPermission perms) { | ||||||
|  |     impl->ProtectRegion(page_table, GetInteger(vaddr), size, perms); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const { | bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const { | ||||||
|     const Kernel::KProcess& process = *system.ApplicationProcess(); |     const Kernel::KProcess& process = *system.ApplicationProcess(); | ||||||
|     const auto& page_table = process.GetPageTable().GetImpl(); |     const auto& page_table = process.GetPageTable().GetImpl(); | ||||||
|  | |||||||
| @ -97,6 +97,17 @@ public: | |||||||
|      */ |      */ | ||||||
|     void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size); |     void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size); | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Protects a region of the emulated process address space with the new permissions. | ||||||
|  |      * | ||||||
|  |      * @param page_table The page table of the emulated process. | ||||||
|  |      * @param base       The start address to re-protect. Must be page-aligned. | ||||||
|  |      * @param size       The amount of bytes to protect. Must be page-aligned. | ||||||
|  |      * @param perms      The permissions the address range is mapped. | ||||||
|  |      */ | ||||||
|  |     void ProtectRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size, | ||||||
|  |                        Common::MemoryPermission perms); | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Checks whether or not the supplied address is a valid virtual |      * Checks whether or not the supplied address is a valid virtual | ||||||
|      * address for the current process. |      * address for the current process. | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user