HLE/SVC: Implement UnmapMemoryBlock.
This implementation will need to be (almost completely) changed when we implement multiprocess support.
This commit is contained in:
		| @@ -188,6 +188,10 @@ template<ResultCode func(s64*, Handle, u32)> void Wrap() { | |||||||
|     FuncReturn(retval); |     FuncReturn(retval); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | template<ResultCode func(Handle, u32)> void Wrap() { | ||||||
|  |     FuncReturn(func(PARAM(0), PARAM(1)).raw); | ||||||
|  | } | ||||||
|  |  | ||||||
| //////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
| // Function wrappers that return type u32 | // Function wrappers that return type u32 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -39,6 +39,12 @@ ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions, | |||||||
|             ErrorSummary::InvalidArgument, ErrorLevel::Permanent); |             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 (fixed_address != 0) { | ||||||
|          if (address != 0 && address != fixed_address) { |          if (address != 0 && address != fixed_address) { | ||||||
|             LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s: fixed_addres is 0x%08X!", |             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; |     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) { | u8* SharedMemory::GetPointer(u32 offset) { | ||||||
|     if (base_address != 0) |     if (base_address != 0) | ||||||
|         return Memory::GetPointer(base_address + offset); |         return Memory::GetPointer(base_address + offset); | ||||||
|   | |||||||
| @@ -52,6 +52,13 @@ public: | |||||||
|      */ |      */ | ||||||
|     ResultCode Map(VAddr address, MemoryPermission permissions, MemoryPermission other_permissions); |     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 |     * Gets a pointer to the shared memory block | ||||||
|     * @param offset Offset from the start of the shared memory block to get pointer |     * @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. | /// Detailed description of the error. This listing is likely incomplete. | ||||||
| enum class ErrorDescription : u32 { | enum class ErrorDescription : u32 { | ||||||
|     Success = 0, |     Success = 0, | ||||||
|  |     WrongAddress = 53, | ||||||
|     FS_NotFound = 100, |     FS_NotFound = 100, | ||||||
|     FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive |     FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive | ||||||
|     InvalidSection = 1000, |     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", |     LOG_TRACE(Kernel_SVC, "called memblock=0x%08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d", | ||||||
|         handle, addr, permissions, other_permissions); |         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); |     SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle); | ||||||
|     if (shared_memory == nullptr) |     if (shared_memory == nullptr) | ||||||
|         return ERR_INVALID_HANDLE; |         return ERR_INVALID_HANDLE; | ||||||
| @@ -175,13 +177,27 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o | |||||||
|     case MemoryPermission::WriteExecute: |     case MemoryPermission::WriteExecute: | ||||||
|     case MemoryPermission::ReadWriteExecute: |     case MemoryPermission::ReadWriteExecute: | ||||||
|     case MemoryPermission::DontCare: |     case MemoryPermission::DontCare: | ||||||
|         shared_memory->Map(addr, permissions_type, |         return shared_memory->Map(addr, permissions_type, | ||||||
|                 static_cast<MemoryPermission>(other_permissions)); |                 static_cast<MemoryPermission>(other_permissions)); | ||||||
|         break; |  | ||||||
|     default: |     default: | ||||||
|         LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions); |         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 | /// 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, | static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission, | ||||||
|         u32 other_permission) { |         u32 other_permission) { | ||||||
|     using Kernel::SharedMemory; |     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; |     using Kernel::MemoryPermission; | ||||||
|     SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(size, |     SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(size, | ||||||
| @@ -912,7 +934,7 @@ static const FunctionDef SVC_Table[] = { | |||||||
|     {0x1D, HLE::Wrap<ClearTimer>,           "ClearTimer"}, |     {0x1D, HLE::Wrap<ClearTimer>,           "ClearTimer"}, | ||||||
|     {0x1E, HLE::Wrap<CreateMemoryBlock>,    "CreateMemoryBlock"}, |     {0x1E, HLE::Wrap<CreateMemoryBlock>,    "CreateMemoryBlock"}, | ||||||
|     {0x1F, HLE::Wrap<MapMemoryBlock>,       "MapMemoryBlock"}, |     {0x1F, HLE::Wrap<MapMemoryBlock>,       "MapMemoryBlock"}, | ||||||
|     {0x20, nullptr,                         "UnmapMemoryBlock"}, |     {0x20, HLE::Wrap<UnmapMemoryBlock>,     "UnmapMemoryBlock"}, | ||||||
|     {0x21, HLE::Wrap<CreateAddressArbiter>, "CreateAddressArbiter"}, |     {0x21, HLE::Wrap<CreateAddressArbiter>, "CreateAddressArbiter"}, | ||||||
|     {0x22, HLE::Wrap<ArbitrateAddress>,     "ArbitrateAddress"}, |     {0x22, HLE::Wrap<ArbitrateAddress>,     "ArbitrateAddress"}, | ||||||
|     {0x23, HLE::Wrap<CloseHandle>,          "CloseHandle"}, |     {0x23, HLE::Wrap<CloseHandle>,          "CloseHandle"}, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user