mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	HLE/SVC: Implement UnmapMemoryBlock.
This implementation will need to be (almost completely) changed when we implement multiprocess support.
This commit is contained in:
		
							parent
							
								
									82087672b7
								
							
						
					
					
						commit
						d90d5a0ee6
					
				
					 5 changed files with 60 additions and 5 deletions
				
			
		|  | @ -188,6 +188,10 @@ template<ResultCode func(s64*, Handle, u32)> void Wrap() { | |||
|     FuncReturn(retval); | ||||
| } | ||||
| 
 | ||||
| template<ResultCode func(Handle, u32)> void Wrap() { | ||||
|     FuncReturn(func(PARAM(0), PARAM(1)).raw); | ||||
| } | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Function wrappers that return type u32
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -39,6 +39,12 @@ ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions, | |||
|             ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | ||||
|     } | ||||
| 
 | ||||
|     // TODO(Subv): Return E0E01BEE when permissions and other_permissions don't
 | ||||
|     // match what was specified when the memory block was created.
 | ||||
| 
 | ||||
|     // TODO(Subv): Return E0E01BEE when address should be 0.
 | ||||
|     // Note: Find out when that's the case.
 | ||||
| 
 | ||||
|     if (fixed_address != 0) { | ||||
|          if (address != 0 && address != fixed_address) { | ||||
|             LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s: fixed_addres is 0x%08X!", | ||||
|  | @ -74,6 +80,21 @@ ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions, | |||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| ResultCode SharedMemory::Unmap(VAddr address) { | ||||
|     if (base_address == 0) { | ||||
|         // TODO(Subv): Verify what actually happens when you want to unmap a memory block that
 | ||||
|         // was originally mapped with address = 0
 | ||||
|         return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); | ||||
|     } | ||||
| 
 | ||||
|     if (base_address != address) | ||||
|         return ResultCode(ErrorDescription::WrongAddress, ErrorModule::OS, ErrorSummary::InvalidState, ErrorLevel::Usage); | ||||
| 
 | ||||
|     base_address = 0; | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| u8* SharedMemory::GetPointer(u32 offset) { | ||||
|     if (base_address != 0) | ||||
|         return Memory::GetPointer(base_address + offset); | ||||
|  |  | |||
|  | @ -52,6 +52,13 @@ public: | |||
|      */ | ||||
|     ResultCode Map(VAddr address, MemoryPermission permissions, MemoryPermission other_permissions); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Unmaps a shared memory block from the specified address in system memory | ||||
|      * @param address Address in system memory where the shared memory block is mapped | ||||
|      * @return Result code of the unmap operation | ||||
|      */ | ||||
|     ResultCode Unmap(VAddr address); | ||||
| 
 | ||||
|     /**
 | ||||
|     * Gets a pointer to the shared memory block | ||||
|     * @param offset Offset from the start of the shared memory block to get pointer | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| /// Detailed description of the error. This listing is likely incomplete.
 | ||||
| enum class ErrorDescription : u32 { | ||||
|     Success = 0, | ||||
|     WrongAddress = 53, | ||||
|     FS_NotFound = 100, | ||||
|     FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive
 | ||||
|     InvalidSection = 1000, | ||||
|  |  | |||
|  | @ -161,6 +161,8 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o | |||
|     LOG_TRACE(Kernel_SVC, "called memblock=0x%08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d", | ||||
|         handle, addr, permissions, other_permissions); | ||||
| 
 | ||||
|     // TODO(Subv): The same process that created a SharedMemory object can not map it in its own address space
 | ||||
| 
 | ||||
|     SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle); | ||||
|     if (shared_memory == nullptr) | ||||
|         return ERR_INVALID_HANDLE; | ||||
|  | @ -175,13 +177,27 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o | |||
|     case MemoryPermission::WriteExecute: | ||||
|     case MemoryPermission::ReadWriteExecute: | ||||
|     case MemoryPermission::DontCare: | ||||
|         shared_memory->Map(addr, permissions_type, | ||||
|         return shared_memory->Map(addr, permissions_type, | ||||
|                 static_cast<MemoryPermission>(other_permissions)); | ||||
|         break; | ||||
|     default: | ||||
|         LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions); | ||||
|     } | ||||
|     return RESULT_SUCCESS; | ||||
| 
 | ||||
|     return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); | ||||
| } | ||||
| 
 | ||||
| static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) { | ||||
|     using Kernel::SharedMemory; | ||||
| 
 | ||||
|     LOG_TRACE(Kernel_SVC, "called memblock=0x%08X, addr=0x%08X", handle, addr); | ||||
| 
 | ||||
|     // TODO(Subv): Return E0A01BF5 if the address is not in the application's heap
 | ||||
| 
 | ||||
|     SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle); | ||||
|     if (shared_memory == nullptr) | ||||
|         return ERR_INVALID_HANDLE; | ||||
| 
 | ||||
|     return shared_memory->Unmap(addr); | ||||
| } | ||||
| 
 | ||||
| /// Connect to an OS service given the port name, returns the handle to the port to out
 | ||||
|  | @ -765,7 +781,13 @@ static s64 GetSystemTick() { | |||
| static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission, | ||||
|         u32 other_permission) { | ||||
|     using Kernel::SharedMemory; | ||||
|     // TODO(Subv): Implement this function
 | ||||
| 
 | ||||
|     if (size % Memory::PAGE_SIZE != 0) | ||||
|         return ResultCode(ErrorDescription::MisalignedSize, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); | ||||
| 
 | ||||
|     // TODO(Subv): Return E0A01BF5 if the address is not in the application's heap
 | ||||
| 
 | ||||
|     // TODO(Subv): Implement this function properly
 | ||||
| 
 | ||||
|     using Kernel::MemoryPermission; | ||||
|     SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(size, | ||||
|  | @ -912,7 +934,7 @@ static const FunctionDef SVC_Table[] = { | |||
|     {0x1D, HLE::Wrap<ClearTimer>,           "ClearTimer"}, | ||||
|     {0x1E, HLE::Wrap<CreateMemoryBlock>,    "CreateMemoryBlock"}, | ||||
|     {0x1F, HLE::Wrap<MapMemoryBlock>,       "MapMemoryBlock"}, | ||||
|     {0x20, nullptr,                         "UnmapMemoryBlock"}, | ||||
|     {0x20, HLE::Wrap<UnmapMemoryBlock>,     "UnmapMemoryBlock"}, | ||||
|     {0x21, HLE::Wrap<CreateAddressArbiter>, "CreateAddressArbiter"}, | ||||
|     {0x22, HLE::Wrap<ArbitrateAddress>,     "ArbitrateAddress"}, | ||||
|     {0x23, HLE::Wrap<CloseHandle>,          "CloseHandle"}, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue