diff options
Diffstat (limited to 'src/core/hle')
45 files changed, 470 insertions, 251 deletions
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h index 545cd884a..419f45896 100644 --- a/src/core/hle/ipc.h +++ b/src/core/hle/ipc.h @@ -12,7 +12,7 @@ namespace IPC { /// Size of the command buffer area, in 32-bit words. -constexpr size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32); +constexpr std::size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32); // These errors are commonly returned by invalid IPC translations, so alias them here for // convenience. diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 0f3ffdb60..a4bfe2eb0 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -152,8 +152,8 @@ public: } void ValidateHeader() { - const size_t num_domain_objects = context->NumDomainObjects(); - const size_t num_move_objects = context->NumMoveObjects(); + const std::size_t num_domain_objects = context->NumDomainObjects(); + const std::size_t num_move_objects = context->NumMoveObjects(); ASSERT_MSG(!num_domain_objects || !num_move_objects, "cannot move normal handles and domain objects"); ASSERT_MSG((index - datapayload_index) == normal_params_size, @@ -290,13 +290,6 @@ public: Skip(CommandIdSize, false); } - ResponseBuilder MakeBuilder(u32 normal_params_size, u32 num_handles_to_copy, - u32 num_handles_to_move, - ResponseBuilder::Flags flags = ResponseBuilder::Flags::None) const { - return ResponseBuilder{*context, normal_params_size, num_handles_to_copy, - num_handles_to_move, flags}; - } - template <typename T> T Pop(); @@ -329,10 +322,10 @@ public: T PopRaw(); template <typename T> - Kernel::SharedPtr<T> GetMoveObject(size_t index); + Kernel::SharedPtr<T> GetMoveObject(std::size_t index); template <typename T> - Kernel::SharedPtr<T> GetCopyObject(size_t index); + Kernel::SharedPtr<T> GetCopyObject(std::size_t index); template <class T> std::shared_ptr<T> PopIpcInterface() { @@ -406,12 +399,12 @@ void RequestParser::Pop(First& first_value, Other&... other_values) { } template <typename T> -Kernel::SharedPtr<T> RequestParser::GetMoveObject(size_t index) { +Kernel::SharedPtr<T> RequestParser::GetMoveObject(std::size_t index) { return context->GetMoveObject<T>(index); } template <typename T> -Kernel::SharedPtr<T> RequestParser::GetCopyObject(size_t index) { +Kernel::SharedPtr<T> RequestParser::GetCopyObject(std::size_t index) { return context->GetCopyObject<T>(index); } diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 6657accd5..93577591f 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -35,16 +35,17 @@ static ResultCode WaitForAddress(VAddr address, s64 timeout) { // Gets the threads waiting on an address. static std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) { - const auto RetrieveWaitingThreads = - [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) { - const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); - auto& thread_list = scheduler->GetThreadList(); - - for (auto& thread : thread_list) { - if (thread->arb_wait_address == arb_addr) - waiting_threads.push_back(thread); - } - }; + const auto RetrieveWaitingThreads = [](std::size_t core_index, + std::vector<SharedPtr<Thread>>& waiting_threads, + VAddr arb_addr) { + const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); + auto& thread_list = scheduler->GetThreadList(); + + for (auto& thread : thread_list) { + if (thread->arb_wait_address == arb_addr) + waiting_threads.push_back(thread); + } + }; // Retrieve all threads that are waiting for this address. std::vector<SharedPtr<Thread>> threads; @@ -66,12 +67,12 @@ static std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) static void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wake) { // Only process up to 'target' threads, unless 'target' is <= 0, in which case process // them all. - size_t last = waiting_threads.size(); + std::size_t last = waiting_threads.size(); if (num_to_wake > 0) last = num_to_wake; // Signal the waiting threads. - for (size_t i = 0; i < last; i++) { + for (std::size_t i = 0; i < last; i++) { ASSERT(waiting_threads[i]->status == ThreadStatus::WaitArb); waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); waiting_threads[i]->arb_wait_address = 0; diff --git a/src/core/hle/kernel/errors.h b/src/core/hle/kernel/errors.h index ad39c8271..8c2be2681 100644 --- a/src/core/hle/kernel/errors.h +++ b/src/core/hle/kernel/errors.h @@ -17,6 +17,7 @@ enum { // Confirmed Switch OS error codes MaxConnectionsReached = 7, + InvalidSize = 101, InvalidAddress = 102, HandleTableFull = 105, InvalidMemoryState = 106, @@ -29,6 +30,7 @@ enum { SynchronizationCanceled = 118, TooLarge = 119, InvalidEnumValue = 120, + NoSuchEntry = 121, InvalidState = 125, ResourceLimitExceeded = 132, }; @@ -55,6 +57,7 @@ constexpr ResultCode ERR_INVALID_MEMORY_PERMISSIONS(ErrorModule::Kernel, ErrCodes::InvalidMemoryPermissions); constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle); constexpr ResultCode ERR_INVALID_PROCESSOR_ID(ErrorModule::Kernel, ErrCodes::InvalidProcessorId); +constexpr ResultCode ERR_INVALID_SIZE(ErrorModule::Kernel, ErrCodes::InvalidSize); constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState); constexpr ResultCode ERR_INVALID_THREAD_PRIORITY(ErrorModule::Kernel, ErrCodes::InvalidThreadPriority); @@ -63,7 +66,7 @@ constexpr ResultCode ERR_INVALID_OBJECT_ADDR(-1); constexpr ResultCode ERR_NOT_AUTHORIZED(-1); /// Alternate code returned instead of ERR_INVALID_HANDLE in some code paths. constexpr ResultCode ERR_INVALID_HANDLE_OS(-1); -constexpr ResultCode ERR_NOT_FOUND(-1); +constexpr ResultCode ERR_NOT_FOUND(ErrorModule::Kernel, ErrCodes::NoSuchEntry); constexpr ResultCode RESULT_TIMEOUT(ErrorModule::Kernel, ErrCodes::Timeout); /// Returned when Accept() is called on a port with no sessions to be accepted. constexpr ResultCode ERR_NO_PENDING_SESSIONS(-1); diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 3a079b9a9..5ee5c05e3 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -65,7 +65,7 @@ ResultCode HandleTable::Close(Handle handle) { } bool HandleTable::IsValid(Handle handle) const { - size_t slot = GetSlot(handle); + std::size_t slot = GetSlot(handle); u16 generation = GetGeneration(handle); return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation; diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index cac928adb..9e2f33e8a 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -93,7 +93,7 @@ private: * This is the maximum limit of handles allowed per process in CTR-OS. It can be further * reduced by ExHeader values, but this is not emulated here. */ - static const size_t MAX_COUNT = 4096; + static const std::size_t MAX_COUNT = 4096; static u16 GetSlot(Handle handle) { return handle >> 15; diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 7264be906..72fb9d250 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -42,9 +42,9 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, Kernel::SharedPtr<Kernel::Event> event) { // Put the client thread to sleep until the wait event is signaled or the timeout expires. - thread->wakeup_callback = - [context = *this, callback](ThreadWakeupReason reason, SharedPtr<Thread> thread, - SharedPtr<WaitObject> object, size_t index) mutable -> bool { + thread->wakeup_callback = [context = *this, callback]( + ThreadWakeupReason reason, SharedPtr<Thread> thread, + SharedPtr<WaitObject> object, std::size_t index) mutable -> bool { ASSERT(thread->status == ThreadStatus::WaitHLEEvent); callback(thread, context, reason); context.WriteToOutgoingCommandBuffer(*thread); @@ -199,8 +199,8 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(u32_le* src_cmdb } // The data_size already includes the payload header, the padding and the domain header. - size_t size = data_payload_offset + command_header->data_size - - sizeof(IPC::DataPayloadHeader) / sizeof(u32) - 4; + std::size_t size = data_payload_offset + command_header->data_size - + sizeof(IPC::DataPayloadHeader) / sizeof(u32) - 4; if (domain_message_header) size -= sizeof(IPC::DomainMessageHeader) / sizeof(u32); std::copy_n(src_cmdbuf, size, cmd_buf.begin()); @@ -217,8 +217,8 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(const Thread& thread) ParseCommandBuffer(cmd_buf.data(), false); // The data_size already includes the payload header, the padding and the domain header. - size_t size = data_payload_offset + command_header->data_size - - sizeof(IPC::DataPayloadHeader) / sizeof(u32) - 4; + std::size_t size = data_payload_offset + command_header->data_size - + sizeof(IPC::DataPayloadHeader) / sizeof(u32) - 4; if (domain_message_header) size -= sizeof(IPC::DomainMessageHeader) / sizeof(u32); @@ -229,7 +229,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(const Thread& thread) "Handle descriptor bit set but no handles to translate"); // We write the translated handles at a specific offset in the command buffer, this space // was already reserved when writing the header. - size_t current_offset = + std::size_t current_offset = (sizeof(IPC::CommandHeader) + sizeof(IPC::HandleDescriptorHeader)) / sizeof(u32); ASSERT_MSG(!handle_descriptor_header->send_current_pid, "Sending PID is not implemented"); @@ -258,7 +258,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(const Thread& thread) ASSERT(domain_message_header->num_objects == domain_objects.size()); // Write the domain objects to the command buffer, these go after the raw untranslated data. // TODO(Subv): This completely ignores C buffers. - size_t domain_offset = size - domain_message_header->num_objects; + std::size_t domain_offset = size - domain_message_header->num_objects; auto& request_handlers = server_session->domain_request_handlers; for (auto& object : domain_objects) { @@ -291,14 +291,15 @@ std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const { return buffer; } -size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size, int buffer_index) const { +std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size, + int buffer_index) const { if (size == 0) { LOG_WARNING(Core, "skip empty buffer write"); return 0; } const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[buffer_index].Size()}; - const size_t buffer_size{GetWriteBufferSize(buffer_index)}; + const std::size_t buffer_size{GetWriteBufferSize(buffer_index)}; if (size > buffer_size) { LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size, buffer_size); @@ -314,13 +315,13 @@ size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size, int buffe return size; } -size_t HLERequestContext::GetReadBufferSize(int buffer_index) const { +std::size_t HLERequestContext::GetReadBufferSize(int buffer_index) const { const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[buffer_index].Size()}; return is_buffer_a ? BufferDescriptorA()[buffer_index].Size() : BufferDescriptorX()[buffer_index].Size(); } -size_t HLERequestContext::GetWriteBufferSize(int buffer_index) const { +std::size_t HLERequestContext::GetWriteBufferSize(int buffer_index) const { const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[buffer_index].Size()}; return is_buffer_b ? BufferDescriptorB()[buffer_index].Size() : BufferDescriptorC()[buffer_index].Size(); diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index f0d07f1b6..894479ee0 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -170,7 +170,7 @@ public: std::vector<u8> ReadBuffer(int buffer_index = 0) const; /// Helper function to write a buffer using the appropriate buffer descriptor - size_t WriteBuffer(const void* buffer, size_t size, int buffer_index = 0) const; + std::size_t WriteBuffer(const void* buffer, std::size_t size, int buffer_index = 0) const; /* Helper function to write a buffer using the appropriate buffer descriptor * @@ -182,7 +182,7 @@ public: */ template <typename ContiguousContainer, typename = std::enable_if_t<!std::is_pointer_v<ContiguousContainer>>> - size_t WriteBuffer(const ContiguousContainer& container, int buffer_index = 0) const { + std::size_t WriteBuffer(const ContiguousContainer& container, int buffer_index = 0) const { using ContiguousType = typename ContiguousContainer::value_type; static_assert(std::is_trivially_copyable_v<ContiguousType>, @@ -193,19 +193,19 @@ public: } /// Helper function to get the size of the input buffer - size_t GetReadBufferSize(int buffer_index = 0) const; + std::size_t GetReadBufferSize(int buffer_index = 0) const; /// Helper function to get the size of the output buffer - size_t GetWriteBufferSize(int buffer_index = 0) const; + std::size_t GetWriteBufferSize(int buffer_index = 0) const; template <typename T> - SharedPtr<T> GetCopyObject(size_t index) { + SharedPtr<T> GetCopyObject(std::size_t index) { ASSERT(index < copy_objects.size()); return DynamicObjectCast<T>(copy_objects[index]); } template <typename T> - SharedPtr<T> GetMoveObject(size_t index) { + SharedPtr<T> GetMoveObject(std::size_t index) { ASSERT(index < move_objects.size()); return DynamicObjectCast<T>(move_objects[index]); } @@ -223,7 +223,7 @@ public: } template <typename T> - std::shared_ptr<T> GetDomainRequestHandler(size_t index) const { + std::shared_ptr<T> GetDomainRequestHandler(std::size_t index) const { return std::static_pointer_cast<T>(domain_request_handlers[index]); } @@ -240,15 +240,15 @@ public: domain_objects.clear(); } - size_t NumMoveObjects() const { + std::size_t NumMoveObjects() const { return move_objects.size(); } - size_t NumCopyObjects() const { + std::size_t NumCopyObjects() const { return copy_objects.size(); } - size_t NumDomainObjects() const { + std::size_t NumDomainObjects() const { return domain_objects.size(); } diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 36bf0b677..51f4544be 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -62,7 +62,7 @@ ResultCode Mutex::TryAcquire(HandleTable& handle_table, VAddr address, Handle ho Handle requesting_thread_handle) { // The mutex address must be 4-byte aligned if ((address % sizeof(u32)) != 0) { - return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidAddress); + return ERR_INVALID_ADDRESS; } SharedPtr<Thread> holding_thread = handle_table.Get<Thread>(holding_thread_handle); @@ -100,7 +100,7 @@ ResultCode Mutex::TryAcquire(HandleTable& handle_table, VAddr address, Handle ho ResultCode Mutex::Release(VAddr address) { // The mutex address must be 4-byte aligned if ((address % sizeof(u32)) != 0) { - return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidAddress); + return ERR_INVALID_ADDRESS; } auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(GetCurrentThread(), address); diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index b025e323f..7a272d031 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -40,8 +40,8 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) { return process; } -void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { - for (size_t i = 0; i < len; ++i) { +void Process::ParseKernelCaps(const u32* kernel_caps, std::size_t len) { + for (std::size_t i = 0; i < len; ++i) { u32 descriptor = kernel_caps[i]; u32 type = descriptor >> 20; @@ -211,7 +211,7 @@ ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size) { "Shared memory exceeds bounds of mapped block"); const std::shared_ptr<std::vector<u8>>& backing_block = vma->second.backing_block; - size_t backing_block_offset = vma->second.offset + vma_offset; + std::size_t backing_block_offset = vma->second.offset + vma_offset; CASCADE_RESULT(auto new_vma, vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size, diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 1587d40c1..81538f70c 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -59,7 +59,7 @@ class ResourceLimit; struct CodeSet final : public Object { struct Segment { - size_t offset = 0; + std::size_t offset = 0; VAddr addr = 0; u32 size = 0; }; @@ -164,7 +164,7 @@ public: * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them * to this process. */ - void ParseKernelCaps(const u32* kernel_caps, size_t len); + void ParseKernelCaps(const u32* kernel_caps, std::size_t len); /** * Applies address space changes and launches the process main thread. diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 2c729afe3..2c06bb7ce 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -119,7 +119,7 @@ public: /// Backing memory for this shared memory block. std::shared_ptr<std::vector<u8>> backing_block; /// Offset into the backing block for this shared memory. - size_t backing_block_offset; + std::size_t backing_block_offset; /// Size of the memory block. Page-aligned. u64 size; /// Permission restrictions applied to the process which created the block. diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index f500fd2e7..371fc439e 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -35,10 +35,21 @@ #include "core/hle/service/service.h" namespace Kernel { +namespace { +constexpr bool Is4KBAligned(VAddr address) { + return (address & 0xFFF) == 0; +} +} // Anonymous namespace /// Set the process heap to a given Size. It can both extend and shrink the heap. static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); + + // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 4GB. + if ((heap_size & 0xFFFFFFFE001FFFFF) != 0) { + return ERR_INVALID_SIZE; + } + auto& process = *Core::CurrentProcess(); CASCADE_RESULT(*heap_addr, process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite)); @@ -56,6 +67,15 @@ static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, src_addr, size); + + if (!Is4KBAligned(dst_addr) || !Is4KBAligned(src_addr)) { + return ERR_INVALID_ADDRESS; + } + + if (size == 0 || !Is4KBAligned(size)) { + return ERR_INVALID_SIZE; + } + return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size); } @@ -63,6 +83,15 @@ static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, src_addr, size); + + if (!Is4KBAligned(dst_addr) || !Is4KBAligned(src_addr)) { + return ERR_INVALID_ADDRESS; + } + + if (size == 0 || !Is4KBAligned(size)) { + return ERR_INVALID_SIZE; + } + return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size); } @@ -146,7 +175,7 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) { /// Default thread wakeup callback for WaitSynchronization static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, - SharedPtr<WaitObject> object, size_t index) { + SharedPtr<WaitObject> object, std::size_t index) { ASSERT(thread->status == ThreadStatus::WaitSynchAny); if (reason == ThreadWakeupReason::Timeout) { @@ -251,6 +280,10 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, "requesting_current_thread_handle=0x{:08X}", holding_thread_handle, mutex_addr, requesting_thread_handle); + if (Memory::IsKernelVirtualAddress(mutex_addr)) { + return ERR_INVALID_ADDRESS_STATE; + } + auto& handle_table = Core::System::GetInstance().Kernel().HandleTable(); return Mutex::TryAcquire(handle_table, mutex_addr, holding_thread_handle, requesting_thread_handle); @@ -260,6 +293,10 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, static ResultCode ArbitrateUnlock(VAddr mutex_addr) { LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); + if (Memory::IsKernelVirtualAddress(mutex_addr)) { + return ERR_INVALID_ADDRESS_STATE; + } + return Mutex::Release(mutex_addr); } @@ -415,35 +452,43 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", shared_memory_handle, addr, size, permissions); + if (!Is4KBAligned(addr)) { + return ERR_INVALID_ADDRESS; + } + + if (size == 0 || !Is4KBAligned(size)) { + return ERR_INVALID_SIZE; + } + + const auto permissions_type = static_cast<MemoryPermission>(permissions); + if (permissions_type != MemoryPermission::Read && + permissions_type != MemoryPermission::ReadWrite) { + LOG_ERROR(Kernel_SVC, "Invalid permissions=0x{:08X}", permissions); + return ERR_INVALID_MEMORY_PERMISSIONS; + } + auto& kernel = Core::System::GetInstance().Kernel(); auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); if (!shared_memory) { return ERR_INVALID_HANDLE; } - MemoryPermission permissions_type = static_cast<MemoryPermission>(permissions); - switch (permissions_type) { - case MemoryPermission::Read: - case MemoryPermission::Write: - case MemoryPermission::ReadWrite: - case MemoryPermission::Execute: - case MemoryPermission::ReadExecute: - case MemoryPermission::WriteExecute: - case MemoryPermission::ReadWriteExecute: - case MemoryPermission::DontCare: - return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type, - MemoryPermission::DontCare); - default: - LOG_ERROR(Kernel_SVC, "unknown permissions=0x{:08X}", permissions); - } - - return RESULT_SUCCESS; + return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type, + MemoryPermission::DontCare); } static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}", shared_memory_handle, addr, size); + if (!Is4KBAligned(addr)) { + return ERR_INVALID_ADDRESS; + } + + if (size == 0 || !Is4KBAligned(size)) { + return ERR_INVALID_SIZE; + } + auto& kernel = Core::System::GetInstance().Kernel(); auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); @@ -524,7 +569,7 @@ static void ExitProcess() { /// Creates a new thread static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, u32 priority, s32 processor_id) { - std::string name = fmt::format("unknown-{:X}", entry_point); + std::string name = fmt::format("thread-{:X}", entry_point); if (priority > THREADPRIO_LOWEST) { return ERR_INVALID_THREAD_PRIORITY; @@ -647,16 +692,17 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}", condition_variable_addr, target); - auto RetrieveWaitingThreads = - [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr condvar_addr) { - const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); - auto& thread_list = scheduler->GetThreadList(); + auto RetrieveWaitingThreads = [](std::size_t core_index, + std::vector<SharedPtr<Thread>>& waiting_threads, + VAddr condvar_addr) { + const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); + auto& thread_list = scheduler->GetThreadList(); - for (auto& thread : thread_list) { - if (thread->condvar_wait_address == condvar_addr) - waiting_threads.push_back(thread); - } - }; + for (auto& thread : thread_list) { + if (thread->condvar_wait_address == condvar_addr) + waiting_threads.push_back(thread); + } + }; // Retrieve a list of all threads that are waiting for this condition variable. std::vector<SharedPtr<Thread>> waiting_threads; @@ -672,7 +718,7 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target // Only process up to 'target' threads, unless 'target' is -1, in which case process // them all. - size_t last = waiting_threads.size(); + std::size_t last = waiting_threads.size(); if (target != -1) last = target; @@ -680,12 +726,12 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target if (last > waiting_threads.size()) return RESULT_SUCCESS; - for (size_t index = 0; index < last; ++index) { + for (std::size_t index = 0; index < last; ++index) { auto& thread = waiting_threads[index]; ASSERT(thread->condvar_wait_address == condition_variable_addr); - size_t current_core = Core::System::GetInstance().CurrentCoreIndex(); + std::size_t current_core = Core::System::GetInstance().CurrentCoreIndex(); auto& monitor = Core::System::GetInstance().Monitor(); @@ -898,12 +944,28 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size, local_permissions, remote_permissions); + // Size must be a multiple of 4KB and be less than or equal to + // approx. 8 GB (actually (1GB - 512B) * 8) + if (size == 0 || (size & 0xFFFFFFFE00000FFF) != 0) { + return ERR_INVALID_SIZE; + } + + const auto local_perms = static_cast<MemoryPermission>(local_permissions); + if (local_perms != MemoryPermission::Read && local_perms != MemoryPermission::ReadWrite) { + return ERR_INVALID_MEMORY_PERMISSIONS; + } + + const auto remote_perms = static_cast<MemoryPermission>(remote_permissions); + if (remote_perms != MemoryPermission::Read && remote_perms != MemoryPermission::ReadWrite && + remote_perms != MemoryPermission::DontCare) { + return ERR_INVALID_MEMORY_PERMISSIONS; + } + auto& kernel = Core::System::GetInstance().Kernel(); auto& handle_table = kernel.HandleTable(); auto shared_mem_handle = SharedMemory::Create(kernel, handle_table.Get<Process>(KernelHandle::CurrentProcess), size, - static_cast<MemoryPermission>(local_permissions), - static_cast<MemoryPermission>(remote_permissions)); + local_perms, remote_perms); CASCADE_RESULT(*handle, handle_table.Create(shared_mem_handle)); return RESULT_SUCCESS; diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 1eda5f879..fea9ba5ea 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h @@ -13,7 +13,9 @@ namespace Kernel { -#define PARAM(n) Core::CurrentArmInterface().GetReg(n) +static inline u64 Param(int n) { + return Core::CurrentArmInterface().GetReg(n); +} /** * HLE a function return from the current ARM userland process @@ -28,23 +30,23 @@ static inline void FuncReturn(u64 res) { template <ResultCode func(u64)> void SvcWrap() { - FuncReturn(func(PARAM(0)).raw); + FuncReturn(func(Param(0)).raw); } template <ResultCode func(u32)> void SvcWrap() { - FuncReturn(func((u32)PARAM(0)).raw); + FuncReturn(func((u32)Param(0)).raw); } template <ResultCode func(u32, u32)> void SvcWrap() { - FuncReturn(func((u32)PARAM(0), (u32)PARAM(1)).raw); + FuncReturn(func((u32)Param(0), (u32)Param(1)).raw); } template <ResultCode func(u32*, u32)> void SvcWrap() { u32 param_1 = 0; - u32 retval = func(¶m_1, (u32)PARAM(1)).raw; + u32 retval = func(¶m_1, (u32)Param(1)).raw; Core::CurrentArmInterface().SetReg(1, param_1); FuncReturn(retval); } @@ -52,39 +54,39 @@ void SvcWrap() { template <ResultCode func(u32*, u64)> void SvcWrap() { u32 param_1 = 0; - u32 retval = func(¶m_1, PARAM(1)).raw; + u32 retval = func(¶m_1, Param(1)).raw; Core::CurrentArmInterface().SetReg(1, param_1); FuncReturn(retval); } template <ResultCode func(u64, s32)> void SvcWrap() { - FuncReturn(func(PARAM(0), (s32)PARAM(1)).raw); + FuncReturn(func(Param(0), (s32)Param(1)).raw); } template <ResultCode func(u64*, u64)> void SvcWrap() { u64 param_1 = 0; - u32 retval = func(¶m_1, PARAM(1)).raw; + u32 retval = func(¶m_1, Param(1)).raw; Core::CurrentArmInterface().SetReg(1, param_1); FuncReturn(retval); } template <ResultCode func(u32, u64)> void SvcWrap() { - FuncReturn(func((u32)(PARAM(0) & 0xFFFFFFFF), PARAM(1)).raw); + FuncReturn(func((u32)(Param(0) & 0xFFFFFFFF), Param(1)).raw); } template <ResultCode func(u32, u32, u64)> void SvcWrap() { - FuncReturn(func((u32)(PARAM(0) & 0xFFFFFFFF), (u32)(PARAM(1) & 0xFFFFFFFF), PARAM(2)).raw); + FuncReturn(func((u32)(Param(0) & 0xFFFFFFFF), (u32)(Param(1) & 0xFFFFFFFF), Param(2)).raw); } template <ResultCode func(u32, u32*, u64*)> void SvcWrap() { u32 param_1 = 0; u64 param_2 = 0; - ResultCode retval = func((u32)(PARAM(2) & 0xFFFFFFFF), ¶m_1, ¶m_2); + ResultCode retval = func((u32)(Param(2) & 0xFFFFFFFF), ¶m_1, ¶m_2); Core::CurrentArmInterface().SetReg(1, param_1); Core::CurrentArmInterface().SetReg(2, param_2); FuncReturn(retval.raw); @@ -93,46 +95,46 @@ void SvcWrap() { template <ResultCode func(u64, u64, u32, u32)> void SvcWrap() { FuncReturn( - func(PARAM(0), PARAM(1), (u32)(PARAM(3) & 0xFFFFFFFF), (u32)(PARAM(3) & 0xFFFFFFFF)).raw); + func(Param(0), Param(1), (u32)(Param(3) & 0xFFFFFFFF), (u32)(Param(3) & 0xFFFFFFFF)).raw); } template <ResultCode func(u32, u64, u32)> void SvcWrap() { - FuncReturn(func((u32)PARAM(0), PARAM(1), (u32)PARAM(2)).raw); + FuncReturn(func((u32)Param(0), Param(1), (u32)Param(2)).raw); } template <ResultCode func(u64, u64, u64)> void SvcWrap() { - FuncReturn(func(PARAM(0), PARAM(1), PARAM(2)).raw); + FuncReturn(func(Param(0), Param(1), Param(2)).raw); } template <ResultCode func(u32, u64, u64, u32)> void SvcWrap() { - FuncReturn(func((u32)PARAM(0), PARAM(1), PARAM(2), (u32)PARAM(3)).raw); + FuncReturn(func((u32)Param(0), Param(1), Param(2), (u32)Param(3)).raw); } template <ResultCode func(u32, u64, u64)> void SvcWrap() { - FuncReturn(func((u32)PARAM(0), PARAM(1), PARAM(2)).raw); + FuncReturn(func((u32)Param(0), Param(1), Param(2)).raw); } template <ResultCode func(u32*, u64, u64, s64)> void SvcWrap() { u32 param_1 = 0; - ResultCode retval = func(¶m_1, PARAM(1), (u32)(PARAM(2) & 0xFFFFFFFF), (s64)PARAM(3)); + ResultCode retval = func(¶m_1, Param(1), (u32)(Param(2) & 0xFFFFFFFF), (s64)Param(3)); Core::CurrentArmInterface().SetReg(1, param_1); FuncReturn(retval.raw); } template <ResultCode func(u64, u64, u32, s64)> void SvcWrap() { - FuncReturn(func(PARAM(0), PARAM(1), (u32)PARAM(2), (s64)PARAM(3)).raw); + FuncReturn(func(Param(0), Param(1), (u32)Param(2), (s64)Param(3)).raw); } template <ResultCode func(u64*, u64, u64, u64)> void SvcWrap() { u64 param_1 = 0; - u32 retval = func(¶m_1, PARAM(1), PARAM(2), PARAM(3)).raw; + u32 retval = func(¶m_1, Param(1), Param(2), Param(3)).raw; Core::CurrentArmInterface().SetReg(1, param_1); FuncReturn(retval); } @@ -141,7 +143,7 @@ template <ResultCode func(u32*, u64, u64, u64, u32, s32)> void SvcWrap() { u32 param_1 = 0; u32 retval = - func(¶m_1, PARAM(1), PARAM(2), PARAM(3), (u32)PARAM(4), (s32)(PARAM(5) & 0xFFFFFFFF)) + func(¶m_1, Param(1), Param(2), Param(3), (u32)Param(4), (s32)(Param(5) & 0xFFFFFFFF)) .raw; Core::CurrentArmInterface().SetReg(1, param_1); FuncReturn(retval); @@ -151,13 +153,13 @@ template <ResultCode func(MemoryInfo*, PageInfo*, u64)> void SvcWrap() { MemoryInfo memory_info = {}; PageInfo page_info = {}; - u32 retval = func(&memory_info, &page_info, PARAM(2)).raw; + u32 retval = func(&memory_info, &page_info, Param(2)).raw; - Memory::Write64(PARAM(0), memory_info.base_address); - Memory::Write64(PARAM(0) + 8, memory_info.size); - Memory::Write32(PARAM(0) + 16, memory_info.type); - Memory::Write32(PARAM(0) + 20, memory_info.attributes); - Memory::Write32(PARAM(0) + 24, memory_info.permission); + Memory::Write64(Param(0), memory_info.base_address); + Memory::Write64(Param(0) + 8, memory_info.size); + Memory::Write32(Param(0) + 16, memory_info.type); + Memory::Write32(Param(0) + 20, memory_info.attributes); + Memory::Write32(Param(0) + 24, memory_info.permission); FuncReturn(retval); } @@ -165,7 +167,7 @@ void SvcWrap() { template <ResultCode func(u32*, u64, u64, u32)> void SvcWrap() { u32 param_1 = 0; - u32 retval = func(¶m_1, PARAM(1), PARAM(2), (u32)(PARAM(3) & 0xFFFFFFFF)).raw; + u32 retval = func(¶m_1, Param(1), Param(2), (u32)(Param(3) & 0xFFFFFFFF)).raw; Core::CurrentArmInterface().SetReg(1, param_1); FuncReturn(retval); } @@ -174,7 +176,7 @@ template <ResultCode func(Handle*, u64, u32, u32)> void SvcWrap() { u32 param_1 = 0; u32 retval = - func(¶m_1, PARAM(1), (u32)(PARAM(2) & 0xFFFFFFFF), (u32)(PARAM(3) & 0xFFFFFFFF)).raw; + func(¶m_1, Param(1), (u32)(Param(2) & 0xFFFFFFFF), (u32)(Param(3) & 0xFFFFFFFF)).raw; Core::CurrentArmInterface().SetReg(1, param_1); FuncReturn(retval); } @@ -182,14 +184,14 @@ void SvcWrap() { template <ResultCode func(u64, u32, s32, s64)> void SvcWrap() { FuncReturn( - func(PARAM(0), (u32)(PARAM(1) & 0xFFFFFFFF), (s32)(PARAM(2) & 0xFFFFFFFF), (s64)PARAM(3)) + func(Param(0), (u32)(Param(1) & 0xFFFFFFFF), (s32)(Param(2) & 0xFFFFFFFF), (s64)Param(3)) .raw); } template <ResultCode func(u64, u32, s32, s32)> void SvcWrap() { - FuncReturn(func(PARAM(0), (u32)(PARAM(1) & 0xFFFFFFFF), (s32)(PARAM(2) & 0xFFFFFFFF), - (s32)(PARAM(3) & 0xFFFFFFFF)) + FuncReturn(func(Param(0), (u32)(Param(1) & 0xFFFFFFFF), (s32)(Param(2) & 0xFFFFFFFF), + (s32)(Param(3) & 0xFFFFFFFF)) .raw); } @@ -219,20 +221,17 @@ void SvcWrap() { template <void func(s64)> void SvcWrap() { - func((s64)PARAM(0)); + func((s64)Param(0)); } template <void func(u64, u64 len)> void SvcWrap() { - func(PARAM(0), PARAM(1)); + func(Param(0), Param(1)); } template <void func(u64, u64, u64)> void SvcWrap() { - func(PARAM(0), PARAM(1), PARAM(2)); + func(Param(0), Param(1), Param(2)); } -#undef PARAM -#undef FuncReturn - } // namespace Kernel diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 3f12a84dc..d4183d6e3 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -217,8 +217,8 @@ static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAdd context.cpu_registers[0] = arg; context.pc = entry_point; context.sp = stack_top; - context.cpsr = 0; - context.fpscr = 0; + context.pstate = 0; + context.fpcr = 0; } ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point, @@ -275,7 +275,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name available_slot = 0; // Use the first slot in the new page // Allocate some memory from the end of the linear heap for this region. - const size_t offset = thread->tls_memory->size(); + const std::size_t offset = thread->tls_memory->size(); thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0); auto& vm_manager = owner_process->vm_manager; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index cb57ee78a..df4748942 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -254,7 +254,7 @@ public: Handle callback_handle; using WakeupCallback = bool(ThreadWakeupReason reason, SharedPtr<Thread> thread, - SharedPtr<WaitObject> object, size_t index); + SharedPtr<WaitObject> object, std::size_t index); // Callback that will be invoked when the thread is resumed from a waiting state. If the thread // was waiting via WaitSynchronizationN then the object will be the last object that became // available. In case of a timeout, the object will be nullptr. diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 479cacb62..608cbd57b 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -86,7 +86,7 @@ VMManager::VMAHandle VMManager::FindVMA(VAddr target) const { ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block, - size_t offset, u64 size, + std::size_t offset, u64 size, MemoryState state) { ASSERT(block != nullptr); ASSERT(offset + size <= block->size()); diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 98bd04bea..de75036c0 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -81,7 +81,7 @@ struct VirtualMemoryArea { /// Memory block backing this VMA. std::shared_ptr<std::vector<u8>> backing_block = nullptr; /// Offset into the backing_memory the mapping starts from. - size_t offset = 0; + std::size_t offset = 0; // Settings for type = BackingMemory /// Pointer backing this VMA. It will not be destroyed or freed when the VMA is removed. @@ -147,7 +147,7 @@ public: * @param state MemoryState tag to attach to the VMA. */ ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block, - size_t offset, u64 size, MemoryState state); + std::size_t offset, u64 size, MemoryState state); /** * Maps an unmanaged host memory pointer at a given address. diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index eef00b729..b190ceb98 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp @@ -81,7 +81,7 @@ void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) { } } - size_t index = thread->GetWaitObjectIndex(this); + std::size_t index = thread->GetWaitObjectIndex(this); for (auto& object : thread->wait_objects) object->RemoveWaitingThread(thread.get()); diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 1502dbf55..e61748ca3 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -34,7 +34,7 @@ public: static const FunctionInfo functions[] = { {0, &IProfile::Get, "Get"}, {1, &IProfile::GetBase, "GetBase"}, - {10, nullptr, "GetImageSize"}, + {10, &IProfile::GetImageSize, "GetImageSize"}, {11, &IProfile::LoadImage, "LoadImage"}, }; RegisterHandlers(functions); @@ -93,6 +93,14 @@ private: rb.Push<u32>(jpeg_size); } + void GetImageSize(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_ACC, "(STUBBED) called"); + constexpr u32 jpeg_size = 107; + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(jpeg_size); + } + const ProfileManager& profile_manager; UUID user_id; ///< The user id this profile refers to. }; @@ -122,11 +130,10 @@ private: void GetAccountId(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); - // TODO(Subv): Find out what this actually does and implement it. Stub it as an error for - // now since we do not implement NNID. Returning a bogus id here will cause games to send - // invalid IPC requests after ListOpenUsers is called. - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultCode(-1)); + // Should return a nintendo account ID + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw<u64>(1); } }; diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 4ccebef23..bcb3475db 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -25,7 +25,7 @@ const UUID& UUID::Generate() { ProfileManager::ProfileManager() { // TODO(ogniK): Create the default user we have for now until loading/saving users is added auto user_uuid = UUID{1, 0}; - CreateNewUser(user_uuid, Settings::values.username); + ASSERT(CreateNewUser(user_uuid, Settings::values.username).IsSuccess()); OpenUser(user_uuid); } @@ -33,7 +33,7 @@ ProfileManager::~ProfileManager() = default; /// After a users creation it needs to be "registered" to the system. AddToProfiles handles the /// internal management of the users profiles -boost::optional<size_t> ProfileManager::AddToProfiles(const ProfileInfo& user) { +boost::optional<std::size_t> ProfileManager::AddToProfiles(const ProfileInfo& user) { if (user_count >= MAX_USERS) { return boost::none; } @@ -42,7 +42,7 @@ boost::optional<size_t> ProfileManager::AddToProfiles(const ProfileInfo& user) { } /// Deletes a specific profile based on it's profile index -bool ProfileManager::RemoveProfileAtIndex(size_t index) { +bool ProfileManager::RemoveProfileAtIndex(std::size_t index) { if (index >= MAX_USERS || index >= user_count) { return false; } @@ -91,7 +91,8 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, const ProfileUsername& usern /// specifically by allowing an std::string for the username. This is required specifically since /// we're loading a string straight from the config ResultCode ProfileManager::CreateNewUser(UUID uuid, const std::string& username) { - ProfileUsername username_output; + ProfileUsername username_output{}; + if (username.size() > username_output.size()) { std::copy_n(username.begin(), username_output.size(), username_output.begin()); } else { @@ -101,7 +102,7 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, const std::string& username) } /// Returns a users profile index based on their user id. -boost::optional<size_t> ProfileManager::GetUserIndex(const UUID& uuid) const { +boost::optional<std::size_t> ProfileManager::GetUserIndex(const UUID& uuid) const { if (!uuid) { return boost::none; } @@ -110,16 +111,17 @@ boost::optional<size_t> ProfileManager::GetUserIndex(const UUID& uuid) const { if (iter == profiles.end()) { return boost::none; } - return static_cast<size_t>(std::distance(profiles.begin(), iter)); + return static_cast<std::size_t>(std::distance(profiles.begin(), iter)); } /// Returns a users profile index based on their profile -boost::optional<size_t> ProfileManager::GetUserIndex(const ProfileInfo& user) const { +boost::optional<std::size_t> ProfileManager::GetUserIndex(const ProfileInfo& user) const { return GetUserIndex(user.user_uuid); } /// Returns the data structure used by the switch when GetProfileBase is called on acc:* -bool ProfileManager::GetProfileBase(boost::optional<size_t> index, ProfileBase& profile) const { +bool ProfileManager::GetProfileBase(boost::optional<std::size_t> index, + ProfileBase& profile) const { if (index == boost::none || index >= MAX_USERS) { return false; } @@ -143,14 +145,16 @@ bool ProfileManager::GetProfileBase(const ProfileInfo& user, ProfileBase& profil /// Returns the current user count on the system. We keep a variable which tracks the count so we /// don't have to loop the internal profile array every call. -size_t ProfileManager::GetUserCount() const { + +std::size_t ProfileManager::GetUserCount() const { return user_count; } /// Lists the current "opened" users on the system. Users are typically not open until they sign /// into something or pick a profile. As of right now users should all be open until qlaunch is /// booting -size_t ProfileManager::GetOpenUserCount() const { + +std::size_t ProfileManager::GetOpenUserCount() const { return std::count_if(profiles.begin(), profiles.end(), [](const ProfileInfo& p) { return p.is_open; }); } @@ -206,7 +210,7 @@ UUID ProfileManager::GetLastOpenedUser() const { } /// Return the users profile base and the unknown arbitary data. -bool ProfileManager::GetProfileBaseAndData(boost::optional<size_t> index, ProfileBase& profile, +bool ProfileManager::GetProfileBaseAndData(boost::optional<std::size_t> index, ProfileBase& profile, ProfileData& data) const { if (GetProfileBase(index, profile)) { data = profiles[index.get()].data; diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index cd8df93a5..bffd4cf4d 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -12,8 +12,8 @@ #include "core/hle/result.h" namespace Service::Account { -constexpr size_t MAX_USERS = 8; -constexpr size_t MAX_DATA = 128; +constexpr std::size_t MAX_USERS = 8; +constexpr std::size_t MAX_DATA = 128; constexpr u128 INVALID_UUID{{0, 0}}; struct UUID { @@ -87,18 +87,18 @@ public: ResultCode AddUser(const ProfileInfo& user); ResultCode CreateNewUser(UUID uuid, const ProfileUsername& username); ResultCode CreateNewUser(UUID uuid, const std::string& username); - boost::optional<size_t> GetUserIndex(const UUID& uuid) const; - boost::optional<size_t> GetUserIndex(const ProfileInfo& user) const; - bool GetProfileBase(boost::optional<size_t> index, ProfileBase& profile) const; + boost::optional<std::size_t> GetUserIndex(const UUID& uuid) const; + boost::optional<std::size_t> GetUserIndex(const ProfileInfo& user) const; + bool GetProfileBase(boost::optional<std::size_t> index, ProfileBase& profile) const; bool GetProfileBase(UUID uuid, ProfileBase& profile) const; bool GetProfileBase(const ProfileInfo& user, ProfileBase& profile) const; - bool GetProfileBaseAndData(boost::optional<size_t> index, ProfileBase& profile, + bool GetProfileBaseAndData(boost::optional<std::size_t> index, ProfileBase& profile, ProfileData& data) const; bool GetProfileBaseAndData(UUID uuid, ProfileBase& profile, ProfileData& data) const; bool GetProfileBaseAndData(const ProfileInfo& user, ProfileBase& profile, ProfileData& data) const; - size_t GetUserCount() const; - size_t GetOpenUserCount() const; + std::size_t GetUserCount() const; + std::size_t GetOpenUserCount() const; bool UserExists(UUID uuid) const; void OpenUser(UUID uuid); void CloseUser(UUID uuid); @@ -110,9 +110,9 @@ public: private: std::array<ProfileInfo, MAX_USERS> profiles{}; - size_t user_count = 0; - boost::optional<size_t> AddToProfiles(const ProfileInfo& profile); - bool RemoveProfileAtIndex(size_t index); + std::size_t user_count = 0; + boost::optional<std::size_t> AddToProfiles(const ProfileInfo& profile); + bool RemoveProfileAtIndex(std::size_t index); UUID last_opened_user{INVALID_UUID}; }; diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index a57ed3042..69bfce1c1 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -20,6 +20,7 @@ #include "core/hle/service/nvflinger/nvflinger.h" #include "core/hle/service/pm/pm.h" #include "core/hle/service/set/set.h" +#include "core/hle/service/vi/vi.h" #include "core/settings.h" namespace Service::AM { @@ -334,7 +335,7 @@ ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter" {51, nullptr, "SetVrModeEnabled"}, {52, nullptr, "SwitchLcdBacklight"}, {55, nullptr, "IsInControllerFirmwareUpdateSection"}, - {60, nullptr, "GetDefaultDisplayResolution"}, + {60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"}, {61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"}, {62, nullptr, "GetHdcpAuthenticationState"}, @@ -393,6 +394,21 @@ void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLEReque LOG_WARNING(Service_AM, "(STUBBED) called"); } +void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + + if (Settings::values.use_docked_mode) { + rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth)); + rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight)); + } else { + rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth)); + rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight)); + } + + LOG_DEBUG(Service_AM, "called"); +} + void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { const bool use_docked_mode{Settings::values.use_docked_mode}; IPC::ResponseBuilder rb{ctx, 3}; @@ -446,7 +462,7 @@ private: std::memcpy(&buffer[offset], data.data(), data.size()); - IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)}; + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_DEBUG(Service_AM, "called, offset={}", offset); @@ -456,13 +472,13 @@ private: IPC::RequestParser rp{ctx}; const u64 offset{rp.Pop<u64>()}; - const size_t size{ctx.GetWriteBufferSize()}; + const std::size_t size{ctx.GetWriteBufferSize()}; ASSERT(offset + size <= buffer.size()); ctx.WriteBuffer(buffer.data() + offset, size); - IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)}; + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_DEBUG(Service_AM, "called, offset={}", offset); @@ -552,7 +568,7 @@ private: IPC::RequestParser rp{ctx}; storage_stack.push(rp.PopIpcInterface<AM::IStorage>()); - IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)}; + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_DEBUG(Service_AM, "called"); @@ -600,7 +616,7 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { const u64 size{rp.Pop<u64>()}; std::vector<u8> buffer(size); - IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 1)}; + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<AM::IStorage>(std::move(buffer)); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index fd9ae296b..b39b0d838 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -123,6 +123,7 @@ private: void GetOperationMode(Kernel::HLERequestContext& ctx); void GetPerformanceMode(Kernel::HLERequestContext& ctx); void GetBootMode(Kernel::HLERequestContext& ctx); + void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); Kernel::SharedPtr<Kernel::Event> event; }; diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 80a002322..ff1edefbb 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -190,7 +190,7 @@ void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { ctx.WriteBuffer(DefaultDevice); - IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(1); // Amount of audio devices diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index e84c4fa2b..06ac6372d 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -137,7 +137,7 @@ private: constexpr std::array<char, 15> audio_interface{{"AudioInterface"}}; ctx.WriteBuffer(audio_interface); - IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(1); } @@ -151,7 +151,7 @@ private: auto file_buffer = ctx.ReadBuffer(); auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0'); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -162,7 +162,7 @@ private: constexpr std::array<char, 12> audio_interface{{"AudioDevice"}}; ctx.WriteBuffer(audio_interface); - IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(1); } diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index 668fef145..fc6067e59 100644 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp @@ -61,7 +61,7 @@ private: bool Decoder_DecodeInterleaved(u32& consumed, u32& sample_count, const std::vector<u8>& input, std::vector<opus_int16>& output) { - size_t raw_output_sz = output.size() * sizeof(opus_int16); + std::size_t raw_output_sz = output.size() * sizeof(opus_int16); if (sizeof(OpusHeader) > input.size()) return false; OpusHeader hdr{}; @@ -96,7 +96,7 @@ private: u32 channel_count; }; -static size_t WorkerBufferSize(u32 channel_count) { +static std::size_t WorkerBufferSize(u32 channel_count) { ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); return opus_decoder_get_size(static_cast<int>(channel_count)); } @@ -129,7 +129,7 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) { "Invalid sample rate"); ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); - size_t worker_sz = WorkerBufferSize(channel_count); + std::size_t worker_sz = WorkerBufferSize(channel_count); ASSERT_MSG(buffer_sz < worker_sz, "Worker buffer too large"); std::unique_ptr<OpusDecoder, OpusDeleter> decoder{ static_cast<OpusDecoder*>(operator new(worker_sz))}; diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 5c4971724..d349ee686 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -197,7 +197,7 @@ ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const s auto dir = GetDirectoryRelativeWrapped(backing, path); if (dir == nullptr) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return FileSys::ERROR_PATH_NOT_FOUND; } return MakeResult(dir); } diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index a8e0c869f..7c6b0a4e6 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -89,7 +89,7 @@ private: controller_header.left_color_body = JOYCON_BODY_NEON_BLUE; controller_header.left_color_buttons = JOYCON_BUTTONS_NEON_BLUE; - for (size_t controller = 0; controller < mem.controllers.size(); controller++) { + for (std::size_t controller = 0; controller < mem.controllers.size(); controller++) { for (auto& layout : mem.controllers[controller].layouts) { layout.header.num_entries = HID_NUM_ENTRIES; layout.header.max_entry_index = HID_NUM_ENTRIES - 1; @@ -313,7 +313,7 @@ public: {64, nullptr, "DeactivateJoySixAxisSensor"}, {65, nullptr, "GetJoySixAxisSensorLifoHandle"}, {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"}, - {67, nullptr, "StopSixAxisSensor"}, + {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"}, {68, nullptr, "IsSixAxisSensorFusionEnabled"}, {69, nullptr, "EnableSixAxisSensorFusion"}, {70, nullptr, "SetSixAxisSensorFusionParameters"}, @@ -329,7 +329,7 @@ public: {80, nullptr, "GetGyroscopeZeroDriftMode"}, {81, nullptr, "ResetGyroscopeZeroDriftMode"}, {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"}, - {91, nullptr, "ActivateGesture"}, + {91, &Hid::ActivateGesture, "ActivateGesture"}, {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"}, {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"}, {102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"}, @@ -338,7 +338,7 @@ public: {106, &Hid::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"}, {107, &Hid::DisconnectNpad, "DisconnectNpad"}, {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"}, - {109, nullptr, "ActivateNpadWithRevision"}, + {109, &Hid::ActivateNpadWithRevision, "ActivateNpadWithRevision"}, {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"}, @@ -364,8 +364,8 @@ public: {208, nullptr, "GetActualVibrationGcErmCommand"}, {209, nullptr, "BeginPermitVibrationSession"}, {210, nullptr, "EndPermitVibrationSession"}, - {300, nullptr, "ActivateConsoleSixAxisSensor"}, - {301, nullptr, "StartConsoleSixAxisSensor"}, + {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"}, + {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"}, {302, nullptr, "StopConsoleSixAxisSensor"}, {303, nullptr, "ActivateSevenSixAxisSensor"}, {304, nullptr, "StartSevenSixAxisSensor"}, @@ -579,6 +579,36 @@ private: rb.Push(RESULT_SUCCESS); LOG_WARNING(Service_HID, "(STUBBED) called"); } + + void ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + + void StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + + void StopSixAxisSensor(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + + void ActivateGesture(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + + void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } }; class HidDbg final : public ServiceFramework<HidDbg> { diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index 098da2a41..c89157a4d 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -99,7 +99,7 @@ private: std::string thread; while (addr < end_addr) { const Field field{static_cast<Field>(Memory::Read8(addr++))}; - const size_t length{Memory::Read8(addr++)}; + const std::size_t length{Memory::Read8(addr++)}; if (static_cast<Field>(Memory::Read8(addr)) == Field::Skip) { ++addr; diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index ed4f5f539..b6075f256 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp @@ -65,7 +65,7 @@ private: LOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push<u32>(0); + rb.Push<u32>(3); } void GetResult(Kernel::HLERequestContext& ctx) { @@ -114,10 +114,11 @@ public: private: void GetClientId(Kernel::HLERequestContext& ctx) { + static constexpr u32 client_id = 1; LOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - rb.Push<u64>(0); + rb.Push<u64>(client_id); // Client ID needs to be non zero otherwise it's considered invalid } void CreateScanRequest(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; @@ -141,10 +142,16 @@ private: rb.Push(RESULT_SUCCESS); } void CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) { - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + ASSERT_MSG(ctx.GetReadBufferSize() == 0x17c, "NetworkProfileData is not the correct size"); + u128 uuid{}; + auto buffer = ctx.ReadBuffer(); + std::memcpy(&uuid, buffer.data() + 8, sizeof(u128)); + + IPC::ResponseBuilder rb{ctx, 6, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<INetworkProfile>(); + rb.PushRaw<u128>(uuid); LOG_DEBUG(Service_NIFM, "called"); } diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index bd05b0a70..c1737defa 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -2,6 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <chrono> +#include <ctime> +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/event.h" #include "core/hle/service/nim/nim.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" @@ -100,19 +104,111 @@ public: } }; +class IEnsureNetworkClockAvailabilityService final + : public ServiceFramework<IEnsureNetworkClockAvailabilityService> { +public: + IEnsureNetworkClockAvailabilityService() + : ServiceFramework("IEnsureNetworkClockAvailabilityService") { + static const FunctionInfo functions[] = { + {0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"}, + {1, &IEnsureNetworkClockAvailabilityService::GetFinishNotificationEvent, + "GetFinishNotificationEvent"}, + {2, &IEnsureNetworkClockAvailabilityService::GetResult, "GetResult"}, + {3, &IEnsureNetworkClockAvailabilityService::Cancel, "Cancel"}, + {4, &IEnsureNetworkClockAvailabilityService::IsProcessing, "IsProcessing"}, + {5, &IEnsureNetworkClockAvailabilityService::GetServerTime, "GetServerTime"}, + }; + RegisterHandlers(functions); + + auto& kernel = Core::System::GetInstance().Kernel(); + finished_event = + Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, + "IEnsureNetworkClockAvailabilityService:FinishEvent"); + } + +private: + Kernel::SharedPtr<Kernel::Event> finished_event; + + void StartTask(Kernel::HLERequestContext& ctx) { + // No need to connect to the internet, just finish the task straight away. + finished_event->Signal(); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_DEBUG(Service_NIM, "called"); + } + + void GetFinishNotificationEvent(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushCopyObjects(finished_event); + LOG_DEBUG(Service_NIM, "called"); + } + + void GetResult(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_DEBUG(Service_NIM, "called"); + } + + void Cancel(Kernel::HLERequestContext& ctx) { + finished_event->Clear(); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_DEBUG(Service_NIM, "called"); + } + + void IsProcessing(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw<u32>(0); // We instantly process the request + LOG_DEBUG(Service_NIM, "called"); + } + + void GetServerTime(Kernel::HLERequestContext& ctx) { + const s64 server_time{std::chrono::duration_cast<std::chrono::seconds>( + std::chrono::system_clock::now().time_since_epoch()) + .count()}; + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw<s64>(server_time); + LOG_DEBUG(Service_NIM, "called"); + } +}; + class NTC final : public ServiceFramework<NTC> { public: explicit NTC() : ServiceFramework{"ntc"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "OpenEnsureNetworkClockAvailabilityService"}, - {100, nullptr, "SuspendAutonomicTimeCorrection"}, - {101, nullptr, "ResumeAutonomicTimeCorrection"}, + {0, &NTC::OpenEnsureNetworkClockAvailabilityService, "OpenEnsureNetworkClockAvailabilityService"}, + {100, &NTC::SuspendAutonomicTimeCorrection, "SuspendAutonomicTimeCorrection"}, + {101, &NTC::ResumeAutonomicTimeCorrection, "ResumeAutonomicTimeCorrection"}, }; // clang-format on RegisterHandlers(functions); } + +private: + void OpenEnsureNetworkClockAvailabilityService(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IEnsureNetworkClockAvailabilityService>(); + LOG_DEBUG(Service_NIM, "called"); + } + + // TODO(ogniK): Do we need these? + void SuspendAutonomicTimeCorrection(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_NIM, "(STUBBED) called"); + } + + void ResumeAutonomicTimeCorrection(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_NIM, "(STUBBED) called"); + } }; void InstallInterfaces(SM::ServiceManager& sm) { diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index 447689a1a..1069d103f 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -78,7 +78,7 @@ enum class LoadState : u32 { }; static void DecryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, - size_t& offset) { + std::size_t& offset) { ASSERT_MSG(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE, "Shared fonts exceeds 17mb!"); ASSERT_MSG(input[0] == EXPECTED_MAGIC, "Failed to derive key, unexpected magic number"); @@ -95,7 +95,7 @@ static void DecryptSharedFont(const std::vector<u32>& input, std::vector<u8>& ou } static void EncryptSharedFont(const std::vector<u8>& input, std::vector<u8>& output, - size_t& offset) { + std::size_t& offset) { ASSERT_MSG(offset + input.size() + 8 < SHARED_FONT_MEM_SIZE, "Shared fonts exceeds 17mb!"); const u32 KEY = EXPECTED_MAGIC ^ EXPECTED_RESULT; std::memcpy(output.data() + offset, &EXPECTED_RESULT, sizeof(u32)); // Magic header @@ -113,7 +113,7 @@ static u32 GetU32Swapped(const u8* data) { } struct PL_U::Impl { - const FontRegion& GetSharedFontRegion(size_t index) const { + const FontRegion& GetSharedFontRegion(std::size_t index) const { if (index >= shared_font_regions.size() || shared_font_regions.empty()) { // No font fallback return EMPTY_REGION; @@ -126,7 +126,7 @@ struct PL_U::Impl { // based on the shared memory dump unsigned cur_offset = 0; - for (size_t i = 0; i < SHARED_FONTS.size(); i++) { + for (std::size_t i = 0; i < SHARED_FONTS.size(); i++) { // Out of shared fonts/invalid font if (GetU32Swapped(input.data() + cur_offset) != EXPECTED_RESULT) { break; @@ -162,7 +162,7 @@ PL_U::PL_U() : ServiceFramework("pl:u"), impl{std::make_unique<Impl>()} { RegisterHandlers(functions); // Attempt to load shared font data from disk const auto nand = FileSystem::GetSystemNANDContents(); - size_t offset = 0; + std::size_t offset = 0; // Rebuild shared fonts from data ncas if (nand->HasEntry(static_cast<u64>(FontArchives::Standard), FileSys::ContentRecordType::Data)) { @@ -344,7 +344,7 @@ void PL_U::GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx) { std::vector<u32> font_sizes; // TODO(ogniK): Have actual priority order - for (size_t i = 0; i < impl->shared_font_regions.size(); i++) { + for (std::size_t i = 0; i < impl->shared_font_regions.size(); i++) { font_codes.push_back(static_cast<u32>(i)); auto region = impl->GetSharedFontRegion(i); font_offsets.push_back(region.offset); 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 25d5a93fa..d8b8037a8 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -71,7 +71,7 @@ u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& } u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) { - size_t num_entries = input.size() / sizeof(IoctlRemapEntry); + std::size_t num_entries = input.size() / sizeof(IoctlRemapEntry); LOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries=0x{:X}", num_entries); diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 7455ddd19..d47b6f659 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -23,7 +23,7 @@ namespace Service::NVFlinger { -constexpr size_t SCREEN_REFRESH_RATE = 60; +constexpr std::size_t SCREEN_REFRESH_RATE = 60; constexpr u64 frame_ticks = static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / SCREEN_REFRESH_RATE); NVFlinger::NVFlinger() { diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 9bb7c7b26..62f049660 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -50,6 +50,7 @@ #include "core/hle/service/nim/nim.h" #include "core/hle/service/ns/ns.h" #include "core/hle/service/nvdrv/nvdrv.h" +#include "core/hle/service/nvflinger/nvflinger.h" #include "core/hle/service/pcie/pcie.h" #include "core/hle/service/pctl/pctl.h" #include "core/hle/service/pcv/pcv.h" @@ -58,7 +59,6 @@ #include "core/hle/service/psc/psc.h" #include "core/hle/service/service.h" #include "core/hle/service/set/settings.h" -#include "core/hle/service/sm/controller.h" #include "core/hle/service/sm/sm.h" #include "core/hle/service/sockets/sockets.h" #include "core/hle/service/spl/module.h" @@ -129,9 +129,9 @@ Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() { return client_port; } -void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, size_t n) { +void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) { handlers.reserve(handlers.size() + n); - for (size_t i = 0; i < n; ++i) { + for (std::size_t i = 0; i < n; ++i) { // Usually this array is sorted by id already, so hint to insert at the end handlers.emplace_hint(handlers.cend(), functions[i].expected_header, functions[i]); } diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 7a051523e..2fc57a82e 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -88,7 +88,7 @@ private: ServiceFrameworkBase(const char* service_name, u32 max_sessions, InvokerFn* handler_invoker); ~ServiceFrameworkBase(); - void RegisterHandlersBase(const FunctionInfoBase* functions, size_t n); + void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n); void ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, const FunctionInfoBase* info); /// Identifier string used to connect to the service. @@ -152,7 +152,7 @@ protected: : ServiceFrameworkBase(service_name, max_sessions, Invoker) {} /// Registers handlers in the service. - template <size_t N> + template <std::size_t N> void RegisterHandlers(const FunctionInfo (&functions)[N]) { RegisterHandlers(functions, N); } @@ -161,7 +161,7 @@ protected: * Registers handlers in the service. Usually prefer using the other RegisterHandlers * overload in order to avoid needing to specify the array size. */ - void RegisterHandlers(const FunctionInfo* functions, size_t n) { + void RegisterHandlers(const FunctionInfo* functions, std::size_t n) { RegisterHandlersBase(functions, n); } diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index 59eb20155..9e5af7839 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -32,21 +32,21 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{ LanguageCode::ZH_HANT, }}; -constexpr size_t pre4_0_0_max_entries = 0xF; -constexpr size_t post4_0_0_max_entries = 0x40; +constexpr std::size_t pre4_0_0_max_entries = 0xF; +constexpr std::size_t post4_0_0_max_entries = 0x40; -LanguageCode GetLanguageCodeFromIndex(size_t index) { +LanguageCode GetLanguageCodeFromIndex(std::size_t index) { return available_language_codes.at(index); } -template <size_t size> +template <std::size_t size> static std::array<LanguageCode, size> MakeLanguageCodeSubset() { std::array<LanguageCode, size> arr; std::copy_n(available_language_codes.begin(), size, arr.begin()); return arr; } -static void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, size_t max_size) { +static void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, std::size_t max_size) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); if (available_language_codes.size() > max_size) diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h index 5f0214359..266f13e46 100644 --- a/src/core/hle/service/set/set.h +++ b/src/core/hle/service/set/set.h @@ -28,7 +28,7 @@ enum class LanguageCode : u64 { ZH_HANS = 0x00736E61482D687A, ZH_HANT = 0x00746E61482D687A, }; -LanguageCode GetLanguageCodeFromIndex(size_t idx); +LanguageCode GetLanguageCodeFromIndex(std::size_t idx); class SET final : public ServiceFramework<SET> { public: diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 18d1641b8..464e79d01 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -15,6 +15,10 @@ namespace Service::SM { +constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorModule::SM, 4); +constexpr ResultCode ERR_INVALID_NAME(ErrorModule::SM, 6); +constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); + ServiceManager::ServiceManager() = default; ServiceManager::~ServiceManager() = default; @@ -24,10 +28,10 @@ void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) { static ResultCode ValidateServiceName(const std::string& name) { if (name.size() <= 0 || name.size() > 8) { - return ERR_INVALID_NAME_SIZE; + return ERR_INVALID_NAME; } if (name.find('\0') != std::string::npos) { - return ERR_NAME_CONTAINS_NUL; + return ERR_INVALID_NAME; } return RESULT_SUCCESS; } @@ -104,7 +108,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { auto client_port = service_manager->GetServicePort(name); if (client_port.Failed()) { - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(client_port.Code()); LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, client_port.Code().raw); if (name.length() == 0) @@ -117,8 +121,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { ASSERT(session.Succeeded()); if (session.Succeeded()) { LOG_DEBUG(Service_SM, "called service={} -> session={}", name, (*session)->GetObjectId()); - IPC::ResponseBuilder rb = - rp.MakeBuilder(2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles); + IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(session.Code()); rb.PushMoveObjects(std::move(session).Unwrap()); } diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index a58d922a0..da2c51082 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -36,12 +36,6 @@ private: std::shared_ptr<ServiceManager> service_manager; }; -constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(-1); -constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1); -constexpr ResultCode ERR_INVALID_NAME_SIZE(-1); -constexpr ResultCode ERR_NAME_CONTAINS_NUL(-1); -constexpr ResultCode ERR_ALREADY_REGISTERED(-1); - class ServiceManager { public: static void InstallInterfaces(std::shared_ptr<ServiceManager> self); diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp index 0d8441fb1..44a6717d0 100644 --- a/src/core/hle/service/spl/module.cpp +++ b/src/core/hle/service/spl/module.cpp @@ -21,7 +21,7 @@ Module::Interface::~Interface() = default; void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - size_t size = ctx.GetWriteBufferSize(); + std::size_t size = ctx.GetWriteBufferSize(); std::vector<u8> data(size); std::generate(data.begin(), data.end(), std::rand); diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 63b86e099..fe0a318ee 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp @@ -71,7 +71,7 @@ private: LOG_WARNING(Service_SSL, "(STUBBED) called"); IPC::RequestParser rp{ctx}; - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index cf94b00e6..2ee60f1ec 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -4,25 +4,28 @@ #include <algorithm> #include <array> +#include <cstring> #include <memory> #include <type_traits> #include <utility> #include <boost/optional.hpp> #include "common/alignment.h" +#include "common/assert.h" +#include "common/common_funcs.h" +#include "common/logging/log.h" #include "common/math_util.h" -#include "common/scope_exit.h" +#include "common/swap.h" #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" #include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/nvflinger/buffer_queue.h" +#include "core/hle/service/nvflinger/nvflinger.h" #include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi_m.h" #include "core/hle/service/vi/vi_s.h" #include "core/hle/service/vi/vi_u.h" #include "core/settings.h" -#include "video_core/renderer_base.h" -#include "video_core/video_core.h" namespace Service::VI { @@ -38,7 +41,7 @@ static_assert(sizeof(DisplayInfo) == 0x60, "DisplayInfo has wrong size"); class Parcel { public: // This default size was chosen arbitrarily. - static constexpr size_t DefaultBufferSize = 0x40; + static constexpr std::size_t DefaultBufferSize = 0x40; Parcel() : buffer(DefaultBufferSize) {} explicit Parcel(std::vector<u8> data) : buffer(std::move(data)) {} virtual ~Parcel() = default; @@ -66,7 +69,7 @@ public: return val; } - std::vector<u8> ReadBlock(size_t length) { + std::vector<u8> ReadBlock(std::size_t length) { ASSERT(read_index + length <= buffer.size()); const u8* const begin = buffer.data() + read_index; const u8* const end = begin + length; @@ -156,8 +159,8 @@ private: static_assert(sizeof(Header) == 16, "ParcelHeader has wrong size"); std::vector<u8> buffer; - size_t read_index = 0; - size_t write_index = 0; + std::size_t read_index = 0; + std::size_t write_index = 0; }; class NativeWindow : public Parcel { @@ -647,7 +650,7 @@ private: u64 layer_id = rp.Pop<u64>(); u64 z_value = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -655,7 +658,7 @@ private: IPC::RequestParser rp{ctx}; u64 layer_id = rp.Pop<u64>(); bool visibility = rp.Pop<bool>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x{:08X}, visibility={}", layer_id, visibility); @@ -744,7 +747,7 @@ private: IPC::RequestParser rp{ctx}; u64 display = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -758,7 +761,7 @@ private: u64 layer_id = nv_flinger->CreateLayer(display); - IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(layer_id); } @@ -769,7 +772,7 @@ private: u32 stack = rp.Pop<u32>(); u64 layer_id = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -777,7 +780,7 @@ private: IPC::RequestParser rp{ctx}; u64 layer_id = rp.Pop<u64>(); bool visibility = rp.Pop<bool>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x{:X}, visibility={}", layer_id, visibility); @@ -834,7 +837,7 @@ private: ASSERT_MSG(name == "Default", "Non-default displays aren't supported yet"); - IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(nv_flinger->OpenDisplay(name)); } @@ -844,7 +847,7 @@ private: IPC::RequestParser rp{ctx}; u64 display_id = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -853,7 +856,7 @@ private: IPC::RequestParser rp{ctx}; u64 display_id = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(6, 0, 0); + IPC::ResponseBuilder rb{ctx, 6}; rb.Push(RESULT_SUCCESS); if (Settings::values.use_docked_mode) { @@ -871,7 +874,7 @@ private: u32 scaling_mode = rp.Pop<u32>(); u64 unknown = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -879,7 +882,7 @@ private: IPC::RequestParser rp{ctx}; DisplayInfo display_info; ctx.WriteBuffer(&display_info, sizeof(DisplayInfo)); - IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(1); LOG_WARNING(Service_VI, "(STUBBED) called"); @@ -900,7 +903,7 @@ private: u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id); NativeWindow native_window{buffer_queue_id}; - IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize())); } @@ -919,7 +922,7 @@ private: u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id); NativeWindow native_window{buffer_queue_id}; - IPC::ResponseBuilder rb = rp.MakeBuilder(6, 0, 0); + IPC::ResponseBuilder rb{ctx, 6}; rb.Push(RESULT_SUCCESS); rb.Push(layer_id); rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize())); @@ -931,7 +934,7 @@ private: IPC::RequestParser rp{ctx}; u64 layer_id = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -942,7 +945,7 @@ private: auto vsync_event = nv_flinger->GetVsyncEvent(display_id); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 1, 0); + IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(vsync_event); } diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h index c2dc83605..e3963502a 100644 --- a/src/core/hle/service/vi/vi.h +++ b/src/core/hle/service/vi/vi.h @@ -4,11 +4,10 @@ #pragma once -#include "core/hle/service/nvflinger/nvflinger.h" #include "core/hle/service/service.h" -namespace CoreTiming { -struct EventType; +namespace Service::NVFlinger { +class NVFlinger; } namespace Service::VI { |