Merge pull request #160 from bunnei/svc-improvements
Several SVC fixes and improvements
This commit is contained in:
		
						commit
						1ddc18454e
					
				| @ -15,13 +15,12 @@ ConditionVariable::ConditionVariable() {} | ||||
| ConditionVariable::~ConditionVariable() {} | ||||
| 
 | ||||
| ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr, | ||||
|                                                                   VAddr mutex_addr, | ||||
|                                                                   std::string name) { | ||||
|     SharedPtr<ConditionVariable> condition_variable(new ConditionVariable); | ||||
| 
 | ||||
|     condition_variable->name = std::move(name); | ||||
|     condition_variable->guest_addr = guest_addr; | ||||
|     condition_variable->mutex_addr = mutex_addr; | ||||
|     condition_variable->mutex_addr = 0; | ||||
| 
 | ||||
|     // Condition variables are referenced by guest address, so track this in the kernel
 | ||||
|     g_object_address_table.Insert(guest_addr, condition_variable); | ||||
|  | ||||
| @ -19,12 +19,10 @@ public: | ||||
|      * Creates a condition variable. | ||||
|      * @param guest_addr Address of the object tracking the condition variable in guest memory. If | ||||
|      * specified, this condition variable will update the guest object when its state changes. | ||||
|      * @param mutex_addr Optional address of a guest mutex associated with this condition variable, | ||||
|      * used by the OS for implementing events. | ||||
|      * @param name Optional name of condition variable. | ||||
|      * @return The created condition variable. | ||||
|      */ | ||||
|     static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, VAddr mutex_addr = 0, | ||||
|     static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, | ||||
|                                                           std::string name = "Unknown"); | ||||
| 
 | ||||
|     std::string GetTypeName() const override { | ||||
|  | ||||
| @ -14,7 +14,7 @@ namespace Kernel { | ||||
| SharedMemory::SharedMemory() {} | ||||
| SharedMemory::~SharedMemory() {} | ||||
| 
 | ||||
| SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size, | ||||
| SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u64 size, | ||||
|                                              MemoryPermission permissions, | ||||
|                                              MemoryPermission other_permissions, VAddr address, | ||||
|                                              MemoryRegion region, std::string name) { | ||||
|  | ||||
| @ -39,7 +39,7 @@ public: | ||||
|      * linear heap. | ||||
|      * @param name Optional object name, used for debugging purposes. | ||||
|      */ | ||||
|     static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u32 size, | ||||
|     static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u64 size, | ||||
|                                           MemoryPermission permissions, | ||||
|                                           MemoryPermission other_permissions, VAddr address = 0, | ||||
|                                           MemoryRegion region = MemoryRegion::BASE, | ||||
| @ -116,7 +116,7 @@ public: | ||||
|     /// Offset into the backing block for this shared memory.
 | ||||
|     size_t backing_block_offset; | ||||
|     /// Size of the memory block. Page-aligned.
 | ||||
|     u32 size; | ||||
|     u64 size; | ||||
|     /// Permission restrictions applied to the process which created the block.
 | ||||
|     MemoryPermission permissions; | ||||
|     /// Permission restrictions applied to other processes mapping the block.
 | ||||
|  | ||||
| @ -263,6 +263,7 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, | ||||
|     SharedPtr<Thread> requesting_thread = g_handle_table.Get<Thread>(requesting_thread_handle); | ||||
| 
 | ||||
|     ASSERT(requesting_thread); | ||||
|     ASSERT(requesting_thread == GetCurrentThread()); | ||||
| 
 | ||||
|     SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr); | ||||
|     if (!mutex) { | ||||
| @ -331,6 +332,9 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | ||||
|     case GetInfoType::TotalHeapUsage: | ||||
|         *result = vm_manager.GetTotalHeapUsage(); | ||||
|         break; | ||||
|     case GetInfoType::IsCurrentProcessBeingDebugged: | ||||
|         *result = 0; | ||||
|         break; | ||||
|     case GetInfoType::RandomEntropy: | ||||
|         *result = 0; | ||||
|         break; | ||||
| @ -415,8 +419,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s | ||||
|               "called, shared_memory_handle=0x%08X, addr=0x%llx, size=0x%llx, permissions=0x%08X", | ||||
|               shared_memory_handle, addr, size, permissions); | ||||
| 
 | ||||
|     SharedPtr<SharedMemory> shared_memory = | ||||
|         Kernel::g_handle_table.Get<SharedMemory>(shared_memory_handle); | ||||
|     SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle); | ||||
|     if (!shared_memory) { | ||||
|         return ERR_INVALID_HANDLE; | ||||
|     } | ||||
| @ -431,7 +434,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s | ||||
|     case MemoryPermission::WriteExecute: | ||||
|     case MemoryPermission::ReadWriteExecute: | ||||
|     case MemoryPermission::DontCare: | ||||
|         return shared_memory->Map(Kernel::g_current_process.get(), addr, permissions_type, | ||||
|         return shared_memory->Map(g_current_process.get(), addr, permissions_type, | ||||
|                                   MemoryPermission::DontCare); | ||||
|     default: | ||||
|         LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions); | ||||
| @ -612,20 +615,29 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var | ||||
|         mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); | ||||
|     } | ||||
| 
 | ||||
