diff options
Diffstat (limited to '')
70 files changed, 818 insertions, 918 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c1a645460..b3807c204 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -42,8 +42,6 @@ add_library(core STATIC hle/kernel/client_port.h hle/kernel/client_session.cpp hle/kernel/client_session.h - hle/kernel/condition_variable.cpp - hle/kernel/condition_variable.h hle/kernel/errors.h hle/kernel/event.cpp hle/kernel/event.h diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp index ca1323873..4d00249fa 100644 --- a/src/core/file_sys/disk_filesystem.cpp +++ b/src/core/file_sys/disk_filesystem.cpp @@ -67,10 +67,16 @@ ResultCode Disk_FileSystem::DeleteFile(const std::string& path) const { return RESULT_SUCCESS; } -ResultCode Disk_FileSystem::RenameFile(const Path& src_path, const Path& dest_path) const { - LOG_WARNING(Service_FS, "(STUBBED) called"); +ResultCode Disk_FileSystem::RenameFile(const std::string& src_path, + const std::string& dest_path) const { + const std::string full_src_path = base_directory + src_path; + const std::string full_dest_path = base_directory + dest_path; + + if (!FileUtil::Exists(full_src_path)) { + return ERROR_PATH_NOT_FOUND; + } // TODO(wwylele): Use correct error code - return ResultCode(-1); + return FileUtil::Rename(full_src_path, full_dest_path) ? RESULT_SUCCESS : ResultCode(-1); } ResultCode Disk_FileSystem::DeleteDirectory(const Path& path) const { diff --git a/src/core/file_sys/disk_filesystem.h b/src/core/file_sys/disk_filesystem.h index 8f9e1145a..591e39fda 100644 --- a/src/core/file_sys/disk_filesystem.h +++ b/src/core/file_sys/disk_filesystem.h @@ -26,7 +26,7 @@ public: ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const std::string& path, Mode mode) const override; ResultCode DeleteFile(const std::string& path) const override; - ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override; + ResultCode RenameFile(const std::string& src_path, const std::string& dest_path) const override; ResultCode DeleteDirectory(const Path& path) const override; ResultCode DeleteDirectoryRecursively(const Path& path) const override; ResultCode CreateFile(const std::string& path, u64 size) const override; diff --git a/src/core/file_sys/filesystem.h b/src/core/file_sys/filesystem.h index beefcfdb2..295a3133e 100644 --- a/src/core/file_sys/filesystem.h +++ b/src/core/file_sys/filesystem.h @@ -126,7 +126,8 @@ public: * @param dest_path Destination path relative to the archive * @return Result of the operation */ - virtual ResultCode RenameFile(const Path& src_path, const Path& dest_path) const = 0; + virtual ResultCode RenameFile(const std::string& src_path, + const std::string& dest_path) const = 0; /** * Rename a Directory specified by its path diff --git a/src/core/file_sys/romfs_filesystem.cpp b/src/core/file_sys/romfs_filesystem.cpp index 3d77e2d5f..b9982e6fa 100644 --- a/src/core/file_sys/romfs_filesystem.cpp +++ b/src/core/file_sys/romfs_filesystem.cpp @@ -27,7 +27,8 @@ ResultCode RomFS_FileSystem::DeleteFile(const std::string& path) const { return ResultCode(-1); } -ResultCode RomFS_FileSystem::RenameFile(const Path& src_path, const Path& dest_path) const { +ResultCode RomFS_FileSystem::RenameFile(const std::string& src_path, + const std::string& dest_path) const { LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive (%s).", GetName().c_str()); // TODO(wwylele): Use correct error code diff --git a/src/core/file_sys/romfs_filesystem.h b/src/core/file_sys/romfs_filesystem.h index 1b5cac409..ba9d85823 100644 --- a/src/core/file_sys/romfs_filesystem.h +++ b/src/core/file_sys/romfs_filesystem.h @@ -32,7 +32,7 @@ public: ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const std::string& path, Mode mode) const override; ResultCode DeleteFile(const std::string& path) const override; - ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override; + ResultCode RenameFile(const std::string& src_path, const std::string& dest_path) const override; ResultCode DeleteDirectory(const Path& path) const override; ResultCode DeleteDirectoryRecursively(const Path& path) const override; ResultCode CreateFile(const std::string& path, u64 size) const override; diff --git a/src/core/hle/kernel/condition_variable.cpp b/src/core/hle/kernel/condition_variable.cpp deleted file mode 100644 index a786d7f74..000000000 --- a/src/core/hle/kernel/condition_variable.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2018 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "common/assert.h" -#include "core/hle/kernel/condition_variable.h" -#include "core/hle/kernel/errors.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/object_address_table.h" -#include "core/hle/kernel/thread.h" - -namespace Kernel { - -ConditionVariable::ConditionVariable() {} -ConditionVariable::~ConditionVariable() {} - -ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_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 = 0; - - // Condition variables are referenced by guest address, so track this in the kernel - g_object_address_table.Insert(guest_addr, condition_variable); - - return MakeResult<SharedPtr<ConditionVariable>>(std::move(condition_variable)); -} - -bool ConditionVariable::ShouldWait(Thread* thread) const { - return GetAvailableCount() <= 0; -} - -void ConditionVariable::Acquire(Thread* thread) { - if (GetAvailableCount() <= 0) - return; - - SetAvailableCount(GetAvailableCount() - 1); -} - -ResultCode ConditionVariable::Release(s32 target) { - if (target == -1) { - // When -1, wake up all waiting threads - SetAvailableCount(static_cast<s32>(GetWaitingThreads().size())); - WakeupAllWaitingThreads(); - } else { - // Otherwise, wake up just a single thread - SetAvailableCount(target); - WakeupWaitingThread(GetHighestPriorityReadyThread()); - } - - return RESULT_SUCCESS; -} - -s32 ConditionVariable::GetAvailableCount() const { - return Memory::Read32(guest_addr); -} - -void ConditionVariable::SetAvailableCount(s32 value) const { - Memory::Write32(guest_addr, value); -} - -} // namespace Kernel diff --git a/src/core/hle/kernel/condition_variable.h b/src/core/hle/kernel/condition_variable.h deleted file mode 100644 index 1c9f06769..000000000 --- a/src/core/hle/kernel/condition_variable.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2018 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include <string> -#include <queue> -#include "common/common_types.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/wait_object.h" -#include "core/hle/result.h" - -namespace Kernel { - -class ConditionVariable final : public WaitObject { -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 name Optional name of condition variable. - * @return The created condition variable. - */ - static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, - std::string name = "Unknown"); - - std::string GetTypeName() const override { - return "ConditionVariable"; - } - std::string GetName() const override { - return name; - } - - static const HandleType HANDLE_TYPE = HandleType::ConditionVariable; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - - s32 GetAvailableCount() const; - void SetAvailableCount(s32 value) const; - - std::string name; ///< Name of condition variable (optional) - VAddr guest_addr; ///< Address of the guest condition variable value - VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this condition - ///< variable, used for implementing events - - bool ShouldWait(Thread* thread) const override; - void Acquire(Thread* thread) override; - - /** - * Releases a slot from a condition variable. - * @param target The number of threads to wakeup, -1 is all. - * @return ResultCode indicating if the operation succeeded. - */ - ResultCode Release(s32 target); - -private: - ConditionVariable(); - ~ConditionVariable() override; -}; - -} // namespace Kernel diff --git a/src/core/hle/kernel/errors.h b/src/core/hle/kernel/errors.h index 29d8dfdaa..5be20c878 100644 --- a/src/core/hle/kernel/errors.h +++ b/src/core/hle/kernel/errors.h @@ -20,6 +20,7 @@ enum { MaxConnectionsReached = 52, // Confirmed Switch OS error codes + MisalignedAddress = 102, InvalidHandle = 114, Timeout = 117, SynchronizationCanceled = 118, diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 053bf4e17..402ae900f 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -18,12 +18,10 @@ using Handle = u32; enum class HandleType : u32 { Unknown, Event, - Mutex, SharedMemory, Thread, Process, AddressArbiter, - ConditionVariable, Timer, ResourceLimit, CodeSet, @@ -63,9 +61,7 @@ public: bool IsWaitable() const { switch (GetHandleType()) { case HandleType::Event: - case HandleType::Mutex: case HandleType::Thread: - case HandleType::ConditionVariable: case HandleType::Timer: case HandleType::ServerPort: case HandleType::ServerSession: diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 0b9dc700c..63733ad79 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -7,6 +7,7 @@ #include <boost/range/algorithm_ext/erase.hpp> #include "common/assert.h" #include "core/core.h" +#include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/mutex.h" @@ -15,124 +16,120 @@ namespace Kernel { -void ReleaseThreadMutexes(Thread* thread) { - for (auto& mtx : thread->held_mutexes) { - mtx->SetHasWaiters(false); - mtx->SetHoldingThread(nullptr); - mtx->WakeupAllWaitingThreads(); - } - thread->held_mutexes.clear(); -} +/// Returns the number of threads that are waiting for a mutex, and the highest priority one among +/// those. +static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread( + SharedPtr<Thread> current_thread, VAddr mutex_addr) { -Mutex::Mutex() {} -Mutex::~Mutex() {} + SharedPtr<Thread> highest_priority_thread; + u32 num_waiters = 0; -SharedPtr<Mutex> Mutex::Create(SharedPtr<Kernel::Thread> holding_thread, VAddr guest_addr, - std::string name) { - SharedPtr<Mutex> mutex(new Mutex); + for (auto& thread : current_thread->wait_mutex_threads) { + if (thread->mutex_wait_address != mutex_addr) + continue; - mutex->guest_addr = guest_addr; - mutex->name = std::move(name); + ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); - // If mutex was initialized with a holding thread, acquire it by the holding thread - if (holding_thread) { - mutex->Acquire(holding_thread.get()); + ++num_waiters; + if (highest_priority_thread == nullptr || + thread->GetPriority() < highest_priority_thread->GetPriority()) { + highest_priority_thread = thread; + } } - // Mutexes are referenced by guest address, so track this in the kernel - g_object_address_table.Insert(guest_addr, mutex); - - return mutex; + return {highest_priority_thread, num_waiters}; } -bool Mutex::ShouldWait(Thread* thread) const { - auto holding_thread = GetHoldingThread(); - return holding_thread != nullptr && thread != holding_thread; +/// Update the mutex owner field of all threads waiting on the mutex to point to the new owner. +static void TransferMutexOwnership(VAddr mutex_addr, SharedPtr<Thread> current_thread, + SharedPtr<Thread> new_owner) { + auto threads = current_thread->wait_mutex_threads; + for (auto& thread : threads) { + if (thread->mutex_wait_address != mutex_addr) + continue; + + ASSERT(thread->lock_owner == current_thread); + current_thread->RemoveMutexWaiter(thread); + if (new_owner != thread) + new_owner->AddMutexWaiter(thread); + } } -void Mutex::Acquire(Thread* thread) { - ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); +ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, + Handle requesting_thread_handle) { + // The mutex address must be 4-byte aligned + if ((address % sizeof(u32)) != 0) { + return ResultCode(ErrorModule::Kernel, ErrCodes::MisalignedAddress); + } - priority = thread->current_priority; - thread->held_mutexes.insert(this); - SetHoldingThread(thread); - thread->UpdatePriority(); - Core::System::GetInstance().PrepareReschedule(); -} + SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle); + SharedPtr<Thread> requesting_thread = g_handle_table.Get<Thread>(requesting_thread_handle); -ResultCode Mutex::Release(Thread* thread) { - auto holding_thread = GetHoldingThread(); - ASSERT(holding_thread); + // TODO(Subv): It is currently unknown if it is possible to lock a mutex in behalf of another + // thread. + ASSERT(requesting_thread == GetCurrentThread()); - // We can only release the mutex if it's held by the calling thread. - ASSERT(thread == holding_thread); + u32 addr_value = Memory::Read32(address); + + // If the mutex isn't being held, just return success. + if (addr_value != (holding_thread_handle | Mutex::MutexHasWaitersFlag)) { + return RESULT_SUCCESS; + } + + if (holding_thread == nullptr) + return ERR_INVALID_HANDLE; + + // Wait until the mutex is released + GetCurrentThread()->mutex_wait_address = address; + GetCurrentThread()->wait_handle = requesting_thread_handle; + + GetCurrentThread()->status = THREADSTATUS_WAIT_MUTEX; + GetCurrentThread()->wakeup_callback = nullptr; + + // Update the lock holder thread's priority to prevent priority inversion. + holding_thread->AddMutexWaiter(GetCurrentThread()); - holding_thread->held_mutexes.erase(this); - holding_thread->UpdatePriority(); - SetHoldingThread(nullptr); - SetHasWaiters(!GetWaitingThreads().empty()); - WakeupAllWaitingThreads(); Core::System::GetInstance().PrepareReschedule(); return RESULT_SUCCESS; } -void Mutex::AddWaitingThread(SharedPtr<Thread> thread) { - WaitObject::AddWaitingThread(thread); - thread->pending_mutexes.insert(this); - SetHasWaiters(true); - UpdatePriority(); -} - -void Mutex::RemoveWaitingThread(Thread* thread) { - WaitObject::RemoveWaitingThread(thread); - thread->pending_mutexes.erase(this); - if (!GetHasWaiters()) - SetHasWaiters(!GetWaitingThreads().empty()); - UpdatePriority(); -} +ResultCode Mutex::Release(VAddr address) { + // The mutex address must be 4-byte aligned + if ((address % sizeof(u32)) != 0) { + return ResultCode(ErrorModule::Kernel, ErrCodes::MisalignedAddress); + } -void Mutex::UpdatePriority() { - if (!GetHoldingThread()) - return; + auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(GetCurrentThread(), address); - u32 best_priority = THREADPRIO_LOWEST; - for (auto& waiter : GetWaitingThreads()) { - if (waiter->current_priority < best_priority) - best_priority = waiter->current_priority; + // There are no more threads waiting for the mutex, release it completely. + if (thread == nullptr) { + ASSERT(GetCurrentThread()->wait_mutex_threads.empty()); + Memory::Write32(address, 0); + return RESULT_SUCCESS; } - if (best_priority != priority) { - priority = best_priority; - GetHoldingThread()->UpdatePriority(); - } -} + // Transfer the ownership of the mutex from the previous owner to the new one. + TransferMutexOwnership(address, GetCurrentThread(), thread); -Handle Mutex::GetOwnerHandle() const { - GuestState guest_state{Memory::Read32(guest_addr)}; - return guest_state.holding_thread_handle; -} + u32 mutex_value = thread->wait_handle; -SharedPtr<Thread> Mutex::GetHoldingThread() const { - GuestState guest_state{Memory::Read32(guest_addr)}; - return g_handle_table.Get<Thread>(guest_state.holding_thread_handle); -} + if (num_waiters >= 2) { + // Notify the guest that there are still some threads waiting for the mutex + mutex_value |= Mutex::MutexHasWaitersFlag; + } -void Mutex::SetHoldingThread(SharedPtr<Thread> thread) { - GuestState guest_state{Memory::Read32(guest_addr)}; - guest_state.holding_thread_handle.Assign(thread ? thread->guest_handle : 0); - Memory::Write32(guest_addr, guest_state.raw); -} + // Grant the mutex to the next waiting thread and resume it. + Memory::Write32(address, mutex_value); -bool Mutex::GetHasWaiters() const { - GuestState guest_state{Memory::Read32(guest_addr)}; - return guest_state.has_waiters != 0; -} + ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); + thread->ResumeFromWait(); -void Mutex::SetHasWaiters(bool has_waiters) { - GuestState guest_state{Memory::Read32(guest_addr)}; - guest_state.has_waiters.Assign(has_waiters ? 1 : 0); - Memory::Write32(guest_addr, guest_state.raw); -} + thread->lock_owner = nullptr; + thread->condvar_wait_address = 0; + thread->mutex_wait_address = 0; + thread->wait_handle = 0; + return RESULT_SUCCESS; +} } // namespace Kernel diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 38db21005..3117e7c70 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -15,87 +15,23 @@ namespace Kernel { class Thread; -class Mutex final : public WaitObject { +class Mutex final { public: - /** - * Creates a mutex. - * @param holding_thread Specifies a thread already holding the mutex. If not nullptr, this - * thread will acquire the mutex. - * @param guest_addr Address of the object tracking the mutex in guest memory. If specified, - * this mutex will update the guest object when its state changes. - * @param name Optional name of mutex - * @return Pointer to new Mutex object - */ - static SharedPtr<Mutex> Create(SharedPtr<Kernel::Thread> holding_thread, VAddr guest_addr = 0, - std::string name = "Unknown"); + /// Flag that indicates that a mutex still has threads waiting for it. + static constexpr u32 MutexHasWaitersFlag = 0x40000000; + /// Mask of the bits in a mutex address value that contain the mutex owner. + static constexpr u32 MutexOwnerMask = 0xBFFFFFFF; - std::string GetTypeName() const override { - return "Mutex"; - } - std::string GetName() const override { - return name; - } + /// Attempts to acquire a mutex at the specified address. + static ResultCode TryAcquire(VAddr address, Handle holding_thread_handle, + Handle requesting_thread_handle); - static const HandleType HANDLE_TYPE = HandleType::Mutex; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - - u32 priority; ///< The priority of the mutex, used for priority inheritance. - std::string name; ///< Name of mutex (optional) - VAddr guest_addr; ///< Address of the guest mutex value - - /** - * Elevate the mutex priority to the best priority - * among the priorities of all its waiting threads. - */ - void UpdatePriority(); - - bool ShouldWait(Thread* thread) const override; - void Acquire(Thread* thread) override; - - void AddWaitingThread(SharedPtr<Thread> thread) override; - void RemoveWaitingThread(Thread* thread) override; - - /** - * Attempts to release the mutex from the specified thread. - * @param thread Thread that wants to release the mutex. - * @returns The result code of the operation. - */ - ResultCode Release(Thread* thread); - - /// Gets the handle to the holding process stored in the guest state. - Handle GetOwnerHandle() const; - - /// Gets the Thread pointed to by the owner handle - SharedPtr<Thread> GetHoldingThread() const; - /// Sets the holding process handle in the guest state. - void SetHoldingThread(SharedPtr<Thread> thread); - - /// Returns the has_waiters bit in the guest state. - bool GetHasWaiters() const; - /// Sets the has_waiters bit in the guest state. - void SetHasWaiters(bool has_waiters); + /// Releases the mutex at the specified address. + static ResultCode Release(VAddr address); private: - Mutex(); - ~Mutex() override; - - /// Object in guest memory used to track the mutex state - union GuestState { - u32_le raw; - /// Handle of the thread that currently holds the mutex, 0 if available - BitField<0, 30, u32_le> holding_thread_handle; - /// 1 when there are threads waiting for this mutex, otherwise 0 - BitField<30, 1, u32_le> has_waiters; - }; - static_assert(sizeof(GuestState) == 4, "GuestState size is incorrect"); + Mutex() = default; + ~Mutex() = default; }; -/** - * Releases all the mutexes held by the specified thread - * @param thread Thread that is holding the mutexes - */ -void ReleaseThreadMutexes(Thread* thread); - } // namespace Kernel diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 633740992..c22da6e47 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -13,7 +13,6 @@ #include "core/core_timing.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" -#include "core/hle/kernel/condition_variable.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/mutex.h" @@ -262,32 +261,14 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, "requesting_current_thread_handle=0x%08X", holding_thread_handle, mutex_addr, requesting_thread_handle); - SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle); - 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) { - // Create a new mutex for the specified address if one does not already exist - mutex = Mutex::Create(holding_thread, mutex_addr); - mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); - } - - ASSERT(holding_thread == mutex->GetHoldingThread()); - - return WaitSynchronization1(mutex, requesting_thread.get()); + return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle); } /// Unlock a mutex static ResultCode ArbitrateUnlock(VAddr mutex_addr) { LOG_TRACE(Kernel_SVC, "called mutex_addr=0x%llx", mutex_addr); - SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr); - ASSERT(mutex); - - return mutex->Release(GetCurrentThread()); + return Mutex::Release(mutex_addr); } /// Break program execution @@ -412,11 +393,6 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { } thread->SetPriority(priority); - thread->UpdatePriority(); - - // Update the mutexes that this thread is waiting for - for (auto& mutex : thread->pending_mutexes) - mutex->UpdatePriority(); Core::System::GetInstance().PrepareReschedule(); return RESULT_SUCCESS; @@ -634,103 +610,75 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); ASSERT(thread); - SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr); - if (!mutex) { - // Create a new mutex for the specified address if one does not already exist - mutex = Mutex::Create(thread, mutex_addr); - mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); - } - - 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).Unwrap(); - condition_variable->name = - Common::StringFromFormat("condition-variable-%llx", condition_variable_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; - } + CASCADE_CODE(Mutex::Release(mutex_addr)); - if (mutex->GetOwnerHandle()) { - // Release the mutex if the current thread is holding it - mutex->Release(thread.get()); - } + SharedPtr<Thread> current_thread = GetCurrentThread(); + current_thread->condvar_wait_address = condition_variable_addr; + current_thread->mutex_wait_address = mutex_addr; + current_thread->wait_handle = thread_handle; + current_thread->status = THREADSTATUS_WAIT_MUTEX; + current_thread->wakeup_callback = nullptr; - auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason, - SharedPtr<Thread> thread, - SharedPtr<WaitObject> object, size_t index) { - ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); + current_thread->WakeAfterDelay(nano_seconds); - if (reason == ThreadWakeupReason::Timeout) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return true; - } + // Note: Deliberately don't attempt to inherit the lock owner's priority. - ASSERT(reason == ThreadWakeupReason::Signal); + Core::System::GetInstance().PrepareReschedule(); + return RESULT_SUCCESS; +} - // Now try to acquire the mutex and don't resume if it's not available. - if (!mutex->ShouldWait(thread.get())) { - mutex->Acquire(thread.get()); - thread->SetWaitSynchronizationResult(RESULT_SUCCESS); - return true; - } +/// Signal process wide key +static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) { + LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x%llx, target=0x%08x", + condition_variable_addr, target); - if (nano_seconds == 0) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return true; - } + u32 processed = 0; + auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList(); - thread->wait_objects = {mutex}; - mutex->AddWaitingThread(thread); - thread->status = THREADSTATUS_WAIT_SYNCH_ANY; + for (auto& thread : thread_list) { + if (thread->condvar_wait_address != condition_variable_addr) + continue; - // Create an event to wake the thread up after the - // specified nanosecond delay has passed - thread->WakeAfterDelay(nano_seconds); - thread->wakeup_callback = DefaultThreadWakeupCallback; + // Only process up to 'target' threads, unless 'target' is -1, in which case process + // them all. + if (target != -1 && processed >= target) + break; - Core::System::GetInstance().PrepareReschedule(); + // If the mutex is not yet acquired, acquire it. + u32 mutex_val = Memory::Read32(thread->mutex_wait_address); - return false; - }; - CASCADE_CODE( - WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback)); + if (mutex_val == 0) { + // We were able to acquire the mutex, resume this thread. + Memory::Write32(thread->mutex_wait_address, thread->wait_handle); + ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); + thread->ResumeFromWait(); - return RESULT_SUCCESS; -} + auto lock_owner = thread->lock_owner; + if (lock_owner) + lock_owner->RemoveMutexWaiter(thread); -/// Signal process wide key -static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) { - LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x%llx, target=0x%08x", - condition_variable_addr, target); + thread->lock_owner = nullptr; + thread->mutex_wait_address = 0; + thread->condvar_wait_address = 0; + thread->wait_handle = 0; + } else { + // Couldn't acquire the mutex, block the thread. + Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); + auto owner = g_handle_table.Get<Thread>(owner_handle); + ASSERT(owner); + ASSERT(thread->status != THREADSTATUS_RUNNING); + thread->status = THREADSTATUS_WAIT_MUTEX; + thread->wakeup_callback = nullptr; - // Wakeup all or one thread - Any other value is unimplemented - ASSERT(target == -1 || target == 1); + // Signal that the mutex now has a waiting thread. + Memory::Write32(thread->mutex_wait_address, mutex_val | Mutex::MutexHasWaitersFlag); - 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).Unwrap(); - condition_variable->name = - Common::StringFromFormat("condition-variable-%llx", condition_variable_addr); - } + owner->AddMutexWaiter(thread); - CASCADE_CODE(condition_variable->Release(target)); + Core::System::GetInstance().PrepareReschedule(); + } - if (condition_variable->mutex_addr) { - // If a mutex was created for this condition_variable, wait the current thread on it - SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(condition_variable->mutex_addr); - return WaitSynchronization1(mutex, GetCurrentThread()); + ++processed; } return RESULT_SUCCESS; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index f3a8aa4aa..36222d45f 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -77,9 +77,6 @@ void Thread::Stop() { } wait_objects.clear(); - // Release all the mutexes that this thread holds - ReleaseThreadMutexes(this); - // Mark the TLS slot in the thread's page as free. u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; u64 tls_slot = @@ -126,6 +123,19 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { resume = thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr, 0); } + if (thread->mutex_wait_address != 0 || thread->condvar_wait_address != 0 || + thread->wait_handle) { + ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); + thread->mutex_wait_address = 0; + thread->condvar_wait_address = 0; + thread->wait_handle = 0; + + auto lock_owner = thread->lock_owner; + // Threads waking up by timeout from WaitProcessWideKey do not perform priority inheritance + // and don't have a lock owner. + ASSERT(lock_owner == nullptr); + } + if (resume) thread->ResumeFromWait(); } @@ -151,6 +161,7 @@ void Thread::ResumeFromWait() { case THREADSTATUS_WAIT_HLE_EVENT: case THREADSTATUS_WAIT_SLEEP: case THREADSTATUS_WAIT_IPC: + case THREADSTATUS_WAIT_MUTEX: break; case THREADSTATUS_READY: @@ -256,7 +267,9 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, thread->last_running_ticks = CoreTiming::GetTicks(); thread->processor_id = processor_id; thread->wait_objects.clear(); - thread->wait_address = 0; + thread->mutex_wait_address = 0; + thread->condvar_wait_address = 0; + thread->wait_handle = 0; thread->name = std::move(name); thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap(); thread->owner_process = owner_process; @@ -317,17 +330,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, void Thread::SetPriority(u32 priority) { ASSERT_MSG(priority <= THREADPRIO_LOWEST && priority >= THREADPRIO_HIGHEST, "Invalid priority value."); - Core::System::GetInstance().Scheduler().SetThreadPriority(this, priority); - nominal_priority = current_priority = priority; -} - -void Thread::UpdatePriority() { - u32 best_priority = nominal_priority; - for (auto& mutex : held_mutexes) { - if (mutex->priority < best_priority) - best_priority = mutex->priority; - } - BoostPriority(best_priority); + nominal_priority = priority; + UpdatePriority(); } void Thread::BoostPriority(u32 priority) { @@ -377,6 +381,38 @@ VAddr Thread::GetCommandBufferAddress() const { return GetTLSAddress() + CommandHeaderOffset; } +void Thread::AddMutexWaiter(SharedPtr<Thread> thread) { + thread->lock_owner = this; + wait_mutex_threads.emplace_back(std::move(thread)); + UpdatePriority(); +} + +void Thread::RemoveMutexWaiter(SharedPtr<Thread> thread) { + boost::remove_erase(wait_mutex_threads, thread); + thread->lock_owner = nullptr; + UpdatePriority(); +} + +void Thread::UpdatePriority() { + // Find the highest priority among all the threads that are waiting for this thread's lock + u32 new_priority = nominal_priority; + for (const auto& thread : wait_mutex_threads) { + if (thread->nominal_priority < new_priority) + new_priority = thread->nominal_priority; + } + + if (new_priority == current_priority) + return; + + Core::System::GetInstance().Scheduler().SetThreadPriority(this, new_priority); + + current_priority = new_priority; + + // Recursively update the priority of the thread that depends on the priority of this one. + if (lock_owner) + lock_owner->UpdatePriority(); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// /** diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index dbf47e269..e0a3c0934 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -18,7 +18,7 @@ enum ThreadPriority : u32 { THREADPRIO_HIGHEST = 0, ///< Highest thread priority THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps - THREADPRIO_DEFAULT = 48, ///< Default thread priority for userland apps + THREADPRIO_DEFAULT = 44, ///< Default thread priority for userland apps THREADPRIO_LOWEST = 63, ///< Lowest thread priority }; @@ -43,6 +43,7 @@ enum ThreadStatus { THREADSTATUS_WAIT_IPC, ///< Waiting for the reply from an IPC request THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true + THREADSTATUS_WAIT_MUTEX, ///< Waiting due to an ArbitrateLock/WaitProcessWideKey svc THREADSTATUS_DORMANT, ///< Created but not yet made ready THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated }; @@ -54,7 +55,6 @@ enum class ThreadWakeupReason { namespace Kernel { -class Mutex; class Process; class Thread final : public WaitObject { @@ -104,17 +104,20 @@ public: void SetPriority(u32 priority); /** - * Boost's a thread's priority to the best priority among the thread's held mutexes. - * This prevents priority inversion via priority inheritance. - */ - void UpdatePriority(); - - /** * Temporarily boosts the thread's priority until the next time it is scheduled * @param priority The new priority */ void BoostPriority(u32 priority); + /// Adds a thread to the list of threads that are waiting for a lock held by this thread. + void AddMutexWaiter(SharedPtr<Thread> thread); + + /// Removes a thread from the list of threads that are waiting for a lock held by this thread. + void RemoveMutexWaiter(SharedPtr<Thread> thread); + + /// Recalculates the current priority taking into account priority inheritance. + void UpdatePriority(); + /** * Gets the thread's thread ID * @return The thread's ID @@ -205,19 +208,22 @@ public: VAddr tls_address; ///< Virtual address of the Thread Local Storage of the thread - /// Mutexes currently held by this thread, which will be released when it exits. - boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; - - /// Mutexes that this thread is currently waiting for. - boost::container::flat_set<SharedPtr<Mutex>> pending_mutexes; - SharedPtr<Process> owner_process; ///< Process that owns this thread /// Objects that the thread is waiting on, in the same order as they were // passed to WaitSynchronization1/N. std::vector<SharedPtr<WaitObject>> wait_objects; - VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address + /// List of threads that are waiting for a mutex that is held by this thread. + std::vector<SharedPtr<Thread>> wait_mutex_threads; + + /// Thread that owns the lock that this thread is waiting for. + SharedPtr<Thread> lock_owner; + + // If waiting on a ConditionVariable, this is the ConditionVariable address + VAddr condvar_wait_address; + VAddr mutex_wait_address; ///< If waiting on a Mutex, this is the mutex address + Handle wait_handle; ///< The handle used to wait for the mutex. std::string name; diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 6bafb2dce..f2fffa760 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -47,7 +47,7 @@ public: private: void GetBase(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); ProfileBase profile_base{}; IPC::ResponseBuilder rb{ctx, 16}; rb.Push(RESULT_SUCCESS); @@ -72,14 +72,14 @@ public: private: void CheckAvailability(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(true); // TODO: Check when this is supposed to return true and when not } void GetAccountId(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(0x12345678ABCDEF); @@ -87,14 +87,14 @@ private: }; void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(true); // TODO: Check when this is supposed to return true and when not } void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID}; ctx.WriteBuffer(user_ids.data(), user_ids.size()); IPC::ResponseBuilder rb{ctx, 2}; @@ -102,7 +102,7 @@ void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { } void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID}; ctx.WriteBuffer(user_ids.data(), user_ids.size()); IPC::ResponseBuilder rb{ctx, 2}; @@ -113,11 +113,11 @@ void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IProfile>(); - LOG_DEBUG(Service_ACC, "called"); + NGLOG_DEBUG(Service_ACC, "called"); } void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -126,11 +126,11 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IManagerForApplication>(); - LOG_DEBUG(Service_ACC, "called"); + NGLOG_DEBUG(Service_ACC, "called"); } void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + NGLOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 6}; rb.Push(RESULT_SUCCESS); rb.PushRaw(DEFAULT_USER_ID); diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index f41a59afe..19fadcb8e 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -28,14 +28,14 @@ IWindowController::IWindowController() : ServiceFramework("IWindowController") { } void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(0); } void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -54,20 +54,20 @@ IAudioController::IAudioController() : ServiceFramework("IAudioController") { } void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(volume); } void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(volume); @@ -139,14 +139,14 @@ void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) { @@ -157,14 +157,14 @@ void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestCo IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called flag=%u", static_cast<u32>(flag)); + NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag); } void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) { @@ -175,7 +175,7 @@ void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestCont IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called flag=%u", static_cast<u32>(flag)); + NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag); } void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) { @@ -188,21 +188,21 @@ void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called enabled=%u", static_cast<u32>(enabled)); + NGLOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled); } void ISelfController::LockExit(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { @@ -212,7 +212,7 @@ void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(launchable_event); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) { @@ -225,7 +225,7 @@ void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) rb.Push(RESULT_SUCCESS); rb.Push(layer_id); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") { @@ -269,7 +269,7 @@ void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(event); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) { @@ -277,7 +277,7 @@ void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push<u32>(15); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { @@ -285,7 +285,7 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push(static_cast<u8>(FocusState::InFocus)); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { @@ -294,7 +294,7 @@ void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld)); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) { @@ -304,7 +304,7 @@ void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) { rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked : APM::PerformanceMode::Handheld)); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { @@ -344,7 +344,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(state_changed_event); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } Kernel::SharedPtr<Kernel::Event> state_changed_event; @@ -368,7 +368,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<AM::ILibraryAppletAccessor>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { @@ -392,7 +392,7 @@ private: rb.Push(RESULT_SUCCESS); rb.Push(static_cast<u64>(buffer.size())); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void Read(Kernel::HLERequestContext& ctx) { @@ -410,7 +410,7 @@ private: rb.Push(RESULT_SUCCESS); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } }; @@ -434,7 +434,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<AM::IStorageAccessor>(buffer); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } }; @@ -498,14 +498,14 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<AM::IStorage>(buffer); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; u128 uid = rp.PopRaw<u128>(); - LOG_WARNING(Service, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]); + NGLOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); IPC::ResponseBuilder rb{ctx, 4}; @@ -533,27 +533,27 @@ void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called, result=0x%08X", result); + NGLOG_WARNING(Service_AM, "(STUBBED) called, result={:#010}", result); } void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(SystemLanguage::English); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) { @@ -561,7 +561,7 @@ void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push<u8>(0); // Unknown, seems to be ignored by official processes - LOG_WARNING(Service_AM, "(STUBBED) called"); + NGLOG_WARNING(Service_AM, "(STUBBED) called"); } void InstallInterfaces(SM::ServiceManager& service_manager, diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp index 4f0698a8a..8951980cf 100644 --- a/src/core/hle/service/am/applet_ae.cpp +++ b/src/core/hle/service/am/applet_ae.cpp @@ -33,56 +33,56 @@ private: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ICommonStateGetter>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetSelfController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ISelfController>(nvflinger); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetWindowController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IWindowController>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetAudioController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IAudioController>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetDisplayController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IDisplayController>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetDebugFunctions(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IDebugFunctions>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ILibraryAppletCreator>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IApplicationFunctions>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } std::shared_ptr<NVFlinger::NVFlinger> nvflinger; @@ -92,7 +92,7 @@ void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index 674b4d753..68388bf5e 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp @@ -33,56 +33,56 @@ private: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IAudioController>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetDisplayController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IDisplayController>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetDebugFunctions(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IDebugFunctions>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetWindowController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IWindowController>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetSelfController(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ISelfController>(nvflinger); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ICommonStateGetter>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ILibraryAppletCreator>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IApplicationFunctions>(); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } std::shared_ptr<NVFlinger::NVFlinger> nvflinger; @@ -92,7 +92,7 @@ void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IApplicationProxy>(nvflinger); - LOG_DEBUG(Service_AM, "called"); + NGLOG_DEBUG(Service_AM, "called"); } AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index 6e7438580..5b6dfb48f 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp @@ -27,14 +27,14 @@ void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(0); - LOG_WARNING(Service_AOC, "(STUBBED) called"); + NGLOG_WARNING(Service_AOC, "(STUBBED) called"); } void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(0); - LOG_WARNING(Service_AOC, "(STUBBED) called"); + NGLOG_WARNING(Service_AOC, "(STUBBED) called"); } void InstallInterfaces(SM::ServiceManager& service_manager) { diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp index 4e11f3f14..3a03188ce 100644 --- a/src/core/hle/service/apm/interface.cpp +++ b/src/core/hle/service/apm/interface.cpp @@ -29,8 +29,8 @@ private: IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_APM, "(STUBBED) called mode=%u config=%u", static_cast<u32>(mode), - config); + NGLOG_WARNING(Service_APM, "(STUBBED) called mode={} config={}", static_cast<u32>(mode), + config); } void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { @@ -42,7 +42,7 @@ private: rb.Push(RESULT_SUCCESS); rb.Push<u32>(0); // Performance configuration - LOG_WARNING(Service_APM, "(STUBBED) called mode=%u", static_cast<u32>(mode)); + NGLOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast<u32>(mode)); } }; diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 2d7f8cb04..6297dc450 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -60,14 +60,14 @@ public: private: void GetAudioOutState(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "called"); + NGLOG_DEBUG(Service_Audio, "called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(static_cast<u32>(audio_out_state)); } void StartAudioOut(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); // Start audio audio_out_state = AudioState::Started; @@ -77,7 +77,7 @@ private: } void StopAudioOut(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); // Stop audio audio_out_state = AudioState::Stopped; @@ -89,7 +89,7 @@ private: } void RegisterBufferEvent(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); @@ -97,7 +97,7 @@ private: } void AppendAudioOutBuffer(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::RequestParser rp{ctx}; const u64 key{rp.Pop<u64>()}; @@ -108,7 +108,7 @@ private: } void GetReleasedAudioOutBuffer(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); // TODO(st4rk): This is how libtransistor currently implements the // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address @@ -164,7 +164,7 @@ private: }; void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::RequestParser rp{ctx}; const std::string audio_interface = "AudioInterface"; @@ -180,7 +180,7 @@ void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) { } void AudOutU::OpenAudioOut(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); if (!audio_out_interface) { audio_out_interface = std::make_shared<IAudioOut>(); diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index d9245cb19..72810b436 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -56,7 +56,7 @@ private: } void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_Audio, "%s", ctx.Description().c_str()); + NGLOG_DEBUG(Service_Audio, "{}", ctx.Description()); AudioRendererResponseData response_data{}; response_data.section_0_size = @@ -79,7 +79,7 @@ private: rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); } void StartAudioRenderer(Kernel::HLERequestContext& ctx) { @@ -87,7 +87,7 @@ private: rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); } void StopAudioRenderer(Kernel::HLERequestContext& ctx) { @@ -95,7 +95,7 @@ private: rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); } void QuerySystemEvent(Kernel::HLERequestContext& ctx) { @@ -105,7 +105,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(system_event); - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); } struct AudioRendererStateEntry { @@ -176,7 +176,7 @@ public: private: void ListAudioDeviceName(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::RequestParser rp{ctx}; const std::string audio_interface = "AudioInterface"; @@ -188,7 +188,7 @@ private: } void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::RequestParser rp{ctx}; f32 volume = static_cast<f32>(rp.Pop<u32>()); @@ -201,7 +201,7 @@ private: } void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::RequestParser rp{ctx}; const std::string audio_interface = "AudioDevice"; @@ -213,7 +213,7 @@ private: } void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); buffer_event->Signal(); @@ -223,7 +223,7 @@ private: } void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(1); @@ -250,7 +250,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<Audio::IAudioRenderer>(); - LOG_DEBUG(Service_Audio, "called"); + NGLOG_DEBUG(Service_Audio, "called"); } void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { @@ -259,7 +259,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push<u64>(0x400); - LOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_WARNING(Service_Audio, "(STUBBED) called"); } void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { @@ -268,7 +268,7 @@ void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<Audio::IAudioDevice>(); - LOG_DEBUG(Service_Audio, "called"); + NGLOG_DEBUG(Service_Audio, "called"); } } // namespace Service::Audio diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 41d58f999..d7ad0600a 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp @@ -16,13 +16,13 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) void Module::Interface::FatalSimple(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx); u32 error_code = rp.Pop<u32>(); - LOG_WARNING(Service_Fatal, "(STUBBED) called, error_code=0x%X", error_code); + NGLOG_WARNING(Service_Fatal, "(STUBBED) called, error_code={:#X}", error_code); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void Module::Interface::TransitionToFatalError(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Fatal, "(STUBBED) called"); + NGLOG_WARNING(Service_Fatal, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 9e504992f..c2951c560 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -25,14 +25,14 @@ ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& fact ASSERT_MSG(inserted, "Tried to register more than one system with same id code"); auto& filesystem = result.first->second; - LOG_DEBUG(Service_FS, "Registered file system %s with id code 0x%08X", - filesystem->GetName().c_str(), static_cast<u32>(type)); + NGLOG_DEBUG(Service_FS, "Registered file system {} with id code {:#010X}", + filesystem->GetName(), static_cast<u32>(type)); return RESULT_SUCCESS; } ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, FileSys::Path& path) { - LOG_TRACE(Service_FS, "Opening FileSystem with type=%d", type); + NGLOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type)); auto itr = filesystem_map.find(type); if (itr == filesystem_map.end()) { @@ -44,7 +44,7 @@ ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, } ResultCode FormatFileSystem(Type type) { - LOG_TRACE(Service_FS, "Formatting FileSystem with type=%d", type); + NGLOG_TRACE(Service_FS, "Formatting FileSystem with type={}", static_cast<u32>(type)); auto itr = filesystem_map.find(type); if (itr == filesystem_map.end()) { diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 2f476c869..ed9f2ef72 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -35,7 +35,7 @@ private: const s64 offset = rp.Pop<s64>(); const s64 length = rp.Pop<s64>(); - LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length); + NGLOG_DEBUG(Service_FS, "called, offset={:#X}, length={}", offset, length); // Error checking if (length < 0) { @@ -87,7 +87,7 @@ private: const s64 offset = rp.Pop<s64>(); const s64 length = rp.Pop<s64>(); - LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length); + NGLOG_DEBUG(Service_FS, "called, offset={:#X}, length={}", offset, length); // Error checking if (length < 0) { @@ -124,7 +124,7 @@ private: const s64 offset = rp.Pop<s64>(); const s64 length = rp.Pop<s64>(); - LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length); + NGLOG_DEBUG(Service_FS, "called, offset={:#X}, length={}", offset, length); // Error checking if (length < 0) { @@ -152,7 +152,7 @@ private: } void Flush(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); + NGLOG_DEBUG(Service_FS, "called"); backend->Flush(); IPC::ResponseBuilder rb{ctx, 2}; @@ -163,7 +163,7 @@ private: IPC::RequestParser rp{ctx}; const u64 size = rp.Pop<u64>(); backend->SetSize(size); - LOG_DEBUG(Service_FS, "called, size=%" PRIu64, size); + NGLOG_DEBUG(Service_FS, "called, size={}", size); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -171,7 +171,7 @@ private: void GetSize(Kernel::HLERequestContext& ctx) { const u64 size = backend->GetSize(); - LOG_DEBUG(Service_FS, "called, size=%" PRIu64, size); + NGLOG_DEBUG(Service_FS, "called, size={}", size); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); @@ -197,7 +197,7 @@ private: IPC::RequestParser rp{ctx}; const u64 unk = rp.Pop<u64>(); - LOG_DEBUG(Service_FS, "called, unk=0x%llx", unk); + NGLOG_DEBUG(Service_FS, "called, unk={:#X}", unk); // Calculate how many entries we can fit in the output buffer u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry); @@ -219,7 +219,7 @@ private: } void GetEntryCount(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); + NGLOG_DEBUG(Service_FS, "called"); u64 count = backend->GetEntryCount(); @@ -239,7 +239,7 @@ public: {2, &IFileSystem::CreateDirectory, "CreateDirectory"}, {3, nullptr, "DeleteDirectory"}, {4, nullptr, "DeleteDirectoryRecursively"}, - {5, nullptr, "RenameFile"}, + {5, &IFileSystem::RenameFile, "RenameFile"}, {6, nullptr, "RenameDirectory"}, {7, &IFileSystem::GetEntryType, "GetEntryType"}, {8, &IFileSystem::OpenFile, "OpenFile"}, @@ -265,8 +265,7 @@ public: u64 mode = rp.Pop<u64>(); u32 size = rp.Pop<u32>(); - LOG_DEBUG(Service_FS, "called file %s mode 0x%" PRIX64 " size 0x%08X", name.c_str(), mode, - size); + NGLOG_DEBUG(Service_FS, "called file {} mode {:#X} size {:#010X}", name, mode, size); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(backend->CreateFile(name, size)); @@ -280,7 +279,7 @@ public: std::string name(file_buffer.begin(), end); - LOG_DEBUG(Service_FS, "called file %s", name.c_str()); + NGLOG_DEBUG(Service_FS, "called file {}", name); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(backend->DeleteFile(name)); @@ -294,12 +293,32 @@ public: std::string name(file_buffer.begin(), end); - LOG_DEBUG(Service_FS, "called directory %s", name.c_str()); + NGLOG_DEBUG(Service_FS, "called directory {}", name); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(backend->CreateDirectory(name)); } + void RenameFile(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + std::vector<u8> buffer; + buffer.resize(ctx.BufferDescriptorX()[0].Size()); + Memory::ReadBlock(ctx.BufferDescriptorX()[0].Address(), buffer.data(), buffer.size()); + auto end = std::find(buffer.begin(), buffer.end(), '\0'); + std::string src_name(buffer.begin(), end); + + buffer.resize(ctx.BufferDescriptorX()[1].Size()); + Memory::ReadBlock(ctx.BufferDescriptorX()[1].Address(), buffer.data(), buffer.size()); + end = std::find(buffer.begin(), buffer.end(), '\0'); + std::string dst_name(buffer.begin(), end); + + NGLOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(backend->RenameFile(src_name, dst_name)); + } + void OpenFile(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; @@ -310,7 +329,7 @@ public: auto mode = static_cast<FileSys::Mode>(rp.Pop<u32>()); - LOG_DEBUG(Service_FS, "called file %s mode %u", name.c_str(), static_cast<u32>(mode)); + NGLOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast<u32>(mode)); auto result = backend->OpenFile(name, mode); if (result.Failed()) { @@ -337,7 +356,7 @@ public: // TODO(Subv): Implement this filter. u32 filter_flags = rp.Pop<u32>(); - LOG_DEBUG(Service_FS, "called directory %s filter %u", name.c_str(), filter_flags); + NGLOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags); auto result = backend->OpenDirectory(name); if (result.Failed()) { @@ -361,7 +380,7 @@ public: std::string name(file_buffer.begin(), end); - LOG_DEBUG(Service_FS, "called file %s", name.c_str()); + NGLOG_DEBUG(Service_FS, "called file {}", name); auto result = backend->GetEntryType(name); if (result.Failed()) { @@ -376,7 +395,7 @@ public: } void Commit(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -492,14 +511,14 @@ void FSP_SRV::TryLoadRomFS() { } void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); + NGLOG_DEBUG(Service_FS, "called"); FileSys::Path unused; auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap(); @@ -516,14 +535,14 @@ void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) { auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>(); u128 uid = rp.PopRaw<u128>(); - LOG_WARNING(Service_FS, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]); + NGLOG_WARNING(Service_FS, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); FileSys::Path unused; auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap(); @@ -534,7 +553,7 @@ void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { } void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); + NGLOG_WARNING(Service_FS, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); @@ -542,12 +561,12 @@ void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { } void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); + NGLOG_DEBUG(Service_FS, "called"); TryLoadRomFS(); if (!romfs) { // TODO (bunnei): Find the right error code to use here - LOG_CRITICAL(Service_FS, "no file system interface available!"); + NGLOG_CRITICAL(Service_FS, "no file system interface available!"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultCode(-1)); return; @@ -556,7 +575,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { // Attempt to open a StorageBackend interface to the RomFS auto storage = romfs->OpenFile({}, {}); if (storage.Failed()) { - LOG_CRITICAL(Service_FS, "no storage interface available!"); + NGLOG_CRITICAL(Service_FS, "no storage interface available!"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(storage.Code()); return; @@ -568,7 +587,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { } void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess"); + NGLOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess"); OpenDataStorageByCurrentProcess(ctx); } diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index c98a46e05..94d9fbf25 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp @@ -13,7 +13,7 @@ namespace Service::Friend { void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_Friend, "(STUBBED) called"); + NGLOG_WARNING(Service_Friend, "(STUBBED) called"); } Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index aad5e688b..736180b63 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -53,7 +53,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(shared_mem); - LOG_DEBUG(Service_HID, "called"); + NGLOG_DEBUG(Service_HID, "called"); } void LoadInputDevices() { @@ -184,7 +184,7 @@ private: void ActivateVibrationDevice(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } }; @@ -286,144 +286,144 @@ private: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IAppletResource>(applet_resource); - LOG_DEBUG(Service_HID, "called"); + NGLOG_DEBUG(Service_HID, "called"); } void ActivateDebugPad(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void ActivateTouchScreen(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void ActivateMouse(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void ActivateKeyboard(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void StartSixAxisSensor(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(0); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void ActivateNpad(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(event); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(joy_hold_type); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SendVibrationValue(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void GetActualVibrationValue(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(0); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IActiveVibrationDeviceList>(); - LOG_DEBUG(Service_HID, "called"); + NGLOG_DEBUG(Service_HID, "called"); } void SendVibrationValues(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + NGLOG_WARNING(Service_HID, "(STUBBED) called"); } }; diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index b87172dff..46194643e 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -141,19 +141,19 @@ private: if (header.IsTailLog()) { switch (header.severity) { case MessageHeader::Severity::Trace: - LOG_TRACE(Debug_Emulated, "%s", log_stream.str().c_str()); + NGLOG_TRACE(Debug_Emulated, "{}", log_stream.str()); break; case MessageHeader::Severity::Info: - LOG_INFO(Debug_Emulated, "%s", log_stream.str().c_str()); + NGLOG_INFO(Debug_Emulated, "{}", log_stream.str()); break; case MessageHeader::Severity::Warning: - LOG_WARNING(Debug_Emulated, "%s", log_stream.str().c_str()); + NGLOG_WARNING(Debug_Emulated, "{}", log_stream.str()); break; case MessageHeader::Severity::Error: - LOG_ERROR(Debug_Emulated, "%s", log_stream.str().c_str()); + NGLOG_ERROR(Debug_Emulated, "{}", log_stream.str()); break; case MessageHeader::Severity::Critical: - LOG_CRITICAL(Debug_Emulated, "%s", log_stream.str().c_str()); + NGLOG_CRITICAL(Debug_Emulated, "{}", log_stream.str()); break; } } @@ -178,7 +178,7 @@ void LM::Initialize(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<Logger>(); - LOG_DEBUG(Service_LM, "called"); + NGLOG_DEBUG(Service_LM, "called"); } LM::LM() : ServiceFramework("lm") { diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index 91e5f527a..6627aaddc 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp @@ -13,7 +13,7 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) : ServiceFramework(name), module(std::move(module)) {} void Module::Interface::Unknown(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NFP, "(STUBBED) called"); + NGLOG_WARNING(Service_NFP, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index df1e7f8fe..eee92cfcd 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp @@ -62,24 +62,24 @@ public: private: void GetRequestState(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(0); } void GetResult(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void GetSystemEventReadableHandles(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 2}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(event1, event2); } void Cancel(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -105,7 +105,7 @@ public: private: void GetClientId(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(0); @@ -116,7 +116,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IScanRequest>(); - LOG_DEBUG(Service_NIFM, "called"); + NGLOG_DEBUG(Service_NIFM, "called"); } void CreateRequest(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; @@ -124,10 +124,10 @@ private: rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IRequest>(); - LOG_DEBUG(Service_NIFM, "called"); + NGLOG_DEBUG(Service_NIFM, "called"); } void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NIFM, "(STUBBED) called"); + NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -137,7 +137,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<INetworkProfile>(); - LOG_DEBUG(Service_NIFM, "called"); + NGLOG_DEBUG(Service_NIFM, "called"); } }; @@ -187,14 +187,14 @@ void Module::Interface::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IGeneralService>(); - LOG_DEBUG(Service_NIFM, "called"); + NGLOG_DEBUG(Service_NIFM, "called"); } void Module::Interface::CreateGeneralService(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IGeneralService>(); - LOG_DEBUG(Service_NIFM, "called"); + NGLOG_DEBUG(Service_NIFM, "called"); } Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index c416ad720..c2a647e89 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -52,7 +52,7 @@ PL_U::PL_U() : ServiceFramework("pl:u") { ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE); file.ReadBytes(shared_font->data(), shared_font->size()); } else { - LOG_WARNING(Service_NS, "Unable to load shared font: %s", filepath.c_str()); + NGLOG_WARNING(Service_NS, "Unable to load shared font: {}", filepath); } } @@ -60,7 +60,7 @@ void PL_U::RequestLoad(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u32 shared_font_type{rp.Pop<u32>()}; - LOG_DEBUG(Service_NS, "called, shared_font_type=%d", shared_font_type); + NGLOG_DEBUG(Service_NS, "called, shared_font_type={}", shared_font_type); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -69,7 +69,7 @@ void PL_U::GetLoadState(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u32 font_id{rp.Pop<u32>()}; - LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); + NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(static_cast<u32>(LoadState::Done)); @@ -79,7 +79,7 @@ void PL_U::GetSize(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u32 font_id{rp.Pop<u32>()}; - LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); + NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(SHARED_FONT_REGIONS[font_id].size); @@ -89,7 +89,7 @@ void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u32 font_id{rp.Pop<u32>()}; - LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); + NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(SHARED_FONT_REGIONS[font_id].offset); @@ -110,7 +110,7 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE, "PL_U:shared_font_mem"); - LOG_DEBUG(Service_NS, "called"); + NGLOG_DEBUG(Service_NS, "called"); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(shared_font_mem); diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 61f22b1a5..103e66d0c 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -13,16 +13,16 @@ namespace Service::Nvidia::Devices { u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; } void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform) { VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); - LOG_WARNING(Service, - "Drawing from address %lx offset %08X Width %u Height %u Stride %u Format %u", addr, - offset, width, height, stride, format); + NGLOG_WARNING(Service, + "Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}", + addr, offset, width, height, stride, format); using PixelFormat = Tegra::FramebufferConfig::PixelFormat; const Tegra::FramebufferConfig framebuffer{ diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 71e844959..36d7f837b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -12,8 +12,8 @@ namespace Service::Nvidia::Devices { u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { - LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", - command.raw, input.size(), output.size()); + NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", + command.raw, input.size(), output.size()); switch (static_cast<IoctlCommand>(command.raw)) { case IoctlCommand::IocInitalizeExCommand: @@ -27,13 +27,18 @@ u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vecto case IoctlCommand::IocGetVaRegionsCommand: return GetVARegions(input, output); } + + if (static_cast<IoctlCommand>(command.cmd.Value()) == IoctlCommand::IocRemapCommand) + return Remap(input, output); + + UNIMPLEMENTED_MSG("Unimplemented ioctl command"); return 0; } u32 nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output) { IoctlInitalizeEx params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size=0x%x", params.big_page_size); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size={:#X}", params.big_page_size); std::memcpy(output.data(), ¶ms, output.size()); return 0; } @@ -41,8 +46,8 @@ u32 nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& ou u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output) { IoctlAllocSpace params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, "called, pages=%x, page_size=%x, flags=%x", params.pages, - params.page_size, params.flags); + NGLOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages, + params.page_size, params.flags); auto& gpu = Core::System::GetInstance().GPU(); const u64 size{static_cast<u64>(params.pages) * static_cast<u64>(params.page_size)}; @@ -56,15 +61,45 @@ u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& return 0; } +u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) { + size_t num_entries = input.size() / sizeof(IoctlRemapEntry); + + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries=0x{:X}", num_entries); + + std::vector<IoctlRemapEntry> entries(num_entries); + std::memcpy(entries.data(), input.data(), input.size()); + + auto& gpu = Core::System::GetInstance().GPU(); + + for (const auto& entry : entries) { + NGLOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}", + entry.offset, entry.nvmap_handle, entry.pages); + Tegra::GPUVAddr offset = static_cast<Tegra::GPUVAddr>(entry.offset) << 0x10; + + auto object = nvmap_dev->GetObject(entry.nvmap_handle); + ASSERT(object); + + ASSERT(object->status == nvmap::Object::Status::Allocated); + + u64 size = static_cast<u64>(entry.pages) << 0x10; + ASSERT(size <= object->size); + + Tegra::GPUVAddr returned = gpu.memory_manager->MapBufferEx(object->addr, offset, size); + ASSERT(returned == offset); + } + std::memcpy(output.data(), entries.data(), output.size()); + return 0; +} + u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { IoctlMapBufferEx params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, - "called, flags=%x, nvmap_handle=%x, buffer_offset=%" PRIu64 ", mapping_size=%" PRIu64 - ", offset=%" PRIu64, - params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size, - params.offset); + NGLOG_DEBUG(Service_NVDRV, + "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" + ", offset={}", + params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size, + params.offset); if (!params.nvmap_handle) { return 0; @@ -73,6 +108,16 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& ou auto object = nvmap_dev->GetObject(params.nvmap_handle); ASSERT(object); + // We can only map objects that have already been assigned a CPU address. + ASSERT(object->status == nvmap::Object::Status::Allocated); + + ASSERT(params.buffer_offset == 0); + + // The real nvservices doesn't make a distinction between handles and ids, and + // object can only have one handle and it will be the same as its id. Assert that this is the + // case to prevent unexpected behavior. + ASSERT(object->id == params.nvmap_handle); + auto& gpu = Core::System::GetInstance().GPU(); if (params.flags & 1) { @@ -88,7 +133,7 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& ou u32 nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& output) { IoctlBindChannel params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, "called, fd=%x", params.fd); + NGLOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); channel = params.fd; std::memcpy(output.data(), ¶ms, output.size()); return 0; @@ -97,8 +142,8 @@ u32 nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& ou u32 nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u8>& output) { IoctlGetVaRegions params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr=%" PRIu64 ", buf_size=%x", - params.buf_addr, params.buf_size); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr={:X}, buf_size={:X}", params.buf_addr, + params.buf_size); params.buf_size = 0x30; params.regions[0].offset = 0x04000000; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index d86c3ebd9..f2dd0c3b3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h @@ -26,6 +26,7 @@ private: enum class IoctlCommand : u32_le { IocInitalizeExCommand = 0x40284109, IocAllocateSpaceCommand = 0xC0184102, + IocRemapCommand = 0x00000014, IocMapBufferExCommand = 0xC0284106, IocBindChannelCommand = 0x40044101, IocGetVaRegionsCommand = 0xC0404108, @@ -54,6 +55,16 @@ private: }; static_assert(sizeof(IoctlAllocSpace) == 24, "IoctlInitalizeEx is incorrect size"); + struct IoctlRemapEntry { + u16_le flags; + u16_le kind; + u32_le nvmap_handle; + INSERT_PADDING_WORDS(1); + u32_le offset; + u32_le pages; + }; + static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size"); + struct IoctlMapBufferEx { u32_le flags; // bit0: fixed_offset, bit2: cacheable u32_le kind; // -1 is default @@ -91,6 +102,7 @@ private: u32 InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output); u32 AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output); + u32 Remap(const std::vector<u8>& input, std::vector<u8>& output); u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output); u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 660a0f665..46f0b6862 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -9,8 +9,8 @@ namespace Service::Nvidia::Devices { u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { - LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", - command.raw, input.size(), output.size()); + NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", + command.raw, input.size(), output.size()); switch (static_cast<IoctlCommand>(command.raw)) { case IoctlCommand::IocGetConfigCommand: @@ -18,15 +18,15 @@ u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector< case IoctlCommand::IocCtrlEventWaitCommand: return IocCtrlEventWait(input, output); } - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; } u32 nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output) { IocGetConfigParams params{}; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_DEBUG(Service_NVDRV, "called, setting=%s!%s", params.domain_str.data(), - params.param_str.data()); + NGLOG_DEBUG(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(), + params.param_str.data()); if (!strcmp(params.domain_str.data(), "nv")) { if (!strcmp(params.param_str.data(), "NV_MEMORY_PROFILER")) { @@ -48,8 +48,8 @@ u32 nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output) { IocCtrlEventWaitParams params{}; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, syncpt_id=%u threshold=%u timeout=%d", - params.syncpt_id, params.threshold, params.timeout); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, syncpt_id={} threshold={} timeout={}", + params.syncpt_id, params.threshold, params.timeout); // TODO(Subv): Implement actual syncpt waiting. params.value = 0; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 18ea12ef5..1e457ae6e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -10,8 +10,8 @@ namespace Service::Nvidia::Devices { u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { - LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", - command.raw, input.size(), output.size()); + NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", + command.raw, input.size(), output.size()); switch (static_cast<IoctlCommand>(command.raw)) { case IoctlCommand::IocGetCharacteristicsCommand: @@ -25,12 +25,12 @@ u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vec case IoctlCommand::IocZcullGetInfo: return ZCullGetInfo(input, output); } - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; } u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlCharacteristics params{}; std::memcpy(¶ms, input.data(), input.size()); params.gc.arch = 0x120; @@ -77,14 +77,14 @@ u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vecto u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output) { IoctlGpuGetTpcMasksArgs params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, mask=0x%x, mask_buf_addr=0x%" PRIx64, - params.mask_buf_size, params.mask_buf_addr); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, mask={:#X}, mask_buf_addr={:#X}", + params.mask_buf_size, params.mask_buf_addr); std::memcpy(output.data(), ¶ms, sizeof(params)); return 0; } u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlActiveSlotMask params{}; std::memcpy(¶ms, input.data(), input.size()); params.slot = 0x07; @@ -94,7 +94,7 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector } u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlZcullGetCtxSize params{}; std::memcpy(¶ms, input.data(), input.size()); params.size = 0x1; @@ -103,7 +103,7 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u } u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlNvgpuGpuZcullGetInfoArgs params{}; std::memcpy(¶ms, input.data(), input.size()); params.width_align_pixels = 0x20; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index a16e90457..70625211e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -12,8 +12,8 @@ namespace Service::Nvidia::Devices { u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { - LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", - command.raw, input.size(), output.size()); + NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", + command.raw, input.size(), output.size()); switch (static_cast<IoctlCommand>(command.raw)) { case IoctlCommand::IocSetNVMAPfdCommand: @@ -40,21 +40,21 @@ u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u } } - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; }; u32 nvhost_gpu::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { IoctlSetNvmapFD params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, "called, fd=%x", params.nvmap_fd); + NGLOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); nvmap_fd = params.nvmap_fd; std::memcpy(output.data(), ¶ms, output.size()); return 0; } u32 nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlClientData params{}; std::memcpy(¶ms, input.data(), input.size()); user_data = params.data; @@ -63,7 +63,7 @@ u32 nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>& out } u32 nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>& output) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IoctlClientData params{}; std::memcpy(¶ms, input.data(), input.size()); params.data = user_data; @@ -73,8 +73,8 @@ u32 nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>& out u32 nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& output) { std::memcpy(&zcull_params, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, "called, gpu_va=%" PRIx64 ", mode=%x", zcull_params.gpu_va, - zcull_params.mode); + NGLOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va, + zcull_params.mode); std::memcpy(output.data(), &zcull_params, output.size()); return 0; } @@ -82,15 +82,15 @@ u32 nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& output) u32 nvhost_gpu::SetErrorNotifier(const std::vector<u8>& input, std::vector<u8>& output) { IoctlSetErrorNotifier params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset=%" PRIx64 ", size=%" PRIx64 ", mem=%x", - params.offset, params.size, params.mem); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", + params.offset, params.size, params.mem); std::memcpy(output.data(), ¶ms, output.size()); return 0; } u32 nvhost_gpu::SetChannelPriority(const std::vector<u8>& input, std::vector<u8>& output) { std::memcpy(&channel_priority, input.data(), input.size()); - LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority=%x", channel_priority); + NGLOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority); std::memcpy(output.data(), &channel_priority, output.size()); return 0; } @@ -98,10 +98,11 @@ u32 nvhost_gpu::SetChannelPriority(const std::vector<u8>& input, std::vector<u8> u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output) { IoctlAllocGpfifoEx2 params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, - "(STUBBED) called, num_entries=%x, flags=%x, unk0=%x, unk1=%x, unk2=%x, unk3=%x", - params.num_entries, params.flags, params.unk0, params.unk1, params.unk2, - params.unk3); + NGLOG_WARNING(Service_NVDRV, + "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " + "unk1={:X}, unk2={:X}, unk3={:X}", + params.num_entries, params.flags, params.unk0, params.unk1, params.unk2, + params.unk3); params.fence_out.id = 0; params.fence_out.value = 0; std::memcpy(output.data(), ¶ms, output.size()); @@ -111,8 +112,8 @@ u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& ou u32 nvhost_gpu::AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output) { IoctlAllocObjCtx params{}; std::memcpy(¶ms, input.data(), input.size()); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num=%x, flags=%x", params.class_num, - params.flags); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num, + params.flags); params.obj_id = 0x0; std::memcpy(output.data(), ¶ms, output.size()); return 0; @@ -123,8 +124,8 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp UNIMPLEMENTED(); IoctlSubmitGpfifo params{}; std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo=%" PRIx64 ", num_entries=%x, flags=%x", - params.gpfifo, params.num_entries, params.flags); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", + params.gpfifo, params.num_entries, params.flags); auto entries = std::vector<IoctlGpfifoEntry>(); entries.resize(params.num_entries); diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 4bb1f57f6..11df8849d 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -32,7 +32,7 @@ u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& o return IocParam(input, output); } - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; } @@ -49,7 +49,7 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { u32 handle = next_handle++; handles[handle] = std::move(object); - LOG_DEBUG(Service_NVDRV, "size=0x%08X", params.size); + NGLOG_DEBUG(Service_NVDRV, "size={:#010X}", params.size); params.handle = handle; @@ -70,7 +70,7 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { object->addr = params.addr; object->status = Object::Status::Allocated; - LOG_DEBUG(Service_NVDRV, "called, addr=0x%" PRIx64, params.addr); + NGLOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr); std::memcpy(output.data(), ¶ms, sizeof(params)); return 0; @@ -80,7 +80,7 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { IocGetIdParams params; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_WARNING(Service_NVDRV, "called"); + NGLOG_WARNING(Service_NVDRV, "called"); auto object = GetObject(params.handle); ASSERT(object); @@ -95,7 +95,7 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) { IocFromIdParams params; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); auto itr = std::find_if(handles.begin(), handles.end(), [&](const auto& entry) { return entry.second->id == params.id; }); @@ -114,7 +114,7 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { IocParamParams params; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_WARNING(Service_NVDRV, "(STUBBED) called type=%u", params.type); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.type); auto object = GetObject(params.handle); ASSERT(object); diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index d0d64a840..38b3a9a84 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp @@ -12,7 +12,7 @@ namespace Service::Nvidia { void NVDRV::Open(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); const auto& buffer = ctx.ReadBuffer(); std::string device_name(buffer.begin(), buffer.end()); @@ -25,7 +25,7 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) { } void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IPC::RequestParser rp{ctx}; u32 fd = rp.Pop<u32>(); @@ -41,7 +41,7 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { } void NVDRV::Close(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_NVDRV, "called"); + NGLOG_DEBUG(Service_NVDRV, "called"); IPC::RequestParser rp{ctx}; u32 fd = rp.Pop<u32>(); @@ -53,7 +53,7 @@ void NVDRV::Close(Kernel::HLERequestContext& ctx) { } void NVDRV::Initialize(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(0); @@ -63,7 +63,7 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; u32 fd = rp.Pop<u32>(); u32 event_id = rp.Pop<u32>(); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, fd=%x, event_id=%x", fd, event_id); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, fd={:X}, event_id={:X}", fd, event_id); IPC::ResponseBuilder rb{ctx, 3, 1}; rb.Push(RESULT_SUCCESS); @@ -75,14 +75,14 @@ void NVDRV::SetClientPID(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; pid = rp.Pop<u64>(); - LOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x%" PRIx64, pid); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, pid={:#X}", pid); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(0); } void NVDRV::FinishInitialize(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 03a4fed59..49e88b394 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -9,7 +9,8 @@ #include "core/core_timing.h" #include "core/hle/service/nvflinger/buffer_queue.h" -namespace Service::NVFlinger { +namespace Service { +namespace NVFlinger { BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { native_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "BufferQueue NativeHandle"); @@ -22,7 +23,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) { buffer.igbp_buffer = igbp_buffer; buffer.status = Buffer::Status::Free; - LOG_WARNING(Service, "Adding graphics buffer %u", slot); + NGLOG_WARNING(Service, "Adding graphics buffer {}", slot); queue.emplace_back(buffer); @@ -93,7 +94,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) { } u32 BufferQueue::Query(QueryType type) { - LOG_WARNING(Service, "(STUBBED) called type=%u", static_cast<u32>(type)); + NGLOG_WARNING(Service, "(STUBBED) called type={}", static_cast<u32>(type)); switch (type) { case QueryType::NativeWindowFormat: // TODO(Subv): Use an enum for this @@ -110,4 +111,5 @@ void BufferQueue::SetBufferWaitEvent(Kernel::SharedPtr<Kernel::Event>&& wait_eve buffer_wait_event = std::move(wait_event); } -} // namespace Service::NVFlinger +} // namespace NVFlinger +} // namespace Service diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 95adc4706..1de5767cb 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -13,7 +13,8 @@ namespace CoreTiming { struct EventType; } -namespace Service::NVFlinger { +namespace Service { +namespace NVFlinger { struct IGBPBuffer { u32_le magic; @@ -97,4 +98,5 @@ private: Kernel::SharedPtr<Kernel::Event> buffer_wait_event; }; -} // namespace Service::NVFlinger +} // namespace NVFlinger +} // namespace Service diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index a99ebc8e6..3481e48d0 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -48,7 +48,7 @@ NVFlinger::~NVFlinger() { } u64 NVFlinger::OpenDisplay(const std::string& name) { - LOG_WARNING(Service, "Opening display %s", name.c_str()); + NGLOG_WARNING(Service, "Opening display {}", name); // TODO(Subv): Currently we only support the Default display. ASSERT(name == "Default"); diff --git a/src/core/hle/service/pctl/pctl_a.cpp b/src/core/hle/service/pctl/pctl_a.cpp index 9fb4628ad..24a6cf310 100644 --- a/src/core/hle/service/pctl/pctl_a.cpp +++ b/src/core/hle/service/pctl/pctl_a.cpp @@ -113,7 +113,7 @@ void PCTL_A::CreateService(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IParentalControlService>(); - LOG_DEBUG(Service_PCTL, "called"); + NGLOG_DEBUG(Service_PCTL, "called"); } PCTL_A::PCTL_A() : ServiceFramework("pctl:a") { diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 08ce29677..5817819fe 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -120,7 +120,7 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext } buf.push_back('}'); - LOG_ERROR(Service, "unknown / unimplemented %s", fmt::to_string(buf).c_str()); + NGLOG_ERROR(Service, "unknown / unimplemented {}", fmt::to_string(buf)); UNIMPLEMENTED(); } @@ -131,8 +131,8 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) { return ReportUnimplementedFunction(ctx, info); } - LOG_TRACE( - Service, "%s", + NGLOG_TRACE( + Service, "{}", MakeFunctionString(info->name, GetServiceName().c_str(), ctx.CommandBuffer()).c_str()); handler_invoker(this, info->handler_callback, ctx); } @@ -199,12 +199,12 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) { VI::InstallInterfaces(*sm, nv_flinger); Set::InstallInterfaces(*sm); - LOG_DEBUG(Service, "initialized OK"); + NGLOG_DEBUG(Service, "initialized OK"); } /// Shutdown ServiceManager void Shutdown() { g_kernel_named_ports.clear(); - LOG_DEBUG(Service, "shutdown OK"); + NGLOG_DEBUG(Service, "shutdown OK"); } } // namespace Service diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index fc3e424d0..ece29aa70 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -22,7 +22,7 @@ void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_SET, "(STUBBED) called"); + NGLOG_WARNING(Service_SET, "(STUBBED) called"); } SET::SET() : ServiceFramework("set") { diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp index fa85277fe..762a664c5 100644 --- a/src/core/hle/service/set/set_sys.cpp +++ b/src/core/hle/service/set/set_sys.cpp @@ -16,7 +16,7 @@ void SET_SYS::GetColorSetId(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push<u32>(0); - LOG_WARNING(Service_SET, "(STUBBED) called"); + NGLOG_WARNING(Service_SET, "(STUBBED) called"); } SET_SYS::SET_SYS() : ServiceFramework("set:sys") { diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index 13e31620d..fe5097cdc 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp @@ -17,7 +17,7 @@ void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push<u32>(1); // Converted sessions start with 1 request handler - LOG_DEBUG(Service, "called, server_session=%d", ctx.Session()->GetObjectId()); + NGLOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetObjectId()); } void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { @@ -29,11 +29,11 @@ void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { Kernel::SharedPtr<Kernel::ClientSession> session{ctx.Session()->parent->client}; rb.PushMoveObjects(session); - LOG_DEBUG(Service, "called, session=%u", session->GetObjectId()); + NGLOG_DEBUG(Service, "called, session={}", session->GetObjectId()); } void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called, using DuplicateSession"); + NGLOG_WARNING(Service, "(STUBBED) called, using DuplicateSession"); DuplicateSession(ctx); } @@ -43,7 +43,7 @@ void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); rb.Push<u32>(0x500); - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); } Controller::Controller() : ServiceFramework("IpcController") { diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 4578fc05f..073277ade 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -86,7 +86,7 @@ SM::~SM() = default; void SM::Initialize(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_DEBUG(Service_SM, "called"); + NGLOG_DEBUG(Service_SM, "called"); } void SM::GetService(Kernel::HLERequestContext& ctx) { @@ -102,8 +102,8 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { if (client_port.Failed()) { IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); rb.Push(client_port.Code()); - LOG_ERROR(Service_SM, "called service=%s -> error 0x%08X", name.c_str(), - client_port.Code().raw); + NGLOG_ERROR(Service_SM, "called service={} -> error {:#010X}", name, + client_port.Code().raw); if (name.length() == 0) return; // LibNX Fix UNIMPLEMENTED(); @@ -113,8 +113,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { auto session = client_port.Unwrap()->Connect(); ASSERT(session.Succeeded()); if (session.Succeeded()) { - LOG_DEBUG(Service_SM, "called service=%s -> session=%u", name.c_str(), - (*session)->GetObjectId()); + NGLOG_DEBUG(Service_SM, "called service={} -> session={}", name, (*session)->GetObjectId()); IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles); rb.Push(session.Code()); diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index f99809bed..ab909fdaa 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -8,7 +8,7 @@ namespace Service::Sockets { void BSD::RegisterClient(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; @@ -17,7 +17,7 @@ void BSD::RegisterClient(Kernel::HLERequestContext& ctx) { } void BSD::StartMonitoring(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; @@ -32,7 +32,8 @@ void BSD::Socket(Kernel::HLERequestContext& ctx) { u32 type = rp.Pop<u32>(); u32 protocol = rp.Pop<u32>(); - LOG_WARNING(Service, "(STUBBED) called domain=%u type=%u protocol=%u", domain, type, protocol); + NGLOG_WARNING(Service, "(STUBBED) called domain={} type={} protocol={}", domain, type, + protocol); u32 fd = next_fd++; @@ -44,7 +45,7 @@ void BSD::Socket(Kernel::HLERequestContext& ctx) { } void BSD::Connect(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; @@ -54,7 +55,7 @@ void BSD::Connect(Kernel::HLERequestContext& ctx) { } void BSD::SendTo(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; @@ -64,7 +65,7 @@ void BSD::SendTo(Kernel::HLERequestContext& ctx) { } void BSD::Close(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index d235c4cfd..f377e59f2 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp @@ -10,7 +10,7 @@ namespace Service::Sockets { void SFDNSRES::GetAddrInfo(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - LOG_WARNING(Service, "(STUBBED) called"); + NGLOG_WARNING(Service, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp index 3f5a342a7..76ba97156 100644 --- a/src/core/hle/service/spl/module.cpp +++ b/src/core/hle/service/spl/module.cpp @@ -28,7 +28,7 @@ void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_DEBUG(Service_SPL, "called"); + NGLOG_DEBUG(Service_SPL, "called"); } void InstallInterfaces(SM::ServiceManager& service_manager) { diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 11d438728..c7788da5c 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp @@ -65,7 +65,7 @@ public: private: void SetOption(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_SSL, "(STUBBED) called"); + NGLOG_WARNING(Service_SSL, "(STUBBED) called"); IPC::RequestParser rp{ctx}; IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); @@ -73,7 +73,7 @@ private: } void CreateConnection(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_SSL, "(STUBBED) called"); + NGLOG_WARNING(Service_SSL, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -82,7 +82,7 @@ private: }; void SSL::CreateContext(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_SSL, "(STUBBED) called"); + NGLOG_WARNING(Service_SSL, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 2604ecc1c..278465358 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -32,14 +32,14 @@ private: const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>( std::chrono::system_clock::now().time_since_epoch()) .count()}; - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(time_since_epoch); } void GetSystemClockContext(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Time, "(STUBBED) called"); + NGLOG_WARNING(Service_Time, "(STUBBED) called"); SystemClockContext system_clock_ontext{}; IPC::ResponseBuilder rb{ctx, (sizeof(SystemClockContext) / 4) + 2}; rb.Push(RESULT_SUCCESS); @@ -58,7 +58,7 @@ public: private: void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); SteadyClockTimePoint steady_clock_time_point{cyclesToMs(CoreTiming::GetTicks()) / 1000}; IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2}; rb.Push(RESULT_SUCCESS); @@ -86,7 +86,7 @@ public: private: void GetDeviceLocationName(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Time, "(STUBBED) called"); + NGLOG_WARNING(Service_Time, "(STUBBED) called"); LocationName location_name{}; IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2}; rb.Push(RESULT_SUCCESS); @@ -94,14 +94,14 @@ private: } void GetTotalLocationNameCount(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Time, "(STUBBED) called"); + NGLOG_WARNING(Service_Time, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(0); } void LoadTimeZoneRule(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Time, "(STUBBED) called"); + NGLOG_WARNING(Service_Time, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -110,7 +110,7 @@ private: IPC::RequestParser rp{ctx}; u64 posix_time = rp.Pop<u64>(); - LOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x%016lX", posix_time); + NGLOG_WARNING(Service_Time, "(STUBBED) called, posix_time={:#018X}", posix_time); CalendarTime calendar_time{2018, 1, 1, 0, 0, 0}; CalendarAdditionalInfo additional_info{}; @@ -125,35 +125,35 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ISystemClock>(); - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); } void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ISystemClock>(); - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); } void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ISteadyClock>(); - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); } void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ITimeZoneService>(); - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); } void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ISystemClock>(); - LOG_DEBUG(Service_Time, "called"); + NGLOG_DEBUG(Service_Time, "called"); } Module::Interface::Interface(std::shared_ptr<Module> time, const char* name) diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 36ae2215f..45f3568d2 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -470,7 +470,7 @@ private: u32 flags = rp.Pop<u32>(); auto buffer_queue = nv_flinger->GetBufferQueue(id); - LOG_DEBUG(Service_VI, "called, transaction=%x", static_cast<u32>(transaction)); + NGLOG_DEBUG(Service_VI, "called, transaction={:X}", static_cast<u32>(transaction)); if (transaction == TransactionId::Connect) { IGBPConnectRequestParcel request{ctx.ReadBuffer()}; @@ -532,7 +532,7 @@ private: IGBPQueryResponseParcel response{value}; ctx.WriteBuffer(response.Serialize()); } else if (transaction == TransactionId::CancelBuffer) { - LOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); + NGLOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); } else { ASSERT_MSG(false, "Unimplemented"); } @@ -547,7 +547,8 @@ private: s32 addval = rp.PopRaw<s32>(); u32 type = rp.Pop<u32>(); - LOG_WARNING(Service_VI, "(STUBBED) called id=%u, addval=%08X, type=%08X", id, addval, type); + NGLOG_WARNING(Service_VI, "(STUBBED) called id={}, addval={:08X}, type={:08X}", id, addval, + type); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -561,7 +562,7 @@ private: // TODO(Subv): Find out what this actually is. - LOG_WARNING(Service_VI, "(STUBBED) called id=%u, unknown=%08X", id, unknown); + NGLOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(buffer_queue->GetNativeHandle()); @@ -624,7 +625,7 @@ public: private: void SetLayerZ(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 layer_id = rp.Pop<u64>(); u64 z_value = rp.Pop<u64>(); @@ -639,8 +640,8 @@ private: bool visibility = rp.Pop<bool>(); IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x%x, visibility=%u", layer_id, - visibility); + NGLOG_WARNING(Service_VI, "(STUBBED) called, layer_id={:#010X}, visibility={}", layer_id, + visibility); } }; @@ -722,7 +723,7 @@ public: private: void CloseDisplay(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 display = rp.Pop<u64>(); @@ -731,7 +732,7 @@ private: } void CreateManagedLayer(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u32 unknown = rp.Pop<u32>(); rp.Skip(1, false); @@ -746,7 +747,7 @@ private: } void AddToLayerStack(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u32 stack = rp.Pop<u32>(); u64 layer_id = rp.Pop<u64>(); @@ -761,8 +762,8 @@ private: bool visibility = rp.Pop<bool>(); IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x%x, visibility=%u", layer_id, - visibility); + NGLOG_WARNING(Service_VI, "(STUBBED) called, layer_id={:#X}, visibility={}", layer_id, + visibility); } std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; @@ -775,7 +776,7 @@ public: private: void GetRelayService(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -783,7 +784,7 @@ private: } void GetSystemDisplayService(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -791,7 +792,7 @@ private: } void GetManagerDisplayService(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -799,7 +800,7 @@ private: } void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -807,7 +808,7 @@ private: } void OpenDisplay(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; auto name_buf = rp.PopRaw<std::array<u8, 0x40>>(); auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); @@ -822,7 +823,7 @@ private: } void CloseDisplay(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 display_id = rp.Pop<u64>(); @@ -831,7 +832,7 @@ private: } void GetDisplayResolution(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 display_id = rp.Pop<u64>(); @@ -848,7 +849,7 @@ private: } void SetLayerScalingMode(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u32 scaling_mode = rp.Pop<u32>(); u64 unknown = rp.Pop<u64>(); @@ -864,11 +865,11 @@ private: IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); rb.Push(RESULT_SUCCESS); rb.Push<u64>(1); - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); } void OpenLayer(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_VI, "called"); + NGLOG_DEBUG(Service_VI, "called"); IPC::RequestParser rp{ctx}; auto name_buf = rp.PopRaw<std::array<u8, 0x40>>(); auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); @@ -888,7 +889,7 @@ private: } void CreateStrayLayer(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_VI, "called"); + NGLOG_DEBUG(Service_VI, "called"); IPC::RequestParser rp{ctx}; u32 flags = rp.Pop<u32>(); @@ -908,7 +909,7 @@ private: } void DestroyStrayLayer(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 layer_id = rp.Pop<u64>(); @@ -918,7 +919,7 @@ private: } void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::RequestParser rp{ctx}; u64 display_id = rp.Pop<u64>(); @@ -967,7 +968,7 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name, : ServiceFramework(name), module(std::move(module)), nv_flinger(std::move(nv_flinger)) {} void Module::Interface::GetDisplayService(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); + NGLOG_WARNING(Service_VI, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index b5133e4d6..3853cfa1a 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -137,7 +137,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) { process->address_mappings = default_address_mappings; process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); - process->Run(base_addr, 48, Memory::DEFAULT_STACK_SIZE); + process->Run(base_addr, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); is_loaded = true; return ResultStatus::Success; diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 3bc10ed0d..962bed2ab 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -165,7 +165,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) { process->address_mappings = default_address_mappings; process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); - process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Memory::DEFAULT_STACK_SIZE); + process->Run(Memory::PROCESS_IMAGE_VADDR, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); is_loaded = true; return ResultStatus::Success; diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 5ee581acf..a022665eb 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -526,6 +526,11 @@ public: return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_high) << 32) | start_low); } + + bool IsEnabled() const { + return enable != 0 && StartAddress() != 0; + } + } vertex_array[NumVertexArrays]; Blend blend; diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 2789a4ca1..2e1edee03 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/alignment.h" #include "common/assert.h" #include "video_core/memory_manager.h" @@ -11,7 +12,8 @@ PAddr MemoryManager::AllocateSpace(u64 size, u64 align) { boost::optional<PAddr> paddr = FindFreeBlock(size, align); ASSERT(paddr); - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { + for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { + ASSERT(PageSlot(*paddr + offset) == static_cast<u64>(PageStatus::Unmapped)); PageSlot(*paddr + offset) = static_cast<u64>(PageStatus::Allocated); } @@ -19,13 +21,8 @@ PAddr MemoryManager::AllocateSpace(u64 size, u64 align) { } PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) { - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { - if (IsPageMapped(paddr + offset)) { - return AllocateSpace(size, align); - } - } - - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { + for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { + ASSERT(PageSlot(paddr + offset) == static_cast<u64>(PageStatus::Unmapped)); PageSlot(paddr + offset) = static_cast<u64>(PageStatus::Allocated); } @@ -33,12 +30,11 @@ PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) { } PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) { - vaddr &= ~Memory::PAGE_MASK; - - boost::optional<PAddr> paddr = FindFreeBlock(size); + boost::optional<PAddr> paddr = FindFreeBlock(size, PAGE_SIZE); ASSERT(paddr); - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { + for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { + ASSERT(PageSlot(*paddr + offset) == static_cast<u64>(PageStatus::Unmapped)); PageSlot(*paddr + offset) = vaddr + offset; } @@ -46,16 +42,10 @@ PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) { } PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) { - vaddr &= ~Memory::PAGE_MASK; - paddr &= ~Memory::PAGE_MASK; + ASSERT((paddr & PAGE_MASK) == 0); - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { - if (PageSlot(paddr + offset) != static_cast<u64>(PageStatus::Allocated)) { - return MapBufferEx(vaddr, size); - } - } - - for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { + for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { + ASSERT(PageSlot(paddr + offset) == static_cast<u64>(PageStatus::Allocated)); PageSlot(paddr + offset) = vaddr + offset; } @@ -63,23 +53,20 @@ PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) { } boost::optional<PAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) { - PAddr paddr{}; - u64 free_space{}; - align = (align + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; + PAddr paddr = 0; + u64 free_space = 0; + align = (align + PAGE_MASK) & ~PAGE_MASK; while (paddr + free_space < MAX_ADDRESS) { if (!IsPageMapped(paddr + free_space)) { - free_space += Memory::PAGE_SIZE; + free_space += PAGE_SIZE; if (free_space >= size) { return paddr; } } else { - paddr += free_space + Memory::PAGE_SIZE; + paddr += free_space + PAGE_SIZE; free_space = 0; - const u64 remainder{paddr % align}; - if (!remainder) { - paddr = (paddr - remainder) + align; - } + paddr = Common::AlignUp(paddr, align); } } @@ -89,7 +76,7 @@ boost::optional<PAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) { VAddr MemoryManager::PhysicalToVirtualAddress(PAddr paddr) { VAddr base_addr = PageSlot(paddr); ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped)); - return base_addr + (paddr & Memory::PAGE_MASK); + return base_addr + (paddr & PAGE_MASK); } bool MemoryManager::IsPageMapped(PAddr paddr) { @@ -97,14 +84,14 @@ bool MemoryManager::IsPageMapped(PAddr paddr) { } VAddr& MemoryManager::PageSlot(PAddr paddr) { - auto& block = page_table[(paddr >> (Memory::PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; + auto& block = page_table[(paddr >> (PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; if (!block) { block = std::make_unique<PageBlock>(); for (unsigned index = 0; index < PAGE_BLOCK_SIZE; index++) { (*block)[index] = static_cast<u64>(PageStatus::Unmapped); } } - return (*block)[(paddr >> Memory::PAGE_BITS) & PAGE_BLOCK_MASK]; + return (*block)[(paddr >> PAGE_BITS) & PAGE_BLOCK_MASK]; } } // namespace Tegra diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 47da7acd6..b73e283f8 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h @@ -24,6 +24,10 @@ public: PAddr MapBufferEx(VAddr vaddr, PAddr paddr, u64 size); VAddr PhysicalToVirtualAddress(PAddr paddr); + static constexpr u64 PAGE_BITS = 16; + static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS; + static constexpr u64 PAGE_MASK = PAGE_SIZE - 1; + private: boost::optional<PAddr> FindFreeBlock(u64 size, u64 align = 1); bool IsPageMapped(PAddr paddr); @@ -35,7 +39,7 @@ private: }; static constexpr u64 MAX_ADDRESS{0x10000000000ULL}; - static constexpr u64 PAGE_TABLE_BITS{14}; + static constexpr u64 PAGE_TABLE_BITS{10}; static constexpr u64 PAGE_TABLE_SIZE{1 << PAGE_TABLE_BITS}; static constexpr u64 PAGE_TABLE_MASK{PAGE_TABLE_SIZE - 1}; static constexpr u64 PAGE_BLOCK_BITS{14}; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2d4a0d6db..82001e7b4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -127,7 +127,8 @@ RasterizerOpenGL::~RasterizerOpenGL() { } } -void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { +std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, + GLintptr buffer_offset) { MICROPROFILE_SCOPE(OpenGL_VAO); const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; @@ -136,43 +137,59 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { state.draw.vertex_buffer = stream_buffer->GetHandle(); state.Apply(); - // TODO(bunnei): Add support for 1+ vertex arrays - const auto& vertex_array{regs.vertex_array[0]}; - const auto& vertex_array_limit{regs.vertex_array_limit[0]}; - ASSERT_MSG(vertex_array.enable, "vertex array 0 is disabled?"); - ASSERT_MSG(!vertex_array.divisor, "vertex array 0 divisor is unimplemented!"); - for (unsigned index = 1; index < Maxwell::NumVertexArrays; ++index) { - ASSERT_MSG(!regs.vertex_array[index].enable, "vertex array %d is unimplemented!", index); + // Upload all guest vertex arrays sequentially to our buffer + for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { + const auto& vertex_array = regs.vertex_array[index]; + if (!vertex_array.IsEnabled()) + continue; + + const Tegra::GPUVAddr start = vertex_array.StartAddress(); + const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); + + ASSERT(end > start); + u64 size = end - start + 1; + + // Copy vertex array data + const VAddr data_addr{memory_manager->PhysicalToVirtualAddress(start)}; + res_cache.FlushRegion(data_addr, size, nullptr); + Memory::ReadBlock(data_addr, array_ptr, size); + + // Bind the vertex array to the buffer at the current offset. + glBindVertexBuffer(index, stream_buffer->GetHandle(), buffer_offset, vertex_array.stride); + + ASSERT_MSG(vertex_array.divisor == 0, "Vertex buffer divisor unimplemented"); + + array_ptr += size; + buffer_offset += size; } // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. // Enables the first 16 vertex attributes always, as we don't know which ones are actually used - // until shader time. Note, Tegra technically supports 32, but we're cappinig this to 16 for now + // until shader time. Note, Tegra technically supports 32, but we're capping this to 16 for now // to avoid OpenGL errors. + // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't + // assume every shader uses them all. for (unsigned index = 0; index < 16; ++index) { auto& attrib = regs.vertex_attrib_format[index]; NGLOG_DEBUG(HW_GPU, "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}", index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(), attrib.offset.Value(), attrib.IsNormalized()); - glVertexAttribPointer(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), - attrib.IsNormalized() ? GL_TRUE : GL_FALSE, vertex_array.stride, - reinterpret_cast<GLvoid*>(buffer_offset + attrib.offset)); + auto& buffer = regs.vertex_array[attrib.buffer]; + ASSERT(buffer.IsEnabled()); + glEnableVertexAttribArray(index); + glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), + attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); + glVertexAttribBinding(index, attrib.buffer); + hw_vao_enabled_attributes[index] = true; } - // Copy vertex array data - const u64 data_size{vertex_array_limit.LimitAddress() - vertex_array.StartAddress() + 1}; - const VAddr data_addr{memory_manager->PhysicalToVirtualAddress(vertex_array.StartAddress())}; - res_cache.FlushRegion(data_addr, data_size, nullptr); - Memory::ReadBlock(data_addr, array_ptr, data_size); - - array_ptr += data_size; - buffer_offset += data_size; + return {array_ptr, buffer_offset}; } -void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size_t ptr_pos) { +void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { // Helper function for uploading uniform data const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) { if (has_ARB_direct_state_access) { @@ -190,8 +207,6 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size u32 current_constbuffer_bindpoint = 0; for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) { - ptr_pos += sizeof(GLShader::MaxwellUniformData); - auto& shader_config = gpu.regs.shader_config[index]; const Maxwell::ShaderProgram program{static_cast<Maxwell::ShaderProgram>(index)}; @@ -205,13 +220,16 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size } // Upload uniform data as one UBO per stage - const GLintptr ubo_offset = buffer_offset + static_cast<GLintptr>(ptr_pos); + const GLintptr ubo_offset = buffer_offset; copy_buffer(uniform_buffers[stage].handle, ubo_offset, sizeof(GLShader::MaxwellUniformData)); GLShader::MaxwellUniformData* ub_ptr = - reinterpret_cast<GLShader::MaxwellUniformData*>(&buffer_ptr[ptr_pos]); + reinterpret_cast<GLShader::MaxwellUniformData*>(buffer_ptr); ub_ptr->SetFromRegs(gpu.state.shader_stages[stage]); + buffer_ptr += sizeof(GLShader::MaxwellUniformData); + buffer_offset += sizeof(GLShader::MaxwellUniformData); + // Fetch program code from memory GLShader::ProgramCode program_code; const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset}; @@ -252,6 +270,24 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size shader_program_manager->UseTrivialGeometryShader(); } +size_t RasterizerOpenGL::CalculateVertexArraysSize() const { + const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; + + size_t size = 0; + for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { + if (!regs.vertex_array[index].IsEnabled()) + continue; + + const Tegra::GPUVAddr start = regs.vertex_array[index].StartAddress(); + const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); + + ASSERT(end > start); + size += end - start + 1; + } + + return size; +} + bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays; DrawArrays(); @@ -329,44 +365,49 @@ void RasterizerOpenGL::DrawArrays() { const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()}; const unsigned vertex_num{is_indexed ? regs.index_array.count : regs.vertex_buffer.count}; - // TODO(bunnei): Add support for 1+ vertex arrays - vs_input_size = vertex_num * regs.vertex_array[0].stride; - state.draw.vertex_buffer = stream_buffer->GetHandle(); state.Apply(); - size_t buffer_size = static_cast<size_t>(vs_input_size); + size_t buffer_size = CalculateVertexArraysSize(); + if (is_indexed) { - buffer_size = Common::AlignUp(buffer_size, 4) + index_buffer_size; + buffer_size = Common::AlignUp<size_t>(buffer_size, 4) + index_buffer_size; } // Uniform space for the 5 shader stages - buffer_size += sizeof(GLShader::MaxwellUniformData) * Maxwell::MaxShaderStage; + buffer_size = Common::AlignUp<size_t>(buffer_size, 4) + + sizeof(GLShader::MaxwellUniformData) * Maxwell::MaxShaderStage; - size_t ptr_pos = 0; u8* buffer_ptr; GLintptr buffer_offset; std::tie(buffer_ptr, buffer_offset) = stream_buffer->Map(static_cast<GLsizeiptr>(buffer_size), 4); - SetupVertexArray(buffer_ptr, buffer_offset); - ptr_pos += vs_input_size; + u8* offseted_buffer; + std::tie(offseted_buffer, buffer_offset) = SetupVertexArrays(buffer_ptr, buffer_offset); + + offseted_buffer = + reinterpret_cast<u8*>(Common::AlignUp(reinterpret_cast<size_t>(offseted_buffer), 4)); + buffer_offset = Common::AlignUp<size_t>(buffer_offset, 4); // If indexed mode, copy the index buffer GLintptr index_buffer_offset = 0; if (is_indexed) { - ptr_pos = Common::AlignUp(ptr_pos, 4); - const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; const VAddr index_data_addr{ memory_manager->PhysicalToVirtualAddress(regs.index_array.StartAddress())}; - Memory::ReadBlock(index_data_addr, &buffer_ptr[ptr_pos], index_buffer_size); + Memory::ReadBlock(index_data_addr, offseted_buffer, index_buffer_size); - index_buffer_offset = buffer_offset + static_cast<GLintptr>(ptr_pos); - ptr_pos += index_buffer_size; + index_buffer_offset = buffer_offset; + offseted_buffer += index_buffer_size; + buffer_offset += index_buffer_size; } - SetupShaders(buffer_ptr, buffer_offset, ptr_pos); + offseted_buffer = + reinterpret_cast<u8*>(Common::AlignUp(reinterpret_cast<size_t>(offseted_buffer), 4)); + buffer_offset = Common::AlignUp<size_t>(buffer_offset, 4); + + SetupShaders(offseted_buffer, buffer_offset); stream_buffer->Unmap(); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 03e02b52a..544714b95 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -148,13 +148,13 @@ private: static constexpr size_t STREAM_BUFFER_SIZE = 4 * 1024 * 1024; std::unique_ptr<OGLStreamBuffer> stream_buffer; - GLsizeiptr vs_input_size; + size_t CalculateVertexArraysSize() const; - void SetupVertexArray(u8* array_ptr, GLintptr buffer_offset); + std::pair<u8*, GLintptr> SetupVertexArrays(u8* array_ptr, GLintptr buffer_offset); std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::MaxShaderStage> uniform_buffers; - void SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size_t ptr_pos); + void SetupShaders(u8* buffer_ptr, GLintptr buffer_offset); enum class AccelDraw { Disabled, Arrays, Indexed }; AccelDraw accelerate_draw; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index ced2b8247..7410471cc 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -49,6 +49,7 @@ struct FormatTuple { static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false, 1}, // ABGR8 {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false, 1}, // B5G6R5 + {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false, 1}, // A2B10G10R10 {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT1 {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT23 {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT45 @@ -104,9 +105,9 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, VAddr b static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr), SurfaceParams::MaxPixelFormat> morton_to_gl_fns = { - MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>, - MortonCopy<true, PixelFormat::DXT1>, MortonCopy<true, PixelFormat::DXT23>, - MortonCopy<true, PixelFormat::DXT45>, + MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>, + MortonCopy<true, PixelFormat::A2B10G10R10>, MortonCopy<true, PixelFormat::DXT1>, + MortonCopy<true, PixelFormat::DXT23>, MortonCopy<true, PixelFormat::DXT45>, }; static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr), @@ -114,6 +115,7 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr), gl_to_morton_fns = { MortonCopy<false, PixelFormat::ABGR8>, MortonCopy<false, PixelFormat::B5G6R5>, + MortonCopy<false, PixelFormat::A2B10G10R10>, // TODO(Subv): Swizzling the DXT1/DXT23/DXT45 formats is not yet supported nullptr, nullptr, diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 6861efe16..bf0fabb29 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -54,9 +54,10 @@ struct SurfaceParams { enum class PixelFormat { ABGR8 = 0, B5G6R5 = 1, - DXT1 = 2, - DXT23 = 3, - DXT45 = 4, + A2B10G10R10 = 2, + DXT1 = 3, + DXT23 = 4, + DXT45 = 5, Max, Invalid = 255, @@ -88,6 +89,7 @@ struct SurfaceParams { constexpr std::array<unsigned int, MaxPixelFormat> bpp_table = { 32, // ABGR8 16, // B5G6R5 + 32, // A2B10G10R10 64, // DXT1 128, // DXT23 128, // DXT45 @@ -104,6 +106,8 @@ struct SurfaceParams { switch (format) { case Tegra::RenderTargetFormat::RGBA8_UNORM: return PixelFormat::ABGR8; + case Tegra::RenderTargetFormat::RGB10_A2_UNORM: + return PixelFormat::A2B10G10R10; default: NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); UNREACHABLE(); @@ -127,6 +131,8 @@ struct SurfaceParams { return PixelFormat::ABGR8; case Tegra::Texture::TextureFormat::B5G6R5: return PixelFormat::B5G6R5; + case Tegra::Texture::TextureFormat::A2B10G10R10: + return PixelFormat::A2B10G10R10; case Tegra::Texture::TextureFormat::DXT1: return PixelFormat::DXT1; case Tegra::Texture::TextureFormat::DXT23: @@ -146,6 +152,8 @@ struct SurfaceParams { return Tegra::Texture::TextureFormat::A8R8G8B8; case PixelFormat::B5G6R5: return Tegra::Texture::TextureFormat::B5G6R5; + case PixelFormat::A2B10G10R10: + return Tegra::Texture::TextureFormat::A2B10G10R10; case PixelFormat::DXT1: return Tegra::Texture::TextureFormat::DXT1; case PixelFormat::DXT23: diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index ab0acb20a..baff2c7af 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -295,7 +295,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, const auto& texcoords = screen_info.display_texcoords; auto left = texcoords.left; auto right = texcoords.right; - if (framebuffer_transform_flags != Tegra::FramebufferConfig::TransformFlags::Unset) + if (framebuffer_transform_flags != Tegra::FramebufferConfig::TransformFlags::Unset) { if (framebuffer_transform_flags == Tegra::FramebufferConfig::TransformFlags::FlipV) { // Flip the framebuffer vertically left = texcoords.right; @@ -306,6 +306,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, framebuffer_transform_flags); UNIMPLEMENTED(); } + } std::array<ScreenRectVertex, 4> vertices = {{ ScreenRectVertex(x, y, texcoords.top, left), diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 4df687786..e0509f0ce 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -53,6 +53,7 @@ u32 BytesPerPixel(TextureFormat format) { // In this case a 'pixel' actually refers to a 4x4 tile. return 16; case TextureFormat::A8R8G8B8: + case TextureFormat::A2B10G10R10: return 4; case TextureFormat::B5G6R5: return 2; @@ -78,6 +79,7 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, unswizzled_data.data(), true, block_height); break; case TextureFormat::A8R8G8B8: + case TextureFormat::A2B10G10R10: case TextureFormat::B5G6R5: CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, unswizzled_data.data(), true, block_height); @@ -100,6 +102,7 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat case TextureFormat::DXT23: case TextureFormat::DXT45: case TextureFormat::A8R8G8B8: + case TextureFormat::A2B10G10R10: case TextureFormat::B5G6R5: // TODO(Subv): For the time being just forward the same data without any decoding. rgba_data = texture_data; diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index 86e45aa88..dc004d361 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h @@ -15,6 +15,7 @@ namespace Texture { enum class TextureFormat : u32 { A8R8G8B8 = 0x8, + A2B10G10R10 = 0x9, B5G6R5 = 0x15, DXT1 = 0x24, DXT23 = 0x25, diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index 1e4844b57..5fada74be 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp @@ -25,6 +25,8 @@ static Tegra::Texture::TextureFormat ConvertToTextureFormat( switch (render_target_format) { case Tegra::RenderTargetFormat::RGBA8_UNORM: return Tegra::Texture::TextureFormat::A8R8G8B8; + case Tegra::RenderTargetFormat::RGB10_A2_UNORM: + return Tegra::Texture::TextureFormat::A2B10G10R10; default: UNIMPLEMENTED_MSG("Unimplemented RT format"); } diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index cae2864e5..acc4c2e0b 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -6,8 +6,8 @@ #include "yuzu/util/util.h" #include "core/core.h" -#include "core/hle/kernel/condition_variable.h" #include "core/hle/kernel/event.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/timer.h" @@ -67,6 +67,29 @@ QString WaitTreeText::GetText() const { return text; } +WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address) : mutex_address(mutex_address) { + mutex_value = Memory::Read32(mutex_address); + owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Mutex::MutexOwnerMask); + owner = Kernel::g_handle_table.Get<Kernel::Thread>(owner_handle); +} + +QString WaitTreeMutexInfo::GetText() const { + return tr("waiting for mutex 0x%1").arg(mutex_address, 16, 16, QLatin1Char('0')); +} + +std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() const { + std::vector<std::unique_ptr<WaitTreeItem>> list; + + bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0; + + list.push_back(std::make_unique<WaitTreeText>(tr("has waiters: %1").arg(has_waiters))); + list.push_back(std::make_unique<WaitTreeText>( + tr("owner handle: 0x%1").arg(owner_handle, 8, 16, QLatin1Char('0')))); + if (owner != nullptr) + list.push_back(std::make_unique<WaitTreeThread>(*owner)); + return list; +} + WaitTreeWaitObject::WaitTreeWaitObject(const Kernel::WaitObject& o) : object(o) {} bool WaitTreeExpandableItem::IsExpandable() const { @@ -84,11 +107,6 @@ std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitO switch (object.GetHandleType()) { case Kernel::HandleType::Event: return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::Event&>(object)); - case Kernel::HandleType::Mutex: - return std::make_unique<WaitTreeMutex>(static_cast<const Kernel::Mutex&>(object)); - case Kernel::HandleType::ConditionVariable: - return std::make_unique<WaitTreeConditionVariable>( - static_cast<const Kernel::ConditionVariable&>(object)); case Kernel::HandleType::Timer: return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object)); case Kernel::HandleType::Thread: @@ -160,6 +178,9 @@ QString WaitTreeThread::GetText() const { case THREADSTATUS_WAIT_SYNCH_ANY: status = tr("waiting for objects"); break; + case THREADSTATUS_WAIT_MUTEX: + status = tr("waiting for mutex"); + break; case THREADSTATUS_DORMANT: status = tr("dormant"); break; @@ -186,6 +207,7 @@ QColor WaitTreeThread::GetColor() const { return QColor(Qt::GlobalColor::darkYellow); case THREADSTATUS_WAIT_SYNCH_ALL: case THREADSTATUS_WAIT_SYNCH_ANY: + case THREADSTATUS_WAIT_MUTEX: return QColor(Qt::GlobalColor::red); case THREADSTATUS_DORMANT: return QColor(Qt::GlobalColor::darkCyan); @@ -225,11 +247,11 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { list.push_back(std::make_unique<WaitTreeText>( tr("last running ticks = %1").arg(thread.last_running_ticks))); - if (thread.held_mutexes.empty()) { - list.push_back(std::make_unique<WaitTreeText>(tr("not holding mutex"))); - } else { - list.push_back(std::make_unique<WaitTreeMutexList>(thread.held_mutexes)); - } + if (thread.mutex_wait_address != 0) + list.push_back(std::make_unique<WaitTreeMutexInfo>(thread.mutex_wait_address)); + else + list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex"))); + if (thread.status == THREADSTATUS_WAIT_SYNCH_ANY || thread.status == THREADSTATUS_WAIT_SYNCH_ALL) { list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects, @@ -250,33 +272,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const { return list; } -WaitTreeMutex::WaitTreeMutex(const Kernel::Mutex& object) : WaitTreeWaitObject(object) {} - -std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutex::GetChildren() const { - std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); - - const auto& mutex = static_cast<const Kernel::Mutex&>(object); - if (mutex.GetHasWaiters()) { - list.push_back(std::make_unique<WaitTreeText>(tr("locked by thread:"))); - list.push_back(std::make_unique<WaitTreeThread>(*mutex.GetHoldingThread())); - } else { - list.push_back(std::make_unique<WaitTreeText>(tr("free"))); - } - return list; -} - -WaitTreeConditionVariable::WaitTreeConditionVariable(const Kernel::ConditionVariable& object) - : WaitTreeWaitObject(object) {} - -std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeConditionVariable::GetChildren() const { - std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); - - const auto& condition_variable = static_cast<const Kernel::ConditionVariable&>(object); - list.push_back(std::make_unique<WaitTreeText>( - tr("available count = %1").arg(condition_variable.GetAvailableCount()))); - return list; -} - WaitTreeTimer::WaitTreeTimer(const Kernel::Timer& object) : WaitTreeWaitObject(object) {} std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeTimer::GetChildren() const { @@ -293,21 +288,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeTimer::GetChildren() const { return list; } -WaitTreeMutexList::WaitTreeMutexList( - const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& list) - : mutex_list(list) {} - -QString WaitTreeMutexList::GetText() const { - return tr("holding mutexes"); -} - -std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexList::GetChildren() const { - std::vector<std::unique_ptr<WaitTreeItem>> list(mutex_list.size()); - std::transform(mutex_list.begin(), mutex_list.end(), list.begin(), - [](const auto& t) { return std::make_unique<WaitTreeMutex>(*t); }); - return list; -} - WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list) : thread_list(list) {} diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index e538174eb..300ba9ae4 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h @@ -16,8 +16,6 @@ class EmuThread; namespace Kernel { class WaitObject; class Event; -class Mutex; -class ConditionVariable; class Thread; class Timer; } // namespace Kernel @@ -61,6 +59,20 @@ public: bool IsExpandable() const override; }; +class WaitTreeMutexInfo : public WaitTreeExpandableItem { + Q_OBJECT +public: + explicit WaitTreeMutexInfo(VAddr mutex_address); + QString GetText() const override; + std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; + +private: + VAddr mutex_address; + u32 mutex_value; + Kernel::Handle owner_handle; + Kernel::SharedPtr<Kernel::Thread> owner; +}; + class WaitTreeWaitObject : public WaitTreeExpandableItem { Q_OBJECT public: @@ -104,20 +116,6 @@ public: std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; }; -class WaitTreeMutex : public WaitTreeWaitObject { - Q_OBJECT -public: - explicit WaitTreeMutex(const Kernel::Mutex& object); - std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; -}; - -class WaitTreeConditionVariable : public WaitTreeWaitObject { - Q_OBJECT -public: - explicit WaitTreeConditionVariable(const Kernel::ConditionVariable& object); - std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; -}; - class WaitTreeTimer : public WaitTreeWaitObject { Q_OBJECT public: @@ -125,19 +123,6 @@ public: std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; }; -class WaitTreeMutexList : public WaitTreeExpandableItem { - Q_OBJECT -public: - explicit WaitTreeMutexList( - const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& list); - - QString GetText() const override; - std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; - -private: - const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& mutex_list; -}; - class WaitTreeThreadList : public WaitTreeExpandableItem { Q_OBJECT public: |