diff options
Diffstat (limited to 'src/core/hle')
27 files changed, 516 insertions, 204 deletions
diff --git a/src/core/hle/kernel/k_class_token.cpp b/src/core/hle/kernel/k_class_token.cpp index beb8a2a05..0be0027be 100644 --- a/src/core/hle/kernel/k_class_token.cpp +++ b/src/core/hle/kernel/k_class_token.cpp @@ -84,50 +84,43 @@ static_assert(ClassToken<KTransferMemory> == ((0b10010001 << 8) | ClassToken<KAu // Ensure that the token hierarchy reflects the class hierarchy. // Base classes. -static_assert(!std::is_final<KSynchronizationObject>::value && - std::is_base_of<KAutoObject, KSynchronizationObject>::value); -static_assert(!std::is_final<KReadableEvent>::value && - std::is_base_of<KSynchronizationObject, KReadableEvent>::value); +static_assert(!std::is_final_v<KSynchronizationObject> && + std::is_base_of_v<KAutoObject, KSynchronizationObject>); +static_assert(!std::is_final_v<KReadableEvent> && + std::is_base_of_v<KSynchronizationObject, KReadableEvent>); // Final classes -// static_assert(std::is_final<KInterruptEvent>::value && -// std::is_base_of<KReadableEvent, KInterruptEvent>::value); -// static_assert(std::is_final<KDebug>::value && -// std::is_base_of<KSynchronizationObject, KDebug>::value); -static_assert(std::is_final<KThread>::value && - std::is_base_of<KSynchronizationObject, KThread>::value); -static_assert(std::is_final<KServerPort>::value && - std::is_base_of<KSynchronizationObject, KServerPort>::value); -static_assert(std::is_final<KServerSession>::value && - std::is_base_of<KSynchronizationObject, KServerSession>::value); -static_assert(std::is_final<KClientPort>::value && - std::is_base_of<KSynchronizationObject, KClientPort>::value); -static_assert(std::is_final<KClientSession>::value && - std::is_base_of<KAutoObject, KClientSession>::value); -static_assert(std::is_final<KProcess>::value && - std::is_base_of<KSynchronizationObject, KProcess>::value); -static_assert(std::is_final<KResourceLimit>::value && - std::is_base_of<KAutoObject, KResourceLimit>::value); -// static_assert(std::is_final<KLightSession>::value && -// std::is_base_of<KAutoObject, KLightSession>::value); -static_assert(std::is_final<KPort>::value && std::is_base_of<KAutoObject, KPort>::value); -static_assert(std::is_final<KSession>::value && std::is_base_of<KAutoObject, KSession>::value); -static_assert(std::is_final<KSharedMemory>::value && - std::is_base_of<KAutoObject, KSharedMemory>::value); -static_assert(std::is_final<KEvent>::value && std::is_base_of<KAutoObject, KEvent>::value); -static_assert(std::is_final<KWritableEvent>::value && - std::is_base_of<KAutoObject, KWritableEvent>::value); -// static_assert(std::is_final<KLightClientSession>::value && -// std::is_base_of<KAutoObject, KLightClientSession>::value); -// static_assert(std::is_final<KLightServerSession>::value && -// std::is_base_of<KAutoObject, KLightServerSession>::value); -static_assert(std::is_final<KTransferMemory>::value && - std::is_base_of<KAutoObject, KTransferMemory>::value); -// static_assert(std::is_final<KDeviceAddressSpace>::value && -// std::is_base_of<KAutoObject, KDeviceAddressSpace>::value); -// static_assert(std::is_final<KSessionRequest>::value && -// std::is_base_of<KAutoObject, KSessionRequest>::value); -// static_assert(std::is_final<KCodeMemory>::value && -// std::is_base_of<KAutoObject, KCodeMemory>::value); +// static_assert(std::is_final_v<KInterruptEvent> && +// std::is_base_of_v<KReadableEvent, KInterruptEvent>); +// static_assert(std::is_final_v<KDebug> && +// std::is_base_of_v<KSynchronizationObject, KDebug>); +static_assert(std::is_final_v<KThread> && std::is_base_of_v<KSynchronizationObject, KThread>); +static_assert(std::is_final_v<KServerPort> && + std::is_base_of_v<KSynchronizationObject, KServerPort>); +static_assert(std::is_final_v<KServerSession> && + std::is_base_of_v<KSynchronizationObject, KServerSession>); +static_assert(std::is_final_v<KClientPort> && + std::is_base_of_v<KSynchronizationObject, KClientPort>); +static_assert(std::is_final_v<KClientSession> && std::is_base_of_v<KAutoObject, KClientSession>); +static_assert(std::is_final_v<KProcess> && std::is_base_of_v<KSynchronizationObject, KProcess>); +static_assert(std::is_final_v<KResourceLimit> && std::is_base_of_v<KAutoObject, KResourceLimit>); +// static_assert(std::is_final_v<KLightSession> && +// std::is_base_of_v<KAutoObject, KLightSession>); +static_assert(std::is_final_v<KPort> && std::is_base_of_v<KAutoObject, KPort>); +static_assert(std::is_final_v<KSession> && std::is_base_of_v<KAutoObject, KSession>); +static_assert(std::is_final_v<KSharedMemory> && std::is_base_of_v<KAutoObject, KSharedMemory>); +static_assert(std::is_final_v<KEvent> && std::is_base_of_v<KAutoObject, KEvent>); +static_assert(std::is_final_v<KWritableEvent> && std::is_base_of_v<KAutoObject, KWritableEvent>); +// static_assert(std::is_final_v<KLightClientSession> && +// std::is_base_of_v<KAutoObject, KLightClientSession>); +// static_assert(std::is_final_v<KLightServerSession> && +// std::is_base_of_v<KAutoObject, KLightServerSession>); +static_assert(std::is_final_v<KTransferMemory> && std::is_base_of_v<KAutoObject, KTransferMemory>); +// static_assert(std::is_final_v<KDeviceAddressSpace> && +// std::is_base_of_v<KAutoObject, KDeviceAddressSpace>); +// static_assert(std::is_final_v<KSessionRequest> && +// std::is_base_of_v<KAutoObject, KSessionRequest>); +// static_assert(std::is_final_v<KCodeMemory> && +// std::is_base_of_v<KAutoObject, KCodeMemory>); } // namespace Kernel diff --git a/src/core/hle/kernel/k_client_port.h b/src/core/hle/kernel/k_client_port.h index 8501156e8..f2fff3b01 100644 --- a/src/core/hle/kernel/k_client_port.h +++ b/src/core/hle/kernel/k_client_port.h @@ -22,7 +22,7 @@ class KClientPort final : public KSynchronizationObject { public: explicit KClientPort(KernelCore& kernel_); - virtual ~KClientPort() override; + ~KClientPort() override; void Initialize(KPort* parent_, s32 max_sessions_, std::string&& name_); void OnSessionFinalized(); @@ -49,8 +49,8 @@ public: bool IsServerClosed() const; // Overridden virtual functions. - virtual void Destroy() override; - virtual bool IsSignaled() const override; + void Destroy() override; + bool IsSignaled() const override; ResultCode CreateSession(KClientSession** out); diff --git a/src/core/hle/kernel/k_client_session.h b/src/core/hle/kernel/k_client_session.h index 720a8c243..b11d5b4e3 100644 --- a/src/core/hle/kernel/k_client_session.h +++ b/src/core/hle/kernel/k_client_session.h @@ -34,7 +34,7 @@ class KClientSession final public: explicit KClientSession(KernelCore& kernel_); - virtual ~KClientSession(); + ~KClientSession() override; void Initialize(KSession* parent_, std::string&& name_) { // Set member variables. @@ -42,7 +42,7 @@ public: name = std::move(name_); } - virtual void Destroy() override; + void Destroy() override; static void PostDestroy([[maybe_unused]] uintptr_t arg) {} KSession* GetParent() const { diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h index 9a59ffb70..3d3ec99e2 100644 --- a/src/core/hle/kernel/k_event.h +++ b/src/core/hle/kernel/k_event.h @@ -20,23 +20,21 @@ class KEvent final : public KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObj public: explicit KEvent(KernelCore& kernel_); - virtual ~KEvent(); + ~KEvent() override; void Initialize(std::string&& name); - virtual void Finalize() override; + void Finalize() override; - virtual bool IsInitialized() const override { + bool IsInitialized() const override { return initialized; } - virtual uintptr_t GetPostDestroyArgument() const override { + uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(owner); } - static void PostDestroy(uintptr_t arg); - - virtual KProcess* GetOwner() const override { + KProcess* GetOwner() const override { return owner; } @@ -48,6 +46,8 @@ public: return writable_event; } + static void PostDestroy(uintptr_t arg); + private: KReadableEvent readable_event; KWritableEvent writable_event; diff --git a/src/core/hle/kernel/k_port.h b/src/core/hle/kernel/k_port.h index 960f1f3a3..4018ea2df 100644 --- a/src/core/hle/kernel/k_port.h +++ b/src/core/hle/kernel/k_port.h @@ -22,7 +22,7 @@ class KPort final : public KAutoObjectWithSlabHeapAndContainer<KPort, KAutoObjec public: explicit KPort(KernelCore& kernel_); - virtual ~KPort(); + ~KPort() override; static void PostDestroy([[maybe_unused]] uintptr_t arg) {} @@ -59,7 +59,6 @@ private: ServerClosed = 3, }; -private: KServerPort server; KClientPort client; State state{State::Invalid}; diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 123d71cd3..c0656b9af 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h @@ -331,19 +331,19 @@ public: void LoadModule(CodeSet code_set, VAddr base_addr); - virtual bool IsInitialized() const override { + bool IsInitialized() const override { return is_initialized; } static void PostDestroy([[maybe_unused]] uintptr_t arg) {} - virtual void Finalize(); + void Finalize() override; - virtual u64 GetId() const override final { + u64 GetId() const override { return GetProcessID(); } - virtual bool IsSignaled() const override; + bool IsSignaled() const override; void PinCurrentThread(); void UnpinCurrentThread(); diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h index 33cd1dd3e..b2850ac7b 100644 --- a/src/core/hle/kernel/k_readable_event.h +++ b/src/core/hle/kernel/k_readable_event.h @@ -31,8 +31,8 @@ public: return parent; } - virtual bool IsSignaled() const override; - virtual void Destroy() override; + bool IsSignaled() const override; + void Destroy() override; ResultCode Signal(); ResultCode Clear(); diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h index 0debbbb51..fab6005ff 100644 --- a/src/core/hle/kernel/k_resource_limit.h +++ b/src/core/hle/kernel/k_resource_limit.h @@ -37,10 +37,10 @@ class KResourceLimit final public: explicit KResourceLimit(KernelCore& kernel_); - virtual ~KResourceLimit(); + ~KResourceLimit() override; void Initialize(const Core::Timing::CoreTiming* core_timing_); - virtual void Finalize() override; + void Finalize() override; s64 GetLimitValue(LimitableResource which) const; s64 GetCurrentValue(LimitableResource which) const; diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 2f82fbcd6..6a7d80d03 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -659,7 +659,6 @@ void KScheduler::Unload(KThread* thread) { if (thread) { if (thread->IsCallingSvc()) { - system.ArmInterface(core_id).ExceptionalExit(); thread->ClearIsCallingSvc(); } if (!thread->IsTerminationRequested()) { diff --git a/src/core/hle/kernel/k_server_port.h b/src/core/hle/kernel/k_server_port.h index d1a757ec3..55481d63f 100644 --- a/src/core/hle/kernel/k_server_port.h +++ b/src/core/hle/kernel/k_server_port.h @@ -25,12 +25,9 @@ class SessionRequestHandler; class KServerPort final : public KSynchronizationObject { KERNEL_AUTOOBJECT_TRAITS(KServerPort, KSynchronizationObject); -private: - using SessionList = boost::intrusive::list<KServerSession>; - public: explicit KServerPort(KernelCore& kernel_); - virtual ~KServerPort() override; + ~KServerPort() override; void Initialize(KPort* parent_, std::string&& name_); @@ -63,13 +60,14 @@ public: bool IsLight() const; // Overridden virtual functions. - virtual void Destroy() override; - virtual bool IsSignaled() const override; + void Destroy() override; + bool IsSignaled() const override; private: + using SessionList = boost::intrusive::list<KServerSession>; + void CleanupSessions(); -private: SessionList session_list; SessionRequestHandlerPtr session_handler; KPort* parent{}; diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h index dd4de2904..27b757ad2 100644 --- a/src/core/hle/kernel/k_server_session.h +++ b/src/core/hle/kernel/k_server_session.h @@ -42,9 +42,9 @@ class KServerSession final : public KSynchronizationObject, public: explicit KServerSession(KernelCore& kernel_); - virtual ~KServerSession() override; + ~KServerSession() override; - virtual void Destroy() override; + void Destroy() override; void Initialize(KSession* parent_, std::string&& name_); @@ -56,7 +56,7 @@ public: return parent; } - virtual bool IsSignaled() const override; + bool IsSignaled() const override; void OnClientClosed(); diff --git a/src/core/hle/kernel/k_session.h b/src/core/hle/kernel/k_session.h index a981fd1f6..4ddd080d2 100644 --- a/src/core/hle/kernel/k_session.h +++ b/src/core/hle/kernel/k_session.h @@ -18,17 +18,17 @@ class KSession final : public KAutoObjectWithSlabHeapAndContainer<KSession, KAut public: explicit KSession(KernelCore& kernel_); - virtual ~KSession() override; + ~KSession() override; void Initialize(KClientPort* port_, const std::string& name_); - virtual void Finalize() override; + void Finalize() override; - virtual bool IsInitialized() const override { + bool IsInitialized() const override { return initialized; } - virtual uintptr_t GetPostDestroyArgument() const override { + uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(process); } @@ -78,7 +78,6 @@ private: ServerClosed = 3, }; -private: void SetState(State state) { atomic_state = static_cast<u8>(state); } @@ -87,7 +86,6 @@ private: return static_cast<State>(atomic_state.load(std::memory_order_relaxed)); } -private: KServerSession server; KClientSession client; std::atomic<std::underlying_type_t<State>> atomic_state{ diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h index 553a56327..e9815f90b 100644 --- a/src/core/hle/kernel/k_shared_memory.h +++ b/src/core/hle/kernel/k_shared_memory.h @@ -68,9 +68,9 @@ public: return device_memory->GetPointer(physical_address + offset); } - virtual void Finalize() override; + void Finalize() override; - virtual bool IsInitialized() const override { + bool IsInitialized() const override { return is_initialized; } static void PostDestroy([[maybe_unused]] uintptr_t arg) {} diff --git a/src/core/hle/kernel/k_slab_heap.h b/src/core/hle/kernel/k_slab_heap.h index 81d472a3e..0ad74b0a0 100644 --- a/src/core/hle/kernel/k_slab_heap.h +++ b/src/core/hle/kernel/k_slab_heap.h @@ -4,34 +4,213 @@ #pragma once +#include <atomic> + +#include "common/assert.h" +#include "common/common_types.h" + namespace Kernel { class KernelCore; -/// This is a placeholder class to manage slab heaps for kernel objects. For now, we just allocate -/// these with new/delete, but this can be re-implemented later to allocate these in emulated -/// memory. +namespace impl { + +class KSlabHeapImpl final : NonCopyable { +public: + struct Node { + Node* next{}; + }; + + constexpr KSlabHeapImpl() = default; + + void Initialize(std::size_t size) { + ASSERT(head == nullptr); + obj_size = size; + } + + constexpr std::size_t GetObjectSize() const { + return obj_size; + } + + Node* GetHead() const { + return head; + } + + void* Allocate() { + Node* ret = head.load(); + + do { + if (ret == nullptr) { + break; + } + } while (!head.compare_exchange_weak(ret, ret->next)); + + return ret; + } + + void Free(void* obj) { + Node* node = static_cast<Node*>(obj); + + Node* cur_head = head.load(); + do { + node->next = cur_head; + } while (!head.compare_exchange_weak(cur_head, node)); + } + +private: + std::atomic<Node*> head{}; + std::size_t obj_size{}; +}; + +} // namespace impl + +class KSlabHeapBase : NonCopyable { +public: + constexpr KSlabHeapBase() = default; + + constexpr bool Contains(uintptr_t addr) const { + return start <= addr && addr < end; + } + + constexpr std::size_t GetSlabHeapSize() const { + return (end - start) / GetObjectSize(); + } + + constexpr std::size_t GetObjectSize() const { + return impl.GetObjectSize(); + } + + constexpr uintptr_t GetSlabHeapAddress() const { + return start; + } + + std::size_t GetObjectIndexImpl(const void* obj) const { + return (reinterpret_cast<uintptr_t>(obj) - start) / GetObjectSize(); + } + + std::size_t GetPeakIndex() const { + return GetObjectIndexImpl(reinterpret_cast<const void*>(peak)); + } + + void* AllocateImpl() { + return impl.Allocate(); + } + + void FreeImpl(void* obj) { + // Don't allow freeing an object that wasn't allocated from this heap + ASSERT(Contains(reinterpret_cast<uintptr_t>(obj))); + + impl.Free(obj); + } + + void InitializeImpl(std::size_t obj_size, void* memory, std::size_t memory_size) { + // Ensure we don't initialize a slab using null memory + ASSERT(memory != nullptr); + + // Initialize the base allocator + impl.Initialize(obj_size); + + // Set our tracking variables + const std::size_t num_obj = (memory_size / obj_size); + start = reinterpret_cast<uintptr_t>(memory); + end = start + num_obj * obj_size; + peak = start; + + // Free the objects + u8* cur = reinterpret_cast<u8*>(end); + + for (std::size_t i{}; i < num_obj; i++) { + cur -= obj_size; + impl.Free(cur); + } + } + +private: + using Impl = impl::KSlabHeapImpl; + + Impl impl; + uintptr_t peak{}; + uintptr_t start{}; + uintptr_t end{}; +}; template <typename T> -class KSlabHeap final : NonCopyable { +class KSlabHeap final : public KSlabHeapBase { public: - KSlabHeap() = default; + enum class AllocationType { + Host, + Guest, + }; - void Initialize([[maybe_unused]] void* memory, [[maybe_unused]] std::size_t memory_size) { - // Placeholder that should initialize the backing slab heap implementation. + explicit constexpr KSlabHeap(AllocationType allocation_type_ = AllocationType::Host) + : KSlabHeapBase(), allocation_type{allocation_type_} {} + + void Initialize(void* memory, std::size_t memory_size) { + if (allocation_type == AllocationType::Guest) { + InitializeImpl(sizeof(T), memory, memory_size); + } } T* Allocate() { - return new T(); + switch (allocation_type) { + case AllocationType::Host: + // Fallback for cases where we do not yet support allocating guest memory from the slab + // heap, such as for kernel memory regions. + return new T; + + case AllocationType::Guest: + T* obj = static_cast<T*>(AllocateImpl()); + if (obj != nullptr) { + new (obj) T(); + } + return obj; + } + + UNREACHABLE_MSG("Invalid AllocationType {}", allocation_type); + return nullptr; } T* AllocateWithKernel(KernelCore& kernel) { - return new T(kernel); + switch (allocation_type) { + case AllocationType::Host: + // Fallback for cases where we do not yet support allocating guest memory from the slab + // heap, such as for kernel memory regions. + return new T(kernel); + + case AllocationType::Guest: + T* obj = static_cast<T*>(AllocateImpl()); + if (obj != nullptr) { + new (obj) T(kernel); + } + return obj; + } + + UNREACHABLE_MSG("Invalid AllocationType {}", allocation_type); + return nullptr; } void Free(T* obj) { - delete obj; + switch (allocation_type) { + case AllocationType::Host: + // Fallback for cases where we do not yet support allocating guest memory from the slab + // heap, such as for kernel memory regions. + delete obj; + return; + + case AllocationType::Guest: + FreeImpl(obj); + return; + } + + UNREACHABLE_MSG("Invalid AllocationType {}", allocation_type); } + + constexpr std::size_t GetObjectIndex(const T* obj) const { + return GetObjectIndexImpl(obj); + } + +private: + const AllocationType allocation_type; }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_synchronization_object.h b/src/core/hle/kernel/k_synchronization_object.h index a41dd1220..3d4ce1fbc 100644 --- a/src/core/hle/kernel/k_synchronization_object.h +++ b/src/core/hle/kernel/k_synchronization_object.h @@ -29,7 +29,7 @@ public: KSynchronizationObject** objects, const s32 num_objects, s64 timeout); - virtual void Finalize() override; + void Finalize() override; [[nodiscard]] virtual bool IsSignaled() const = 0; @@ -37,7 +37,7 @@ public: protected: explicit KSynchronizationObject(KernelCore& kernel); - virtual ~KSynchronizationObject(); + ~KSynchronizationObject() override; virtual void OnFinalizeSynchronizationObject() {} diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index e3f08f256..3cf43d290 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -168,13 +168,13 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s std::memset(static_cast<void*>(std::addressof(GetStackParameters())), 0, sizeof(StackParameters)); - // Setup the TLS, if needed. - if (type == ThreadType::User) { - tls_address = owner->CreateTLSRegion(); - } - // Set parent, if relevant. if (owner != nullptr) { + // Setup the TLS, if needed. + if (type == ThreadType::User) { + tls_address = owner->CreateTLSRegion(); + } + parent = owner; parent->Open(); parent->IncrementThreadCount(); diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 4abfc2b49..01eebb165 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -358,21 +358,21 @@ public: return termination_requested || GetRawState() == ThreadState::Terminated; } - [[nodiscard]] virtual u64 GetId() const override final { + [[nodiscard]] u64 GetId() const override { return this->GetThreadID(); } - [[nodiscard]] virtual bool IsInitialized() const override { + [[nodiscard]] bool IsInitialized() const override { return initialized; } - [[nodiscard]] virtual uintptr_t GetPostDestroyArgument() const override { + [[nodiscard]] uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(parent) | (resource_limit_release_hint ? 1 : 0); } - virtual void Finalize() override; + void Finalize() override; - [[nodiscard]] virtual bool IsSignaled() const override; + [[nodiscard]] bool IsSignaled() const override; static void PostDestroy(uintptr_t arg); diff --git a/src/core/hle/kernel/k_transfer_memory.h b/src/core/hle/kernel/k_transfer_memory.h index c2d0f1eaf..31029a5c2 100644 --- a/src/core/hle/kernel/k_transfer_memory.h +++ b/src/core/hle/kernel/k_transfer_memory.h @@ -27,23 +27,23 @@ class KTransferMemory final public: explicit KTransferMemory(KernelCore& kernel_); - virtual ~KTransferMemory() override; + ~KTransferMemory() override; ResultCode Initialize(VAddr address_, std::size_t size_, Svc::MemoryPermission owner_perm_); - virtual void Finalize() override; + void Finalize() override; - virtual bool IsInitialized() const override { + bool IsInitialized() const override { return is_initialized; } - virtual uintptr_t GetPostDestroyArgument() const override { + uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(owner); } static void PostDestroy(uintptr_t arg); - KProcess* GetOwner() const { + KProcess* GetOwner() const override { return owner; } diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h index 607b0eadb..858d982c4 100644 --- a/src/core/hle/kernel/k_writable_event.h +++ b/src/core/hle/kernel/k_writable_event.h @@ -21,7 +21,7 @@ public: explicit KWritableEvent(KernelCore& kernel_); ~KWritableEvent() override; - virtual void Destroy() override; + void Destroy() override; static void PostDestroy([[maybe_unused]] uintptr_t arg) {} diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 8b55df82e..0ffb78d51 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -258,7 +258,7 @@ struct KernelCore::Impl { KAutoObject::Create(thread.get()); ASSERT(KThread::InitializeDummyThread(thread.get()).IsSuccess()); thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); - return std::move(thread); + return thread; }; thread_local auto thread = make_thread(); @@ -620,7 +620,8 @@ struct KernelCore::Impl { void InitializePageSlab() { // Allocate slab heaps - user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>(); + user_slab_heap_pages = + std::make_unique<KSlabHeap<Page>>(KSlabHeap<Page>::AllocationType::Guest); // TODO(ameerj): This should be derived, not hardcoded within the kernel constexpr u64 user_slab_heap_size{0x3de000}; diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index b05a5da04..b1a81810b 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp @@ -273,8 +273,13 @@ void SoftwareKeyboard::ProcessTextCheck() { std::memcpy(&swkbd_text_check, text_check_data.data(), sizeof(SwkbdTextCheck)); - std::u16string text_check_message = Common::UTF16StringFromFixedZeroTerminatedBuffer( - swkbd_text_check.text_check_message.data(), swkbd_text_check.text_check_message.size()); + std::u16string text_check_message = + swkbd_text_check.text_check_result == SwkbdTextCheckResult::Failure || + swkbd_text_check.text_check_result == SwkbdTextCheckResult::Confirm + ? Common::UTF16StringFromFixedZeroTerminatedBuffer( + swkbd_text_check.text_check_message.data(), + swkbd_text_check.text_check_message.size()) + : u""; LOG_INFO(Service_AM, "\nTextCheckResult: {}\nTextCheckMessage: {}", GetTextCheckResultName(swkbd_text_check.text_check_result), @@ -285,10 +290,10 @@ void SoftwareKeyboard::ProcessTextCheck() { SubmitNormalOutputAndExit(SwkbdResult::Ok, current_text); break; case SwkbdTextCheckResult::Failure: - ShowTextCheckDialog(SwkbdTextCheckResult::Failure, text_check_message); + ShowTextCheckDialog(SwkbdTextCheckResult::Failure, std::move(text_check_message)); break; case SwkbdTextCheckResult::Confirm: - ShowTextCheckDialog(SwkbdTextCheckResult::Confirm, text_check_message); + ShowTextCheckDialog(SwkbdTextCheckResult::Confirm, std::move(text_check_message)); break; case SwkbdTextCheckResult::Silent: default: @@ -482,7 +487,7 @@ void SoftwareKeyboard::InitializeFrontendKeyboard() { max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box; Core::Frontend::KeyboardInitializeParameters initialize_parameters{ - .ok_text{ok_text}, + .ok_text{std::move(ok_text)}, .header_text{}, .sub_text{}, .guide_text{}, @@ -558,10 +563,10 @@ void SoftwareKeyboard::InitializeFrontendKeyboard() { : false; Core::Frontend::KeyboardInitializeParameters initialize_parameters{ - .ok_text{ok_text}, - .header_text{header_text}, - .sub_text{sub_text}, - .guide_text{guide_text}, + .ok_text{std::move(ok_text)}, + .header_text{std::move(header_text)}, + .sub_text{std::move(sub_text)}, + .guide_text{std::move(guide_text)}, .initial_text{initial_text}, .max_text_length{max_text_length}, .min_text_length{min_text_length}, @@ -590,7 +595,7 @@ void SoftwareKeyboard::ShowNormalKeyboard() { void SoftwareKeyboard::ShowTextCheckDialog(SwkbdTextCheckResult text_check_result, std::u16string text_check_message) { - frontend.ShowTextCheckDialog(text_check_result, text_check_message); + frontend.ShowTextCheckDialog(text_check_result, std::move(text_check_message)); } void SoftwareKeyboard::ShowInlineKeyboard() { diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index d311f754b..764abb5b6 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp @@ -91,8 +91,7 @@ bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture, // Update if coordinates change for (size_t id = 0; id < MAX_POINTS; id++) { - if (gesture.points[id].x != last_gesture.points[id].x || - gesture.points[id].y != last_gesture.points[id].y) { + if (gesture.points[id] != last_gesture.points[id]) { return true; } } @@ -124,8 +123,7 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size, cur_entry.sampling_number2 = cur_entry.sampling_number; // Reset values to default - cur_entry.delta_x = 0; - cur_entry.delta_y = 0; + cur_entry.delta = {}; cur_entry.vel_x = 0; cur_entry.vel_y = 0; cur_entry.direction = Direction::None; @@ -146,13 +144,9 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size, cur_entry.detection_count = gesture.detection_count; cur_entry.type = type; cur_entry.attributes = attributes; - cur_entry.x = gesture.mid_point.x; - cur_entry.y = gesture.mid_point.y; + cur_entry.pos = gesture.mid_point; cur_entry.point_count = static_cast<s32>(gesture.active_points); - for (size_t id = 0; id < MAX_POINTS; id++) { - cur_entry.points[id].x = gesture.points[id].x; - cur_entry.points[id].y = gesture.points[id].y; - } + cur_entry.points = gesture.points; last_gesture = gesture; std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); @@ -160,8 +154,8 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size, void Controller_Gesture::NewGesture(GestureProperties& gesture, TouchType& type, Attribute& attributes) { - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; + const auto& last_entry = GetLastGestureEntry(); + gesture.detection_count++; type = TouchType::Touch; @@ -174,13 +168,11 @@ void Controller_Gesture::NewGesture(GestureProperties& gesture, TouchType& type, void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, TouchType& type, f32 time_difference) { - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; + const auto& last_entry = GetLastGestureEntry(); // Promote to pan type if touch moved for (size_t id = 0; id < MAX_POINTS; id++) { - if (gesture.points[id].x != last_gesture.points[id].x || - gesture.points[id].y != last_gesture.points[id].y) { + if (gesture.points[id] != last_gesture.points[id]) { type = TouchType::Pan; break; } @@ -192,10 +184,7 @@ void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, Touch enable_press_and_tap = false; gesture.active_points = 0; gesture.mid_point = {}; - for (size_t id = 0; id < MAX_POINTS; id++) { - gesture.points[id].x = 0; - gesture.points[id].y = 0; - } + gesture.points.fill({}); return; } @@ -214,8 +203,8 @@ void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, Touch void Controller_Gesture::EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props, TouchType& type, Attribute& attributes, f32 time_difference) { - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; + const auto& last_entry = GetLastGestureEntry(); + if (last_gesture_props.active_points != 0) { switch (last_entry.type) { case TouchType::Touch: @@ -265,13 +254,11 @@ void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, TouchType& type, f32 time_difference) { auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index]; - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; - cur_entry.delta_x = gesture.mid_point.x - last_entry.x; - cur_entry.delta_y = gesture.mid_point.y - last_entry.y; + const auto& last_entry = GetLastGestureEntry(); - cur_entry.vel_x = static_cast<f32>(cur_entry.delta_x) / time_difference; - cur_entry.vel_y = static_cast<f32>(cur_entry.delta_y) / time_difference; + cur_entry.delta = gesture.mid_point - last_entry.pos; + cur_entry.vel_x = static_cast<f32>(cur_entry.delta.x) / time_difference; + cur_entry.vel_y = static_cast<f32>(cur_entry.delta.y) / time_difference; last_pan_time_difference = time_difference; // Promote to pinch type @@ -295,12 +282,11 @@ void Controller_Gesture::EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, TouchType& type, f32 time_difference) { auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index]; - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; + const auto& last_entry = GetLastGestureEntry(); cur_entry.vel_x = - static_cast<f32>(last_entry.delta_x) / (last_pan_time_difference + time_difference); + static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference); cur_entry.vel_y = - static_cast<f32>(last_entry.delta_y) / (last_pan_time_difference + time_difference); + static_cast<f32>(last_entry.delta.y) / (last_pan_time_difference + time_difference); const f32 curr_vel = std::sqrt((cur_entry.vel_x * cur_entry.vel_x) + (cur_entry.vel_y * cur_entry.vel_y)); @@ -320,22 +306,22 @@ void Controller_Gesture::EndPanEvent(GestureProperties& gesture, void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, TouchType& type) { auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index]; - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; + const auto& last_entry = GetLastGestureEntry(); + type = TouchType::Swipe; gesture = last_gesture_props; force_update = true; - cur_entry.delta_x = last_entry.delta_x; - cur_entry.delta_y = last_entry.delta_y; - if (std::abs(cur_entry.delta_x) > std::abs(cur_entry.delta_y)) { - if (cur_entry.delta_x > 0) { + cur_entry.delta = last_entry.delta; + + if (std::abs(cur_entry.delta.x) > std::abs(cur_entry.delta.y)) { + if (cur_entry.delta.x > 0) { cur_entry.direction = Direction::Right; return; } cur_entry.direction = Direction::Left; return; } - if (cur_entry.delta_y > 0) { + if (cur_entry.delta.y > 0) { cur_entry.direction = Direction::Down; return; } @@ -364,6 +350,14 @@ std::optional<std::size_t> Controller_Gesture::GetUnusedFingerID() const { return std::nullopt; } +Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() { + return shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; +} + +const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const { + return shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; +} + std::size_t Controller_Gesture::UpdateTouchInputEvent( const std::tuple<float, float, bool>& touch_input, std::size_t finger_id) { const auto& [x, y, pressed] = touch_input; @@ -381,8 +375,7 @@ std::size_t Controller_Gesture::UpdateTouchInputEvent( finger_id = first_free_id.value(); fingers[finger_id].pressed = true; } - fingers[finger_id].x = x; - fingers[finger_id].y = y; + fingers[finger_id].pos = {x, y}; return finger_id; } @@ -402,17 +395,18 @@ Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); for (size_t id = 0; id < gesture.active_points; ++id) { - gesture.points[id].x = - static_cast<s32>(active_fingers[id].x * Layout::ScreenUndocked::Width); - gesture.points[id].y = - static_cast<s32>(active_fingers[id].y * Layout::ScreenUndocked::Height); + const auto& [active_x, active_y] = active_fingers[id].pos; + gesture.points[id] = { + .x = static_cast<s32>(active_x * Layout::ScreenUndocked::Width), + .y = static_cast<s32>(active_y * Layout::ScreenUndocked::Height), + }; // Hack: There is no touch in docked but games still allow it if (Settings::values.use_docked_mode.GetValue()) { - gesture.points[id].x = - static_cast<s32>(active_fingers[id].x * Layout::ScreenDocked::Width); - gesture.points[id].y = - static_cast<s32>(active_fingers[id].y * Layout::ScreenDocked::Height); + gesture.points[id] = { + .x = static_cast<s32>(active_x * Layout::ScreenDocked::Width), + .y = static_cast<s32>(active_y * Layout::ScreenDocked::Height), + }; } gesture.mid_point.x += static_cast<s32>(gesture.points[id].x / gesture.active_points); diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h index f46e29411..7e7ae6625 100644 --- a/src/core/hle/service/hid/controllers/gesture.h +++ b/src/core/hle/service/hid/controllers/gesture.h @@ -7,6 +7,7 @@ #include <array> #include "common/bit_field.h" #include "common/common_types.h" +#include "common/point.h" #include "core/frontend/input.h" #include "core/hle/service/hid/controllers/controller_base.h" @@ -63,29 +64,21 @@ private: }; static_assert(sizeof(Attribute) == 4, "Attribute is an invalid size"); - struct Points { - s32_le x; - s32_le y; - }; - static_assert(sizeof(Points) == 8, "Points is an invalid size"); - struct GestureState { s64_le sampling_number; s64_le sampling_number2; s64_le detection_count; TouchType type; Direction direction; - s32_le x; - s32_le y; - s32_le delta_x; - s32_le delta_y; + Common::Point<s32_le> pos; + Common::Point<s32_le> delta; f32 vel_x; f32 vel_y; Attribute attributes; f32 scale; f32 rotation_angle; s32_le point_count; - std::array<Points, 4> points; + std::array<Common::Point<s32_le>, 4> points; }; static_assert(sizeof(GestureState) == 0x68, "GestureState is an invalid size"); @@ -96,15 +89,14 @@ private: static_assert(sizeof(SharedMemory) == 0x708, "SharedMemory is an invalid size"); struct Finger { - f32 x{}; - f32 y{}; + Common::Point<f32> pos{}; bool pressed{}; }; struct GestureProperties { - std::array<Points, MAX_POINTS> points{}; + std::array<Common::Point<s32_le>, MAX_POINTS> points{}; std::size_t active_points{}; - Points mid_point{}; + Common::Point<s32_le> mid_point{}; s64_le detection_count{}; u64_le delta_time{}; f32 average_distance{}; @@ -148,7 +140,11 @@ private: TouchType& type); // Returns an unused finger id, if there is no fingers available std::nullopt is returned. - std::optional<size_t> GetUnusedFingerID() const; + [[nodiscard]] std::optional<size_t> GetUnusedFingerID() const; + + // Retrieves the last gesture entry, as indicated by shared memory indices. + [[nodiscard]] GestureState& GetLastGestureEntry(); + [[nodiscard]] const GestureState& GetLastGestureEntry() const; /** * If the touch is new it tries to assign a new finger id, if there is no fingers available no @@ -166,10 +162,10 @@ private: std::unique_ptr<Input::TouchDevice> touch_mouse_device; std::unique_ptr<Input::TouchDevice> touch_udp_device; std::unique_ptr<Input::TouchDevice> touch_btn_device; - std::array<size_t, MAX_FINGERS> mouse_finger_id; - std::array<size_t, MAX_FINGERS> keyboard_finger_id; - std::array<size_t, MAX_FINGERS> udp_finger_id; - std::array<Finger, MAX_POINTS> fingers; + std::array<size_t, MAX_FINGERS> mouse_finger_id{}; + std::array<size_t, MAX_FINGERS> keyboard_finger_id{}; + std::array<size_t, MAX_FINGERS> udp_finger_id{}; + std::array<Finger, MAX_POINTS> fingers{}; GestureProperties last_gesture{}; s64_le last_update_timestamp{}; s64_le last_tap_timestamp{}; diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index ac9112c40..6ef17acc5 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp @@ -74,8 +74,11 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin for (std::size_t id = 0; id < MAX_FINGERS; ++id) { auto& touch_entry = cur_entry.states[id]; if (id < active_fingers_count) { - touch_entry.x = static_cast<u16>(active_fingers[id].x * Layout::ScreenUndocked::Width); - touch_entry.y = static_cast<u16>(active_fingers[id].y * Layout::ScreenUndocked::Height); + const auto& [active_x, active_y] = active_fingers[id].position; + touch_entry.position = { + .x = static_cast<u16>(active_x * Layout::ScreenUndocked::Width), + .y = static_cast<u16>(active_y * Layout::ScreenUndocked::Height), + }; touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; @@ -86,8 +89,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin } else { // Clear touch entry touch_entry.attribute.raw = 0; - touch_entry.x = 0; - touch_entry.y = 0; + touch_entry.position = {}; touch_entry.diameter_x = 0; touch_entry.diameter_y = 0; touch_entry.rotation_angle = 0; @@ -140,8 +142,7 @@ std::size_t Controller_Touchscreen::UpdateTouchInputEvent( fingers[finger_id].id = static_cast<u32_le>(finger_id); attribute.start_touch.Assign(1); } - fingers[finger_id].x = x; - fingers[finger_id].y = y; + fingers[finger_id].position = {x, y}; fingers[finger_id].attribute = attribute; return finger_id; } diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index 2869d0cfd..ef2becefd 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h @@ -7,6 +7,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/point.h" #include "common/swap.h" #include "core/frontend/input.h" #include "core/hle/service/hid/controllers/controller_base.h" @@ -55,8 +56,7 @@ private: u64_le delta_time; Attributes attribute; u32_le finger; - u32_le x; - u32_le y; + Common::Point<u32_le> position; u32_le diameter_x; u32_le diameter_y; u32_le rotation_angle; @@ -81,8 +81,7 @@ private: struct Finger { u64_le last_touch{}; - float x{}; - float y{}; + Common::Point<float> position; u32_le id{}; bool pressed{}; Attributes attribute; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 49c17fd14..df0fe1c8e 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -1770,7 +1770,7 @@ public: {232, nullptr, "GetIrSensorState"}, {233, nullptr, "GetXcdHandleForNpadWithIrSensor"}, {301, nullptr, "ActivateNpadSystem"}, - {303, nullptr, "ApplyNpadSystemCommonPolicy"}, + {303, &HidSys::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"}, {304, nullptr, "EnableAssigningSingleOnSlSrPress"}, {305, nullptr, "DisableAssigningSingleOnSlSrPress"}, {306, nullptr, "GetLastActiveNpad"}, @@ -1949,6 +1949,15 @@ public: RegisterHandlers(functions); } + +private: + void ApplyNpadSystemCommonPolicy(Kernel::HLERequestContext& ctx) { + // We already do this for homebrew so we can just stub it out + LOG_WARNING(Service_HID, "called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } }; class HidTmp final : public ServiceFramework<HidTmp> { diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index d160ffe87..c709a8028 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp @@ -215,10 +215,151 @@ public: } }; +class INetworkService final : public ServiceFramework<INetworkService> { +public: + explicit INetworkService(Core::System& system_) : ServiceFramework{system_, "INetworkService"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, + {264, nullptr, "GetNetworkInterfaceLastError"}, + {272, nullptr, "GetRole"}, + {280, nullptr, "GetAdvertiseData"}, + {288, nullptr, "GetGroupInfo"}, + {296, nullptr, "GetGroupInfo2"}, + {304, nullptr, "GetGroupOwner"}, + {312, nullptr, "GetIpConfig"}, + {320, nullptr, "GetLinkLevel"}, + {512, nullptr, "Scan"}, + {768, nullptr, "CreateGroup"}, + {776, nullptr, "DestroyGroup"}, + {784, nullptr, "SetAdvertiseData"}, + {1536, nullptr, "SendToOtherGroup"}, + {1544, nullptr, "RecvFromOtherGroup"}, + {1552, nullptr, "AddAcceptableGroupId"}, + {1560, nullptr, "ClearAcceptableGroupId"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class INetworkServiceMonitor final : public ServiceFramework<INetworkServiceMonitor> { +public: + explicit INetworkServiceMonitor(Core::System& system_) + : ServiceFramework{system_, "INetworkServiceMonitor"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &INetworkServiceMonitor::Initialize, "Initialize"}, + {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, + {264, nullptr, "GetNetworkInterfaceLastError"}, + {272, nullptr, "GetRole"}, + {280, nullptr, "GetAdvertiseData"}, + {281, nullptr, "GetAdvertiseData2"}, + {288, nullptr, "GetGroupInfo"}, + {296, nullptr, "GetGroupInfo2"}, + {304, nullptr, "GetGroupOwner"}, + {312, nullptr, "GetIpConfig"}, + {320, nullptr, "GetLinkLevel"}, + {328, nullptr, "AttachJoinEvent"}, + {336, nullptr, "GetMembers"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + + void Initialize(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERROR_DISABLED); + } +}; + +class LP2PAPP final : public ServiceFramework<LP2PAPP> { +public: + explicit LP2PAPP(Core::System& system_) : ServiceFramework{system_, "lp2p:app"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &LP2PAPP::CreateMonitorService, "CreateNetworkService"}, + {8, &LP2PAPP::CreateMonitorService, "CreateNetworkServiceMonitor"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + + void CreateNetworkervice(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u64 reserved_input = rp.Pop<u64>(); + const u32 input = rp.Pop<u32>(); + + LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input, + input); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<INetworkService>(system); + } + + void CreateMonitorService(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u64 reserved_input = rp.Pop<u64>(); + + LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<INetworkServiceMonitor>(system); + } +}; + +class LP2PSYS final : public ServiceFramework<LP2PSYS> { +public: + explicit LP2PSYS(Core::System& system_) : ServiceFramework{system_, "lp2p:sys"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &LP2PSYS::CreateMonitorService, "CreateNetworkService"}, + {8, &LP2PSYS::CreateMonitorService, "CreateNetworkServiceMonitor"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + + void CreateNetworkervice(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u64 reserved_input = rp.Pop<u64>(); + const u32 input = rp.Pop<u32>(); + + LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input, + input); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<INetworkService>(system); + } + + void CreateMonitorService(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u64 reserved_input = rp.Pop<u64>(); + + LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<INetworkServiceMonitor>(system); + } +}; + void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { std::make_shared<LDNM>(system)->InstallAsService(sm); std::make_shared<LDNS>(system)->InstallAsService(sm); std::make_shared<LDNU>(system)->InstallAsService(sm); + std::make_shared<LP2PAPP>(system)->InstallAsService(sm); + std::make_shared<LP2PSYS>(system)->InstallAsService(sm); } } // namespace Service::LDN |