|     ASSERT(mutex->GetOwnerHandle() == thread_handle); | ||||
| 
 | ||||
|     SharedPtr<ConditionVariable> condition_variable = | ||||
|         g_object_address_table.Get<ConditionVariable>(condition_variable_addr); | ||||
|     if (!condition_variable) { | ||||
|         // Create a new condition_variable for the specified address if one does not already exist
 | ||||
|         condition_variable = | ||||
|             ConditionVariable::Create(condition_variable_addr, mutex_addr).Unwrap(); | ||||
|         condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap(); | ||||
|         condition_variable->name = | ||||
|             Common::StringFromFormat("condition-variable-%llx", condition_variable_addr); | ||||
|     } | ||||
| 
 | ||||
|     ASSERT(condition_variable->GetAvailableCount() == 0); | ||||
|     ASSERT(condition_variable->mutex_addr == mutex_addr); | ||||
|     if (condition_variable->mutex_addr) { | ||||
|         // Previously created the ConditionVariable using WaitProcessWideKeyAtomic, verify
 | ||||
|         // everything is correct
 | ||||
|         ASSERT(condition_variable->mutex_addr == mutex_addr); | ||||
|     } else { | ||||
|         // Previously created the ConditionVariable using SignalProcessWideKey, set the mutex
 | ||||
|         // associated with it
 | ||||
|         condition_variable->mutex_addr = mutex_addr; | ||||
|     } | ||||
| 
 | ||||
|     if (mutex->GetOwnerHandle()) { | ||||
|         // Release the mutex if the current thread is holding it
 | ||||
|         mutex->Release(thread.get()); | ||||
|     } | ||||
| 
 | ||||
|     auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason, | ||||
|                                                  SharedPtr<Thread> thread, | ||||
| @ -667,8 +679,6 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var | ||||
|     CASCADE_CODE( | ||||
|         WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback)); | ||||
| 
 | ||||
|     mutex->Release(thread.get()); | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| @ -738,13 +748,14 @@ static ResultCode SetThreadCoreMask(u64, u64, u64) { | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| static ResultCode CreateSharedMemory(Handle* handle, u64 sz, u32 local_permissions, | ||||
| static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions, | ||||
|                                      u32 remote_permissions) { | ||||
|     LOG_TRACE(Kernel_SVC, "called, sz=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", sz, | ||||
|     LOG_TRACE(Kernel_SVC, "called, size=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", size, | ||||
|               local_permissions, remote_permissions); | ||||
|     auto sharedMemHandle = SharedMemory::Create( | ||||
|         g_handle_table.Get<Process>(KernelHandle::CurrentProcess), sz, | ||||
|         (Kernel::MemoryPermission)local_permissions, (Kernel::MemoryPermission)remote_permissions); | ||||
|     auto sharedMemHandle = | ||||
|         SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size, | ||||
|                              static_cast<MemoryPermission>(local_permissions), | ||||
|                              static_cast<MemoryPermission>(remote_permissions)); | ||||
| 
 | ||||
|     CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle)); | ||||
|     return RESULT_SUCCESS; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei