mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Match changes to svcMapProcessMemoryEx from latest Luma3DS (#264)
This commit is contained in:
		
							parent
							
								
									f3fb038587
								
							
						
					
					
						commit
						608383ec84
					
				
					 4 changed files with 45 additions and 11 deletions
				
			
		|  | @ -179,6 +179,8 @@ Loader::ResultStatus FileSys::Plugin3GXLoader::Map( | |||
|         4 * 1024 * 1024  // 4 MiB
 | ||||
|     }; | ||||
| 
 | ||||
|     const bool is_mem_private = header.infos.flags.use_private_memory != 0; | ||||
| 
 | ||||
|     // Map memory block. This behaviour mimics how plugins are loaded on 3DS as much as possible.
 | ||||
|     // Calculate the sizes of the different memory regions
 | ||||
|     const u32 block_size = mem_region_sizes[header.infos.flags.memory_region_size.Value()]; | ||||
|  | @ -199,7 +201,8 @@ Loader::ResultStatus FileSys::Plugin3GXLoader::Map( | |||
|     std::fill(backing_memory_fb.GetPtr(), backing_memory_fb.GetPtr() + _3GX_fb_size, 0); | ||||
| 
 | ||||
|     auto vma_heap_fb = process.vm_manager.MapBackingMemory( | ||||
|         _3GX_heap_load_addr, backing_memory_fb, _3GX_fb_size, Kernel::MemoryState::Continuous); | ||||
|         _3GX_heap_load_addr, backing_memory_fb, _3GX_fb_size, | ||||
|         is_mem_private ? Kernel::MemoryState::Private : Kernel::MemoryState::Shared); | ||||
|     ASSERT(vma_heap_fb.Succeeded()); | ||||
|     process.vm_manager.Reprotect(vma_heap_fb.Unwrap(), Kernel::VMAPermission::ReadWrite); | ||||
| 
 | ||||
|  | @ -217,7 +220,8 @@ Loader::ResultStatus FileSys::Plugin3GXLoader::Map( | |||
| 
 | ||||
|     // Then we map part of the memory, which contains the executable
 | ||||
|     auto vma = process.vm_manager.MapBackingMemory(_3GX_exe_load_addr, backing_memory, exe_size, | ||||
|                                                    Kernel::MemoryState::Continuous); | ||||
|                                                    is_mem_private ? Kernel::MemoryState::Private | ||||
|                                                                   : Kernel::MemoryState::Shared); | ||||
|     ASSERT(vma.Succeeded()); | ||||
|     process.vm_manager.Reprotect(vma.Unwrap(), Kernel::VMAPermission::ReadWriteExecute); | ||||
| 
 | ||||
|  | @ -256,7 +260,8 @@ Loader::ResultStatus FileSys::Plugin3GXLoader::Map( | |||
|     // Map the rest of the memory at the heap location
 | ||||
|     auto vma_heap = process.vm_manager.MapBackingMemory( | ||||
|         _3GX_heap_load_addr + _3GX_fb_size, backing_memory_heap, | ||||
|         block_size - exe_size - _3GX_fb_size, Kernel::MemoryState::Continuous); | ||||
|         block_size - exe_size - _3GX_fb_size, | ||||
|         is_mem_private ? Kernel::MemoryState::Private : Kernel::MemoryState::Shared); | ||||
|     ASSERT(vma_heap.Succeeded()); | ||||
|     process.vm_manager.Reprotect(vma_heap.Unwrap(), Kernel::VMAPermission::ReadWriteExecute); | ||||
| 
 | ||||
|  |  | |||
|  | @ -94,6 +94,9 @@ private: | |||
|             BitField<1, 1, u32_le> embedded_swap_func; | ||||
|             BitField<2, 2, u32_le> memory_region_size; | ||||
|             BitField<4, 2, u32_le> compatibility; | ||||
|             BitField<6, 1, u32_le> events_self_managed; | ||||
|             BitField<7, 1, u32_le> swap_not_needed; | ||||
|             BitField<8, 1, u32_le> use_private_memory; | ||||
|         } flags; | ||||
|         u32_le exe_load_checksum; | ||||
|         u32_le builtin_load_exe_args[4]; | ||||
|  |  | |||
|  | @ -369,6 +369,16 @@ enum class ControlProcessOP { | |||
|     PROCESSOP_DISABLE_CREATE_THREAD_RESTRICTIONS, | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Accepted by the custom svcMapProcessMemoryEx. | ||||
|  */ | ||||
| enum class MapMemoryExFlag { | ||||
|     /**
 | ||||
|      * Maps the memory region as PRIVATE instead of SHARED | ||||
|      */ | ||||
|     MAPEXFLAGS_PRIVATE = (1 << 0), | ||||
| }; | ||||
| 
 | ||||
| class SVC : public SVCWrapper<SVC> { | ||||
| public: | ||||
|     SVC(Core::System& system); | ||||
|  | @ -460,7 +470,8 @@ private: | |||
|     Result InvalidateEntireInstructionCache(); | ||||
|     u32 ConvertVaToPa(u32 addr); | ||||
|     Result MapProcessMemoryEx(Handle dst_process_handle, u32 dst_address, Handle src_process_handle, | ||||
|                               u32 src_address, u32 size); | ||||
|                               u32 src_address, u32 size, MapMemoryExFlag flags, | ||||
|                               Handle dst_process_handle_backup); | ||||
|     Result UnmapProcessMemoryEx(Handle process, u32 dst_address, u32 size); | ||||
|     Result ControlProcess(Handle process_handle, u32 process_OP, u32 varg2, u32 varg3); | ||||
| 
 | ||||
|  | @ -2012,7 +2023,22 @@ u32 SVC::ConvertVaToPa(u32 addr) { | |||
| } | ||||
| 
 | ||||
| Result SVC::MapProcessMemoryEx(Handle dst_process_handle, u32 dst_address, | ||||
|                                Handle src_process_handle, u32 src_address, u32 size) { | ||||
|                                Handle src_process_handle, u32 src_address, u32 size, | ||||
|                                MapMemoryExFlag flags, Handle dst_process_handle_backup) { | ||||
| 
 | ||||
|     // Determine if this is the second version of the svc by checking the value at R0.
 | ||||
|     constexpr u32 SVC_VERSION2_MAGIC = 0xFFFFFFF2; | ||||
|     if (static_cast<u32>(dst_process_handle) == SVC_VERSION2_MAGIC) { | ||||
|         // Version 2, actual handle is provided in 6th argument
 | ||||
|         dst_process_handle = dst_process_handle_backup; | ||||
|     } else { | ||||
|         // Version 1, the flags argument is not used
 | ||||
|         flags = static_cast<MapMemoryExFlag>(0); | ||||
|     } | ||||
| 
 | ||||
|     const bool map_as_private = | ||||
|         (static_cast<u32>(flags) & static_cast<u32>(MapMemoryExFlag::MAPEXFLAGS_PRIVATE)) != 0; | ||||
| 
 | ||||
|     std::shared_ptr<Process> dst_process = | ||||
|         kernel.GetCurrentProcess()->handle_table.Get<Process>(dst_process_handle); | ||||
|     std::shared_ptr<Process> src_process = | ||||
|  | @ -2024,11 +2050,12 @@ Result SVC::MapProcessMemoryEx(Handle dst_process_handle, u32 dst_address, | |||
|         size = (size & ~0xFFF) + Memory::CITRA_PAGE_SIZE; | ||||
|     } | ||||
| 
 | ||||
|     // TODO(PabloMK7) Fix-up this svc.
 | ||||
| 
 | ||||
|     // Only linear memory supported
 | ||||
|     auto vma = src_process->vm_manager.FindVMA(src_address); | ||||
|     R_UNLESS(vma != src_process->vm_manager.vma_map.end() && | ||||
|                  vma->second.type == VMAType::BackingMemory && | ||||
|                  vma->second.meminfo_state == MemoryState::Continuous, | ||||
|                  vma->second.type == VMAType::BackingMemory, | ||||
|              ResultInvalidAddress); | ||||
| 
 | ||||
|     const u32 offset = src_address - vma->second.base; | ||||
|  | @ -2038,7 +2065,7 @@ Result SVC::MapProcessMemoryEx(Handle dst_process_handle, u32 dst_address, | |||
|         dst_address, | ||||
|         memory.GetFCRAMRef(vma->second.backing_memory.GetPtr() + offset - | ||||
|                            kernel.memory.GetFCRAMPointer(0)), | ||||
|         size, Kernel::MemoryState::Continuous); | ||||
|         size, map_as_private ? MemoryState::Private : MemoryState::Shared); | ||||
| 
 | ||||
|     if (!vma_res.Succeeded()) { | ||||
|         return ResultInvalidAddressState; | ||||
|  | @ -2060,8 +2087,7 @@ Result SVC::UnmapProcessMemoryEx(Handle process, u32 dst_address, u32 size) { | |||
|     // Only linear memory supported
 | ||||
|     auto vma = dst_process->vm_manager.FindVMA(dst_address); | ||||
|     R_UNLESS(vma != dst_process->vm_manager.vma_map.end() && | ||||
|                  vma->second.type == VMAType::BackingMemory && | ||||
|                  vma->second.meminfo_state == MemoryState::Continuous, | ||||
|                  vma->second.type == VMAType::BackingMemory, | ||||
|              ResultInvalidAddress); | ||||
| 
 | ||||
|     dst_process->vm_manager.UnmapRange(dst_address, size); | ||||
|  |  | |||
|  | @ -38,7 +38,7 @@ SERVICE_CONSTRUCT_IMPL(Service::PLGLDR::PLG_LDR) | |||
| 
 | ||||
| namespace Service::PLGLDR { | ||||
| 
 | ||||
| static const Kernel::CoreVersion plgldr_version = Kernel::CoreVersion(1, 0, 0); | ||||
| static const Kernel::CoreVersion plgldr_version = Kernel::CoreVersion(1, 0, 2); | ||||
| 
 | ||||
| PLG_LDR::PLG_LDR(Core::System& system_) : ServiceFramework{"plg:ldr", 1}, system(system_) { | ||||
|     static const FunctionInfo functions[] = { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue