From a7e9d7842dc78e09bfe50ba3bc471b8a75d29b96 Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 2 Jan 2024 19:22:02 -0500 Subject: am: add new datatypes for per-applet state --- src/core/hle/service/am/library_applet_storage.cpp | 140 +++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 src/core/hle/service/am/library_applet_storage.cpp (limited to 'src/core/hle/service/am/library_applet_storage.cpp') diff --git a/src/core/hle/service/am/library_applet_storage.cpp b/src/core/hle/service/am/library_applet_storage.cpp new file mode 100644 index 000000000..46e6c0111 --- /dev/null +++ b/src/core/hle/service/am/library_applet_storage.cpp @@ -0,0 +1,140 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/kernel/k_transfer_memory.h" +#include "core/hle/service/am/am_results.h" +#include "core/hle/service/am/library_applet_storage.h" +#include "core/memory.h" + +namespace Service::AM { + +namespace { + +Result ValidateOffset(s64 offset, size_t size, size_t data_size) { + R_UNLESS(offset >= 0, AM::ResultInvalidOffset); + + const size_t begin = offset; + const size_t end = begin + size; + + R_UNLESS(begin <= end && end <= data_size, AM::ResultInvalidOffset); + R_SUCCEED(); +} + +class BufferLibraryAppletStorage final : public LibraryAppletStorage { +public: + explicit BufferLibraryAppletStorage(std::vector&& data) : m_data(std::move(data)) {} + ~BufferLibraryAppletStorage() = default; + + Result Read(s64 offset, void* buffer, size_t size) override { + R_TRY(ValidateOffset(offset, size, m_data.size())); + + std::memcpy(buffer, m_data.data() + offset, size); + + R_SUCCEED(); + } + + Result Write(s64 offset, const void* buffer, size_t size) override { + R_TRY(ValidateOffset(offset, size, m_data.size())); + + std::memcpy(m_data.data() + offset, buffer, size); + + R_SUCCEED(); + } + + s64 GetSize() override { + return m_data.size(); + } + + Kernel::KTransferMemory* GetHandle() override { + return nullptr; + } + +private: + std::vector m_data; +}; + +class TransferMemoryLibraryAppletStorage : public LibraryAppletStorage { +public: + explicit TransferMemoryLibraryAppletStorage(Core::Memory::Memory& memory, + Kernel::KTransferMemory* trmem, bool is_writable, + s64 size) + : m_memory(memory), m_trmem(trmem), m_is_writable(is_writable), m_size(size) { + m_trmem->Open(); + } + + ~TransferMemoryLibraryAppletStorage() { + m_trmem->Close(); + m_trmem = nullptr; + } + + Result Read(s64 offset, void* buffer, size_t size) override { + R_TRY(ValidateOffset(offset, size, m_size)); + + m_memory.ReadBlock(m_trmem->GetSourceAddress(), buffer, size); + + R_SUCCEED(); + } + + Result Write(s64 offset, const void* buffer, size_t size) override { + R_UNLESS(m_is_writable, ResultUnknown); + R_TRY(ValidateOffset(offset, size, m_size)); + + m_memory.WriteBlock(m_trmem->GetSourceAddress(), buffer, size); + + R_SUCCEED(); + } + + s64 GetSize() override { + return m_size; + } + + Kernel::KTransferMemory* GetHandle() override { + return nullptr; + } + +protected: + Core::Memory::Memory& m_memory; + Kernel::KTransferMemory* m_trmem; + bool m_is_writable; + s64 m_size; +}; + +class HandleLibraryAppletStorage : public TransferMemoryLibraryAppletStorage { +public: + explicit HandleLibraryAppletStorage(Core::Memory::Memory& memory, + Kernel::KTransferMemory* trmem, s64 size) + : TransferMemoryLibraryAppletStorage(memory, trmem, true, size) {} + ~HandleLibraryAppletStorage() = default; + + Kernel::KTransferMemory* GetHandle() override { + return m_trmem; + } +}; + +} // namespace + +LibraryAppletStorage::~LibraryAppletStorage() = default; + +std::vector LibraryAppletStorage::GetData() { + std::vector data(this->GetSize()); + this->Read(0, data.data(), data.size()); + return data; +} + +std::shared_ptr CreateStorage(std::vector&& data) { + return std::make_shared(std::move(data)); +} + +std::shared_ptr CreateTransferMemoryStorage(Core::Memory::Memory& memory, + Kernel::KTransferMemory* trmem, + bool is_writable, s64 size) { + return std::make_shared(memory, trmem, is_writable, size); +} + +std::shared_ptr CreateHandleStorage(Core::Memory::Memory& memory, + Kernel::KTransferMemory* trmem, + s64 size) { + return std::make_shared(memory, trmem, size); +} + +} // namespace Service::AM -- cgit v1.2.3