mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	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() {}
 | 
					ConditionVariable::~ConditionVariable() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr,
 | 
					ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr,
 | 
				
			||||||
                                                                  VAddr mutex_addr,
 | 
					 | 
				
			||||||
                                                                  std::string name) {
 | 
					                                                                  std::string name) {
 | 
				
			||||||
    SharedPtr<ConditionVariable> condition_variable(new ConditionVariable);
 | 
					    SharedPtr<ConditionVariable> condition_variable(new ConditionVariable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    condition_variable->name = std::move(name);
 | 
					    condition_variable->name = std::move(name);
 | 
				
			||||||
    condition_variable->guest_addr = guest_addr;
 | 
					    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
 | 
					    // Condition variables are referenced by guest address, so track this in the kernel
 | 
				
			||||||
    g_object_address_table.Insert(guest_addr, condition_variable);
 | 
					    g_object_address_table.Insert(guest_addr, condition_variable);
 | 
				
			||||||
 | 
				
			|||||||
@ -19,12 +19,10 @@ public:
 | 
				
			|||||||
     * Creates a condition variable.
 | 
					     * Creates a condition variable.
 | 
				
			||||||
     * @param guest_addr Address of the object tracking the condition variable in guest memory. If
 | 
					     * @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.
 | 
					     * 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.
 | 
					     * @param name Optional name of condition variable.
 | 
				
			||||||
     * @return The created 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 name = "Unknown");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string GetTypeName() const override {
 | 
					    std::string GetTypeName() const override {
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,7 @@ namespace Kernel {
 | 
				
			|||||||
SharedMemory::SharedMemory() {}
 | 
					SharedMemory::SharedMemory() {}
 | 
				
			||||||
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 permissions,
 | 
				
			||||||
                                             MemoryPermission other_permissions, VAddr address,
 | 
					                                             MemoryPermission other_permissions, VAddr address,
 | 
				
			||||||
                                             MemoryRegion region, std::string name) {
 | 
					                                             MemoryRegion region, std::string name) {
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@ public:
 | 
				
			|||||||
     * linear heap.
 | 
					     * linear heap.
 | 
				
			||||||
     * @param name Optional object name, used for debugging purposes.
 | 
					     * @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 permissions,
 | 
				
			||||||
                                          MemoryPermission other_permissions, VAddr address = 0,
 | 
					                                          MemoryPermission other_permissions, VAddr address = 0,
 | 
				
			||||||
                                          MemoryRegion region = MemoryRegion::BASE,
 | 
					                                          MemoryRegion region = MemoryRegion::BASE,
 | 
				
			||||||
@ -116,7 +116,7 @@ public:
 | 
				
			|||||||
    /// Offset into the backing block for this shared memory.
 | 
					    /// Offset into the backing block for this shared memory.
 | 
				
			||||||
    size_t backing_block_offset;
 | 
					    size_t backing_block_offset;
 | 
				
			||||||
    /// Size of the memory block. Page-aligned.
 | 
					    /// Size of the memory block. Page-aligned.
 | 
				
			||||||
    u32 size;
 | 
					    u64 size;
 | 
				
			||||||
    /// Permission restrictions applied to the process which created the block.
 | 
					    /// Permission restrictions applied to the process which created the block.
 | 
				
			||||||
    MemoryPermission permissions;
 | 
					    MemoryPermission permissions;
 | 
				
			||||||
    /// Permission restrictions applied to other processes mapping the block.
 | 
					    /// 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);
 | 
					    SharedPtr<Thread> requesting_thread = g_handle_table.Get<Thread>(requesting_thread_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASSERT(requesting_thread);
 | 
					    ASSERT(requesting_thread);
 | 
				
			||||||
 | 
					    ASSERT(requesting_thread == GetCurrentThread());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr);
 | 
					    SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr);
 | 
				
			||||||
    if (!mutex) {
 | 
					    if (!mutex) {
 | 
				
			||||||
@ -331,6 +332,9 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
 | 
				
			|||||||
    case GetInfoType::TotalHeapUsage:
 | 
					    case GetInfoType::TotalHeapUsage:
 | 
				
			||||||
        *result = vm_manager.GetTotalHeapUsage();
 | 
					        *result = vm_manager.GetTotalHeapUsage();
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    case GetInfoType::IsCurrentProcessBeingDebugged:
 | 
				
			||||||
 | 
					        *result = 0;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    case GetInfoType::RandomEntropy:
 | 
					    case GetInfoType::RandomEntropy:
 | 
				
			||||||
        *result = 0;
 | 
					        *result = 0;
 | 
				
			||||||
        break;
 | 
					        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",
 | 
					              "called, shared_memory_handle=0x%08X, addr=0x%llx, size=0x%llx, permissions=0x%08X",
 | 
				
			||||||
              shared_memory_handle, addr, size, permissions);
 | 
					              shared_memory_handle, addr, size, permissions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SharedPtr<SharedMemory> shared_memory =
 | 
					    SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
 | 
				
			||||||
        Kernel::g_handle_table.Get<SharedMemory>(shared_memory_handle);
 | 
					 | 
				
			||||||
    if (!shared_memory) {
 | 
					    if (!shared_memory) {
 | 
				
			||||||
        return ERR_INVALID_HANDLE;
 | 
					        return ERR_INVALID_HANDLE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -431,7 +434,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
 | 
				
			|||||||
    case MemoryPermission::WriteExecute:
 | 
					    case MemoryPermission::WriteExecute:
 | 
				
			||||||
    case MemoryPermission::ReadWriteExecute:
 | 
					    case MemoryPermission::ReadWriteExecute:
 | 
				
			||||||
    case MemoryPermission::DontCare:
 | 
					    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);
 | 
					                                  MemoryPermission::DontCare);
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
 | 
					        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);
 | 
					        mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASSERT(mutex->GetOwnerHandle() == thread_handle);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SharedPtr<ConditionVariable> condition_variable =
 | 
					    SharedPtr<ConditionVariable> condition_variable =
 | 
				
			||||||
        g_object_address_table.Get<ConditionVariable>(condition_variable_addr);
 | 
					        g_object_address_table.Get<ConditionVariable>(condition_variable_addr);
 | 
				
			||||||
    if (!condition_variable) {
 | 
					    if (!condition_variable) {
 | 
				
			||||||
        // Create a new condition_variable for the specified address if one does not already exist
 | 
					        // Create a new condition_variable for the specified address if one does not already exist
 | 
				
			||||||
        condition_variable =
 | 
					        condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap();
 | 
				
			||||||
            ConditionVariable::Create(condition_variable_addr, mutex_addr).Unwrap();
 | 
					 | 
				
			||||||
        condition_variable->name =
 | 
					        condition_variable->name =
 | 
				
			||||||
            Common::StringFromFormat("condition-variable-%llx", condition_variable_addr);
 | 
					            Common::StringFromFormat("condition-variable-%llx", condition_variable_addr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASSERT(condition_variable->GetAvailableCount() == 0);
 | 
					    if (condition_variable->mutex_addr) {
 | 
				
			||||||
    ASSERT(condition_variable->mutex_addr == 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,
 | 
					    auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason,
 | 
				
			||||||
                                                 SharedPtr<Thread> thread,
 | 
					                                                 SharedPtr<Thread> thread,
 | 
				
			||||||
@ -667,8 +679,6 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
 | 
				
			|||||||
    CASCADE_CODE(
 | 
					    CASCADE_CODE(
 | 
				
			||||||
        WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback));
 | 
					        WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mutex->Release(thread.get());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return RESULT_SUCCESS;
 | 
					    return RESULT_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -738,13 +748,14 @@ static ResultCode SetThreadCoreMask(u64, u64, u64) {
 | 
				
			|||||||
    return RESULT_SUCCESS;
 | 
					    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) {
 | 
					                                     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);
 | 
					              local_permissions, remote_permissions);
 | 
				
			||||||
    auto sharedMemHandle = SharedMemory::Create(
 | 
					    auto sharedMemHandle =
 | 
				
			||||||
        g_handle_table.Get<Process>(KernelHandle::CurrentProcess), sz,
 | 
					        SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size,
 | 
				
			||||||
        (Kernel::MemoryPermission)local_permissions, (Kernel::MemoryPermission)remote_permissions);
 | 
					                             static_cast<MemoryPermission>(local_permissions),
 | 
				
			||||||
 | 
					                             static_cast<MemoryPermission>(remote_permissions));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle));
 | 
					    CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle));
 | 
				
			||||||
    return RESULT_SUCCESS;
 | 
					    return RESULT_SUCCESS;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user