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() {}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
    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