diff options
Diffstat (limited to 'src/core/hle')
33 files changed, 244 insertions, 68 deletions
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index e441a27fc..35448b576 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -30,6 +30,7 @@ HandleTable::~HandleTable() = default; ResultCode HandleTable::SetSize(s32 handle_table_size) { if (static_cast<u32>(handle_table_size) > MAX_COUNT) { + LOG_ERROR(Kernel, "Handle table size {} is greater than {}", handle_table_size, MAX_COUNT); return ERR_OUT_OF_MEMORY; } @@ -80,6 +81,7 @@ ResultVal<Handle> HandleTable::Duplicate(Handle handle) { ResultCode HandleTable::Close(Handle handle) { if (!IsValid(handle)) { + LOG_ERROR(Kernel, "Handle is not valid! handle={:08X}", handle); return ERR_INVALID_HANDLE; } diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 91d94025c..ba0eac4c2 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -13,7 +13,6 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/logging/log.h" -#include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" @@ -57,7 +56,6 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread( return true; }); - auto& kernel = Core::System::GetInstance().Kernel(); if (!writable_event) { // Create event if not provided const auto pair = WritableEvent::CreateEventPair(kernel, "HLE Pause Event: " + reason); @@ -79,9 +77,11 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread( return writable_event; } -HLERequestContext::HLERequestContext(std::shared_ptr<Kernel::ServerSession> server_session, +HLERequestContext::HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory, + std::shared_ptr<ServerSession> server_session, std::shared_ptr<Thread> thread) - : server_session(std::move(server_session)), thread(std::move(thread)) { + : server_session(std::move(server_session)), + thread(std::move(thread)), kernel{kernel}, memory{memory} { cmd_buf[0] = 0; } @@ -216,7 +216,6 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const HandleTabl ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) { auto& owner_process = *thread.GetOwnerProcess(); auto& handle_table = owner_process.GetHandleTable(); - auto& memory = Core::System::GetInstance().Memory(); std::array<u32, IPC::COMMAND_BUFFER_LENGTH> dst_cmdbuf; memory.ReadBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(), @@ -286,7 +285,6 @@ std::vector<u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const { std::vector<u8> buffer; const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && BufferDescriptorA()[buffer_index].Size()}; - auto& memory = Core::System::GetInstance().Memory(); if (is_buffer_a) { ASSERT_MSG(BufferDescriptorA().size() > buffer_index, @@ -319,7 +317,6 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size, size = buffer_size; // TODO(bunnei): This needs to be HW tested } - auto& memory = Core::System::GetInstance().Memory(); if (is_buffer_b) { ASSERT_MSG(BufferDescriptorB().size() > buffer_index, "BufferDescriptorB invalid buffer_index {}", buffer_index); diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index af3330297..b31673928 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -19,6 +19,10 @@ union ResultCode; +namespace Core::Memory { +class Memory; +} + namespace Service { class ServiceFrameworkBase; } @@ -28,6 +32,7 @@ namespace Kernel { class Domain; class HandleTable; class HLERequestContext; +class KernelCore; class Process; class ServerSession; class Thread; @@ -98,7 +103,8 @@ protected: */ class HLERequestContext { public: - explicit HLERequestContext(std::shared_ptr<ServerSession> session, + explicit HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory, + std::shared_ptr<ServerSession> session, std::shared_ptr<Thread> thread); ~HLERequestContext(); @@ -305,6 +311,9 @@ private: std::vector<std::shared_ptr<SessionRequestHandler>> domain_request_handlers; bool is_thread_waiting{}; + + KernelCore& kernel; + Core::Memory::Memory& memory; }; } // namespace Kernel diff --git a/src/core/hle/kernel/memory/address_space_info.cpp b/src/core/hle/kernel/memory/address_space_info.cpp index 27fae05e7..a523a2502 100644 --- a/src/core/hle/kernel/memory/address_space_info.cpp +++ b/src/core/hle/kernel/memory/address_space_info.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphère, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX. +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. #include <array> @@ -49,18 +49,18 @@ constexpr bool IsAllowedIndexForAddress(std::size_t index) { return index < std::size(AddressSpaceInfos) && AddressSpaceInfos[index].GetAddress() != Invalid; } -constexpr std::size_t - AddressSpaceIndices32Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{ +constexpr std::array<std::size_t, static_cast<std::size_t>(AddressSpaceInfo::Type::Count)> + AddressSpaceIndices32Bit{ 0, 1, 0, 2, 0, 3, }; -constexpr std::size_t - AddressSpaceIndices36Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{ +constexpr std::array<std::size_t, static_cast<std::size_t>(AddressSpaceInfo::Type::Count)> + AddressSpaceIndices36Bit{ 4, 5, 4, 6, 4, 7, }; -constexpr std::size_t - AddressSpaceIndices39Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{ +constexpr std::array<std::size_t, static_cast<std::size_t>(AddressSpaceInfo::Type::Count)> + AddressSpaceIndices39Bit{ 9, 8, 8, 10, 12, 11, }; diff --git a/src/core/hle/kernel/memory/address_space_info.h b/src/core/hle/kernel/memory/address_space_info.h index cc9a6421e..c479890be 100644 --- a/src/core/hle/kernel/memory/address_space_info.h +++ b/src/core/hle/kernel/memory/address_space_info.h @@ -2,12 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphère, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX. +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. #pragma once -#include "common/common_funcs.h" #include "common/common_types.h" namespace Kernel::Memory { diff --git a/src/core/hle/kernel/memory/memory_block.h b/src/core/hle/kernel/memory/memory_block.h index 9db1f7b39..9d7839d08 100644 --- a/src/core/hle/kernel/memory/memory_block.h +++ b/src/core/hle/kernel/memory/memory_block.h @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphère, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX. +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. #pragma once diff --git a/src/core/hle/kernel/memory/memory_block_manager.cpp b/src/core/hle/kernel/memory/memory_block_manager.cpp index 900395c37..0732fa5a1 100644 --- a/src/core/hle/kernel/memory/memory_block_manager.cpp +++ b/src/core/hle/kernel/memory/memory_block_manager.cpp @@ -67,7 +67,6 @@ void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState p MemoryPermission prev_perm, MemoryAttribute prev_attribute, MemoryState state, MemoryPermission perm, MemoryAttribute attribute) { - const std::size_t prev_count{memory_block_tree.size()}; const VAddr end_addr{addr + num_pages * PageSize}; iterator node{memory_block_tree.begin()}; @@ -109,7 +108,6 @@ void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState p void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState state, MemoryPermission perm, MemoryAttribute attribute) { - const std::size_t prev_count{memory_block_tree.size()}; const VAddr end_addr{addr + num_pages * PageSize}; iterator node{memory_block_tree.begin()}; @@ -145,7 +143,6 @@ void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState s void MemoryBlockManager::UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func, MemoryPermission perm) { - const std::size_t prev_count{memory_block_tree.size()}; const VAddr end_addr{addr + num_pages * PageSize}; iterator node{memory_block_tree.begin()}; diff --git a/src/core/hle/kernel/memory/memory_block_manager.h b/src/core/hle/kernel/memory/memory_block_manager.h index 9451b5df6..6e1d41075 100644 --- a/src/core/hle/kernel/memory/memory_block_manager.h +++ b/src/core/hle/kernel/memory/memory_block_manager.h @@ -6,7 +6,6 @@ #include <functional> #include <list> -#include <memory> #include "common/common_types.h" #include "core/hle/kernel/memory/memory_block.h" diff --git a/src/core/hle/kernel/memory/memory_manager.cpp b/src/core/hle/kernel/memory/memory_manager.cpp index 3cd4f9e85..6b432e1b2 100644 --- a/src/core/hle/kernel/memory/memory_manager.cpp +++ b/src/core/hle/kernel/memory/memory_manager.cpp @@ -104,9 +104,9 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa // Ensure that we don't leave anything un-freed auto group_guard = detail::ScopeExit([&] { for (const auto& it : page_list.Nodes()) { - const auto num_pages{std::min( + const auto min_num_pages{std::min( it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)}; - chosen_manager.Free(it.GetAddress(), num_pages); + chosen_manager.Free(it.GetAddress(), min_num_pages); } }); @@ -165,9 +165,9 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages, // Free all of the pages for (const auto& it : page_list.Nodes()) { - const auto num_pages{std::min( + const auto min_num_pages{std::min( it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)}; - chosen_manager.Free(it.GetAddress(), num_pages); + chosen_manager.Free(it.GetAddress(), min_num_pages); } return RESULT_SUCCESS; diff --git a/src/core/hle/kernel/memory/memory_manager.h b/src/core/hle/kernel/memory/memory_manager.h index b078d7a5e..3cf444857 100644 --- a/src/core/hle/kernel/memory/memory_manager.h +++ b/src/core/hle/kernel/memory/memory_manager.h @@ -7,7 +7,6 @@ #include <array> #include <mutex> -#include "common/common_funcs.h" #include "common/common_types.h" #include "core/hle/kernel/memory/page_heap.h" #include "core/hle/result.h" diff --git a/src/core/hle/kernel/memory/page_heap.cpp b/src/core/hle/kernel/memory/page_heap.cpp index efcbb3cad..0ab1f7205 100644 --- a/src/core/hle/kernel/memory/page_heap.cpp +++ b/src/core/hle/kernel/memory/page_heap.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphère, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX. +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. #include "core/core.h" #include "core/hle/kernel/memory/page_heap.h" diff --git a/src/core/hle/kernel/memory/page_heap.h b/src/core/hle/kernel/memory/page_heap.h index 380c3f5a1..22b0de860 100644 --- a/src/core/hle/kernel/memory/page_heap.h +++ b/src/core/hle/kernel/memory/page_heap.h @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphère, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX. +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. #pragma once diff --git a/src/core/hle/kernel/memory/page_linked_list.h b/src/core/hle/kernel/memory/page_linked_list.h index 0668d00c6..45dc13eaf 100644 --- a/src/core/hle/kernel/memory/page_linked_list.h +++ b/src/core/hle/kernel/memory/page_linked_list.h @@ -7,7 +7,6 @@ #include <list> #include "common/assert.h" -#include "common/common_funcs.h" #include "common/common_types.h" #include "core/hle/kernel/memory/memory_types.h" #include "core/hle/result.h" diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp index 3281611f8..5d6aac00f 100644 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp @@ -6,7 +6,6 @@ #include "common/assert.h" #include "common/scope_exit.h" #include "core/core.h" -#include "core/device_memory.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/memory/address_space_info.h" diff --git a/src/core/hle/kernel/memory/page_table.h b/src/core/hle/kernel/memory/page_table.h index a867aa050..ce0d38849 100644 --- a/src/core/hle/kernel/memory/page_table.h +++ b/src/core/hle/kernel/memory/page_table.h @@ -4,16 +4,15 @@ #pragma once -#include <list> #include <memory> #include <mutex> -#include "common/common_funcs.h" #include "common/common_types.h" #include "common/page_table.h" #include "core/file_sys/program_metadata.h" #include "core/hle/kernel/memory/memory_block.h" #include "core/hle/kernel/memory/memory_manager.h" +#include "core/hle/result.h" namespace Core { class System; diff --git a/src/core/hle/kernel/memory/slab_heap.h b/src/core/hle/kernel/memory/slab_heap.h index be95fc3f7..465eaddb3 100644 --- a/src/core/hle/kernel/memory/slab_heap.h +++ b/src/core/hle/kernel/memory/slab_heap.h @@ -2,15 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -// This file references various implementation details from Atmosphère, an open-source firmware for -// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX. +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. #pragma once #include <atomic> #include "common/assert.h" -#include "common/common_funcs.h" #include "common/common_types.h" namespace Kernel::Memory { diff --git a/src/core/hle/kernel/memory/system_control.cpp b/src/core/hle/kernel/memory/system_control.cpp index 9cae3c6cb..2f98e9c4c 100644 --- a/src/core/hle/kernel/memory/system_control.cpp +++ b/src/core/hle/kernel/memory/system_control.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#pragma once - #include <random> #include "core/hle/kernel/memory/system_control.h" diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index eff4e45b0..7869eb32b 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -7,6 +7,7 @@ #include <vector> #include "common/assert.h" +#include "common/logging/log.h" #include "core/core.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" @@ -67,6 +68,7 @@ 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) { + LOG_ERROR(Kernel, "Address is not 4-byte aligned! address={:016X}", address); return ERR_INVALID_ADDRESS; } @@ -88,6 +90,8 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, } if (holding_thread == nullptr) { + LOG_ERROR(Kernel, "Holding thread does not exist! thread_handle={:08X}", + holding_thread_handle); return ERR_INVALID_HANDLE; } @@ -109,6 +113,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, ResultCode Mutex::Release(VAddr address) { // The mutex address must be 4-byte aligned if ((address % sizeof(u32)) != 0) { + LOG_ERROR(Kernel, "Address is not 4-byte aligned! address={:016X}", address); return ERR_INVALID_ADDRESS; } diff --git a/src/core/hle/kernel/process_capability.cpp b/src/core/hle/kernel/process_capability.cpp index 48e5ae682..63880f13d 100644 --- a/src/core/hle/kernel/process_capability.cpp +++ b/src/core/hle/kernel/process_capability.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "common/bit_util.h" +#include "common/logging/log.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/memory/page_table.h" @@ -119,22 +120,30 @@ ResultCode ProcessCapabilities::ParseCapabilities(const u32* capabilities, // The MapPhysical type uses two descriptor flags for its parameters. // If there's only one, then there's a problem. if (i >= num_capabilities) { + LOG_ERROR(Kernel, "Invalid combination! i={}", i); return ERR_INVALID_COMBINATION; } const auto size_flags = capabilities[i]; if (GetCapabilityType(size_flags) != CapabilityType::MapPhysical) { + LOG_ERROR(Kernel, "Invalid capability type! size_flags={}", size_flags); return ERR_INVALID_COMBINATION; } const auto result = HandleMapPhysicalFlags(descriptor, size_flags, page_table); if (result.IsError()) { + LOG_ERROR(Kernel, "Failed to map physical flags! descriptor={}, size_flags={}", + descriptor, size_flags); return result; } } else { const auto result = ParseSingleFlagCapability(set_flags, set_svc_bits, descriptor, page_table); if (result.IsError()) { + LOG_ERROR( + Kernel, + "Failed to parse capability flag! set_flags={}, set_svc_bits={}, descriptor={}", + set_flags, set_svc_bits, descriptor); return result; } } @@ -162,6 +171,9 @@ ResultCode ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& s const u32 flag_length = GetFlagBitOffset(type); const u32 set_flag = 1U << flag_length; if ((set_flag & set_flags & InitializeOnceMask) != 0) { + LOG_ERROR(Kernel, + "Attempted to initialize flags that may only be initialized once. set_flags={}", + set_flags); return ERR_INVALID_COMBINATION; } set_flags |= set_flag; @@ -187,6 +199,7 @@ ResultCode ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& s break; } + LOG_ERROR(Kernel, "Invalid capability type! type={}", static_cast<u32>(type)); return ERR_INVALID_CAPABILITY_DESCRIPTOR; } @@ -208,23 +221,31 @@ void ProcessCapabilities::Clear() { ResultCode ProcessCapabilities::HandlePriorityCoreNumFlags(u32 flags) { if (priority_mask != 0 || core_mask != 0) { + LOG_ERROR(Kernel, "Core or priority mask are not zero! priority_mask={}, core_mask={}", + priority_mask, core_mask); return ERR_INVALID_CAPABILITY_DESCRIPTOR; } const u32 core_num_min = (flags >> 16) & 0xFF; const u32 core_num_max = (flags >> 24) & 0xFF; if (core_num_min > core_num_max) { + LOG_ERROR(Kernel, "Core min is greater than core max! core_num_min={}, core_num_max={}", + core_num_min, core_num_max); return ERR_INVALID_COMBINATION; } const u32 priority_min = (flags >> 10) & 0x3F; const u32 priority_max = (flags >> 4) & 0x3F; if (priority_min > priority_max) { + LOG_ERROR(Kernel, + "Priority min is greater than priority max! priority_min={}, priority_max={}", + core_num_min, priority_max); return ERR_INVALID_COMBINATION; } // The switch only has 4 usable cores. if (core_num_max >= 4) { + LOG_ERROR(Kernel, "Invalid max cores specified! core_num_max={}", core_num_max); return ERR_INVALID_PROCESSOR_ID; } @@ -259,6 +280,7 @@ ResultCode ProcessCapabilities::HandleSyscallFlags(u32& set_svc_bits, u32 flags) } if (svc_number >= svc_capabilities.size()) { + LOG_ERROR(Kernel, "Process svc capability is out of range! svc_number={}", svc_number); return ERR_OUT_OF_RANGE; } @@ -295,6 +317,8 @@ ResultCode ProcessCapabilities::HandleInterruptFlags(u32 flags) { // emulate that, it's sufficient to mark every interrupt as defined. if (interrupt >= interrupt_capabilities.size()) { + LOG_ERROR(Kernel, "Process interrupt capability is out of range! svc_number={}", + interrupt); return ERR_OUT_OF_RANGE; } @@ -307,6 +331,7 @@ ResultCode ProcessCapabilities::HandleInterruptFlags(u32 flags) { ResultCode ProcessCapabilities::HandleProgramTypeFlags(u32 flags) { const u32 reserved = flags >> 17; if (reserved != 0) { + LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); return ERR_RESERVED_VALUE; } @@ -324,6 +349,9 @@ ResultCode ProcessCapabilities::HandleKernelVersionFlags(u32 flags) { const u32 major_version = kernel_version >> 19; if (major_version != 0 || flags < 0x80000) { + LOG_ERROR(Kernel, + "Kernel version is non zero or flags are too small! major_version={}, flags={}", + major_version, flags); return ERR_INVALID_CAPABILITY_DESCRIPTOR; } @@ -334,6 +362,7 @@ ResultCode ProcessCapabilities::HandleKernelVersionFlags(u32 flags) { ResultCode ProcessCapabilities::HandleHandleTableFlags(u32 flags) { const u32 reserved = flags >> 26; if (reserved != 0) { + LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); return ERR_RESERVED_VALUE; } @@ -344,6 +373,7 @@ ResultCode ProcessCapabilities::HandleHandleTableFlags(u32 flags) { ResultCode ProcessCapabilities::HandleDebugFlags(u32 flags) { const u32 reserved = flags >> 19; if (reserved != 0) { + LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); return ERR_RESERVED_VALUE; } diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp index 9d3d3a81b..00860fcbd 100644 --- a/src/core/hle/kernel/readable_event.cpp +++ b/src/core/hle/kernel/readable_event.cpp @@ -4,6 +4,7 @@ #include <algorithm> #include "common/assert.h" +#include "common/logging/log.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/readable_event.h" @@ -23,10 +24,12 @@ void ReadableEvent::Acquire(Thread* thread) { } void ReadableEvent::Signal() { - if (!is_signaled) { - is_signaled = true; - SynchronizationObject::Signal(); - }; + if (is_signaled) { + return; + } + + is_signaled = true; + SynchronizationObject::Signal(); } void ReadableEvent::Clear() { @@ -35,6 +38,8 @@ void ReadableEvent::Clear() { ResultCode ReadableEvent::Reset() { if (!is_signaled) { + LOG_ERROR(Kernel, "Handle is not signaled! object_id={}, object_type={}, object_name={}", + GetObjectId(), GetTypeName(), GetName()); return ERR_INVALID_STATE; } diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index 96e5b9892..d9beaa3a4 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -69,6 +69,8 @@ ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) { limit[index] = value; return RESULT_SUCCESS; } else { + LOG_ERROR(Kernel, "Limit value is too large! resource={}, value={}, index={}", + static_cast<u32>(resource), value, index); return ERR_INVALID_STATE; } } diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 0f102ca44..25438b86b 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -137,8 +137,8 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con ResultCode ServerSession::QueueSyncRequest(std::shared_ptr<Thread> thread, Core::Memory::Memory& memory) { u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(thread->GetTLSAddress()))}; - std::shared_ptr<Kernel::HLERequestContext> context{ - std::make_shared<Kernel::HLERequestContext>(SharedFrom(this), std::move(thread))}; + auto context = + std::make_shared<HLERequestContext>(kernel, memory, SharedFrom(this), std::move(thread)); context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); request_queue.Push(std::move(context)); diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 41ef2caf6..4ae4529f5 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -685,6 +685,8 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource: case GetInfoType::TotalPhysicalMemoryUsedWithoutSystemResource: { if (info_sub_id != 0) { + LOG_ERROR(Kernel_SVC, "Info sub id is non zero! info_id={}, info_sub_id={}", info_id, + info_sub_id); return ERR_INVALID_ENUM_VALUE; } @@ -692,6 +694,8 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha system.Kernel().CurrentProcess()->GetHandleTable(); const auto process = current_process_handle_table.Get<Process>(static_cast<Handle>(handle)); if (!process) { + LOG_ERROR(Kernel_SVC, "Process is not valid! info_id={}, info_sub_id={}, handle={:08X}", + info_id, info_sub_id, handle); return ERR_INVALID_HANDLE; } @@ -783,10 +787,13 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha case GetInfoType::RegisterResourceLimit: { if (handle != 0) { + LOG_ERROR(Kernel, "Handle is non zero! handle={:08X}", handle); return ERR_INVALID_HANDLE; } if (info_sub_id != 0) { + LOG_ERROR(Kernel, "Info sub id is non zero! info_id={}, info_sub_id={}", info_id, + info_sub_id); return ERR_INVALID_COMBINATION; } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index a919750a6..db7f379ac 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -423,6 +423,8 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { if (new_core == THREADPROCESSORID_DONT_UPDATE) { new_core = use_override ? ideal_core_override : ideal_core; if ((new_affinity_mask & (1ULL << new_core)) == 0) { + LOG_ERROR(Kernel, "New affinity mask is incorrect! new_core={}, new_affinity_mask={}", + new_core, new_affinity_mask); return ERR_INVALID_COMBINATION; } } diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 9a7992f58..630a8b048 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -228,7 +228,8 @@ public: class IManagerForApplication final : public ServiceFramework<IManagerForApplication> { public: - IManagerForApplication() : ServiceFramework("IManagerForApplication") { + explicit IManagerForApplication(Common::UUID user_id) + : ServiceFramework("IManagerForApplication"), user_id(user_id) { // clang-format off static const FunctionInfo functions[] = { {0, &IManagerForApplication::CheckAvailability, "CheckAvailability"}, @@ -254,12 +255,14 @@ private: } void GetAccountId(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - // Should return a nintendo account ID + LOG_DEBUG(Service_ACC, "called"); + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - rb.PushRaw<u64>(1); + rb.PushRaw<u64>(user_id.GetNintendoID()); } + + Common::UUID user_id; }; void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) { @@ -382,7 +385,7 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo LOG_DEBUG(Service_ACC, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IManagerForApplication>(); + rb.PushIpcInterface<IManagerForApplication>(profile_manager->GetLastOpenedUser()); } void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 9450de6e9..4df74c4f9 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1335,12 +1335,23 @@ void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) { } void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + LOG_DEBUG(Service_AM, "called"); + + std::array<u8, 0x10> version_string{}; + + FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()}; + const auto res = pm.GetControlMetadata(); + if (res.first != nullptr) { + const auto& version = res.first->GetVersionString(); + std::copy(version.begin(), version.end(), version_string.begin()); + } else { + constexpr u128 default_version = {1, 0}; + std::memcpy(version_string.data(), default_version.data(), sizeof(u128)); + } IPC::ResponseBuilder rb{ctx, 6}; rb.Push(RESULT_SUCCESS); - rb.Push<u64>(1); - rb.Push<u64>(0); + rb.PushRaw(version_string); } void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { @@ -1514,14 +1525,15 @@ void InstallInterfaces(SM::ServiceManager& service_manager, std::make_shared<TCAP>()->InstallAsService(service_manager); } -IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") { +IHomeMenuFunctions::IHomeMenuFunctions(Kernel::KernelCore& kernel) + : ServiceFramework("IHomeMenuFunctions"), kernel(kernel) { // clang-format off static const FunctionInfo functions[] = { {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"}, {11, nullptr, "LockForeground"}, {12, nullptr, "UnlockForeground"}, {20, nullptr, "PopFromGeneralChannel"}, - {21, nullptr, "GetPopFromGeneralChannelEvent"}, + {21, &IHomeMenuFunctions::GetPopFromGeneralChannelEvent, "GetPopFromGeneralChannelEvent"}, {30, nullptr, "GetHomeButtonWriterLockAccessor"}, {31, nullptr, "GetWriterLockAccessorEx"}, {100, nullptr, "PopRequestLaunchApplicationForDebug"}, @@ -1531,6 +1543,9 @@ IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions" // clang-format on RegisterHandlers(functions); + + pop_from_general_channel_event = Kernel::WritableEvent::CreateEventPair( + kernel, "IHomeMenuFunctions:PopFromGeneralChannelEvent"); } IHomeMenuFunctions::~IHomeMenuFunctions() = default; @@ -1542,6 +1557,14 @@ void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) rb.Push(RESULT_SUCCESS); } +void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushCopyObjects(pop_from_general_channel_event.readable); +} + IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") { // clang-format off static const FunctionInfo functions[] = { diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index dfa701d73..469f7f814 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -292,11 +292,15 @@ private: class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { public: - IHomeMenuFunctions(); + explicit IHomeMenuFunctions(Kernel::KernelCore& kernel); ~IHomeMenuFunctions() override; private: void RequestToGetForeground(Kernel::HLERequestContext& ctx); + void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx); + + Kernel::EventPair pop_from_general_channel_event; + Kernel::KernelCore& kernel; }; class IGlobalStateController final : public ServiceFramework<IGlobalStateController> { diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp index e454b77d8..9df286d17 100644 --- a/src/core/hle/service/am/applet_ae.cpp +++ b/src/core/hle/service/am/applet_ae.cpp @@ -202,7 +202,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IHomeMenuFunctions>(); + rb.PushIpcInterface<IHomeMenuFunctions>(system.Kernel()); } void GetGlobalStateController(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index d7f1d348d..3e2299426 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp @@ -2,6 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" #include "core/hle/service/audio/audin_u.h" namespace Service::Audio { @@ -36,11 +39,12 @@ public: AudInU::AudInU() : ServiceFramework("audin:u") { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "ListAudioIns"}, - {1, nullptr, "OpenAudioIn"}, - {2, nullptr, "Unknown"}, - {3, nullptr, "OpenAudioInAuto"}, - {4, nullptr, "ListAudioInsAuto"}, + {0, &AudInU::ListAudioIns, "ListAudioIns"}, + {1, &AudInU::OpenAudioIn, "OpenAudioIn"}, + {2, &AudInU::ListAudioIns, "ListAudioInsAuto"}, + {3, &AudInU::OpenAudioIn, "OpenAudioInAuto"}, + {4, &AudInU::ListAudioInsAutoFiltered, "ListAudioInsAutoFiltered"}, + {5, &AudInU::OpenAudioInProtocolSpecified, "OpenAudioInProtocolSpecified"}, }; // clang-format on @@ -49,4 +53,60 @@ AudInU::AudInU() : ServiceFramework("audin:u") { AudInU::~AudInU() = default; +void AudInU::ListAudioIns(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + const std::size_t count = ctx.GetWriteBufferSize() / sizeof(AudioInDeviceName); + + const std::size_t device_count = std::min(count, audio_device_names.size()); + std::vector<AudioInDeviceName> device_names; + device_names.reserve(device_count); + + for (std::size_t i = 0; i < device_count; i++) { + const auto& device_name = audio_device_names[i]; + auto& entry = device_names.emplace_back(); + device_name.copy(entry.data(), device_name.size()); + } + + ctx.WriteBuffer(device_names); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(static_cast<u32>(device_names.size())); +} + +void AudInU::ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + constexpr u32 device_count = 0; + + // Since we don't actually use any other audio input devices, we return 0 devices. Filtered + // device listing just omits the default input device + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(static_cast<u32>(device_count)); +} + +void AudInU::OpenInOutImpl(Kernel::HLERequestContext& ctx) { + AudInOutParams params{}; + params.channel_count = 2; + params.sample_format = SampleFormat::PCM16; + params.sample_rate = 48000; + params.state = State::Started; + + IPC::ResponseBuilder rb{ctx, 6, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw<AudInOutParams>(params); + rb.PushIpcInterface<IAudioIn>(); +} + +void AudInU::OpenAudioIn(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_Audio, "(STUBBED) called"); + OpenInOutImpl(ctx); +} + +void AudInU::OpenAudioInProtocolSpecified(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_Audio, "(STUBBED) called"); + OpenInOutImpl(ctx); +} + } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audin_u.h b/src/core/hle/service/audio/audin_u.h index 0538b9560..a599f4a64 100644 --- a/src/core/hle/service/audio/audin_u.h +++ b/src/core/hle/service/audio/audin_u.h @@ -16,6 +16,35 @@ class AudInU final : public ServiceFramework<AudInU> { public: explicit AudInU(); ~AudInU() override; + +private: + enum class SampleFormat : u32_le { + PCM16 = 2, + }; + + enum class State : u32_le { + Started = 0, + Stopped = 1, + }; + + struct AudInOutParams { + u32_le sample_rate{}; + u32_le channel_count{}; + SampleFormat sample_format{}; + State state{}; + }; + static_assert(sizeof(AudInOutParams) == 0x10, "AudInOutParams is an invalid size"); + + using AudioInDeviceName = std::array<char, 256>; + static constexpr std::array<std::string_view, 1> audio_device_names{{ + "BuiltInHeadset", + }}; + + void ListAudioIns(Kernel::HLERequestContext& ctx); + void ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx); + void OpenInOutImpl(Kernel::HLERequestContext& ctx); + void OpenAudioIn(Kernel::HLERequestContext& ctx); + void OpenAudioInProtocolSpecified(Kernel::HLERequestContext& ctx); }; } // namespace Service::Audio diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp index 5febe8fc1..d29e78d7e 100644 --- a/src/core/hle/service/bcat/backend/boxcat.cpp +++ b/src/core/hle/service/bcat/backend/boxcat.cpp @@ -4,8 +4,8 @@ #include <fmt/ostream.h> #include <httplib.h> -#include <json.hpp> #include <mbedtls/sha256.h> +#include <nlohmann/json.hpp> #include "common/hex_util.h" #include "common/logging/backend.h" #include "common/logging/log.h" diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 5559587e3..c84cb1483 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -157,7 +157,7 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) { {11, &Hid::ActivateTouchScreen, "ActivateTouchScreen"}, {21, &Hid::ActivateMouse, "ActivateMouse"}, {31, &Hid::ActivateKeyboard, "ActivateKeyboard"}, - {32, nullptr, "SendKeyboardLockKeyEvent"}, + {32, &Hid::SendKeyboardLockKeyEvent, "SendKeyboardLockKeyEvent"}, {40, nullptr, "AcquireXpadIdEventHandle"}, {41, nullptr, "ReleaseXpadIdEventHandle"}, {51, &Hid::ActivateXpad, "ActivateXpad"}, @@ -871,6 +871,15 @@ void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); } +void Hid::SendKeyboardLockKeyEvent(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto flags{rp.Pop<u32>()}; + LOG_WARNING(Service_HID, "(STUBBED) called. flags={}", flags); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + class HidDbg final : public ServiceFramework<HidDbg> { public: explicit HidDbg() : ServiceFramework{"hid:dbg"} { diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 23552efb1..c8ed4ad8b 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -130,6 +130,7 @@ private: void SetPalmaBoostMode(Kernel::HLERequestContext& ctx); void StopSevenSixAxisSensor(Kernel::HLERequestContext& ctx); void InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx); + void SendKeyboardLockKeyEvent(Kernel::HLERequestContext& ctx); std::shared_ptr<IAppletResource> applet_resource; Core::System& system; |