summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Liam2024-01-01 21:58:56 -0500
committerGravatar Liam2024-01-29 20:17:33 -0500
commitb1c2f791af08b3eaba53c1ce1673fe0729fc5d26 (patch)
tree69300381618872113496f62494e8c3e0353538d9 /src
parentam: migrate global state to per-applet state structure (diff)
downloadyuzu-b1c2f791af08b3eaba53c1ce1673fe0729fc5d26.tar.gz
yuzu-b1c2f791af08b3eaba53c1ce1673fe0729fc5d26.tar.xz
yuzu-b1c2f791af08b3eaba53c1ce1673fe0729fc5d26.zip
am: rework IStorage for transfer storage
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/am_results.h1
-rw-r--r--src/core/hle/service/am/library_applet_creator.cpp28
-rw-r--r--src/core/hle/service/am/storage.cpp71
-rw-r--r--src/core/hle/service/am/storage.h25
-rw-r--r--src/core/hle/service/am/storage_accessor.cpp84
-rw-r--r--src/core/hle/service/am/storage_accessor.h17
6 files changed, 117 insertions, 109 deletions
diff --git a/src/core/hle/service/am/am_results.h b/src/core/hle/service/am/am_results.h
index e82d391ad..a2afc9eec 100644
--- a/src/core/hle/service/am/am_results.h
+++ b/src/core/hle/service/am/am_results.h
@@ -10,6 +10,7 @@ namespace Service::AM {
10constexpr Result ResultNoDataInChannel{ErrorModule::AM, 2}; 10constexpr Result ResultNoDataInChannel{ErrorModule::AM, 2};
11constexpr Result ResultNoMessages{ErrorModule::AM, 3}; 11constexpr Result ResultNoMessages{ErrorModule::AM, 3};
12constexpr Result ResultInvalidOffset{ErrorModule::AM, 503}; 12constexpr Result ResultInvalidOffset{ErrorModule::AM, 503};
13constexpr Result ResultInvalidStorageType{ErrorModule::AM, 511};
13constexpr Result ResultFatalSectionCountImbalance{ErrorModule::AM, 512}; 14constexpr Result ResultFatalSectionCountImbalance{ErrorModule::AM, 512};
14 15
15} // namespace Service::AM 16} // namespace Service::AM
diff --git a/src/core/hle/service/am/library_applet_creator.cpp b/src/core/hle/service/am/library_applet_creator.cpp
index e4332e244..888b8b44b 100644
--- a/src/core/hle/service/am/library_applet_creator.cpp
+++ b/src/core/hle/service/am/library_applet_creator.cpp
@@ -6,6 +6,7 @@
6#include "core/hle/service/am/frontend/applets.h" 6#include "core/hle/service/am/frontend/applets.h"
7#include "core/hle/service/am/library_applet_accessor.h" 7#include "core/hle/service/am/library_applet_accessor.h"
8#include "core/hle/service/am/library_applet_creator.h" 8#include "core/hle/service/am/library_applet_creator.h"
9#include "core/hle/service/am/library_applet_storage.h"
9#include "core/hle/service/am/storage.h" 10#include "core/hle/service/am/storage.h"
10#include "core/hle/service/ipc_helpers.h" 11#include "core/hle/service/ipc_helpers.h"
11#include "core/hle/service/sm/sm.h" 12#include "core/hle/service/sm/sm.h"
@@ -164,28 +165,28 @@ void ILibraryAppletCreator::CreateStorage(HLERequestContext& ctx) {
164 return; 165 return;
165 } 166 }
166 167
167 std::vector<u8> buffer(size); 168 std::vector<u8> data(size);
168 169
169 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 170 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
170 rb.Push(ResultSuccess); 171 rb.Push(ResultSuccess);
171 rb.PushIpcInterface<IStorage>(system, std::move(buffer)); 172 rb.PushIpcInterface<IStorage>(system, AM::CreateStorage(std::move(data)));
172} 173}
173 174
174void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx) { 175void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx) {
175 IPC::RequestParser rp{ctx}; 176 IPC::RequestParser rp{ctx};
176 177
177 struct Parameters { 178 struct Parameters {
178 u8 permissions; 179 bool is_writable;
179 s64 size; 180 s64 size;
180 }; 181 };
181 182
182 const auto parameters{rp.PopRaw<Parameters>()}; 183 const auto params{rp.PopRaw<Parameters>()};
183 const auto handle{ctx.GetCopyHandle(0)}; 184 const auto handle{ctx.GetCopyHandle(0)};
184 185
185 LOG_DEBUG(Service_AM, "called, permissions={}, size={}, handle={:08X}", parameters.permissions, 186 LOG_DEBUG(Service_AM, "called, is_writable={}, size={}, handle={:08X}", params.is_writable,
186 parameters.size, handle); 187 params.size, handle);
187 188
188 if (parameters.size <= 0) { 189 if (params.size <= 0) {
189 LOG_ERROR(Service_AM, "size is less than or equal to 0"); 190 LOG_ERROR(Service_AM, "size is less than or equal to 0");
190 IPC::ResponseBuilder rb{ctx, 2}; 191 IPC::ResponseBuilder rb{ctx, 2};
191 rb.Push(ResultUnknown); 192 rb.Push(ResultUnknown);
@@ -201,12 +202,11 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx)
201 return; 202 return;
202 } 203 }
203 204
204 std::vector<u8> memory(transfer_mem->GetSize());
205 ctx.GetMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size());
206
207 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 205 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
208 rb.Push(ResultSuccess); 206 rb.Push(ResultSuccess);
209 rb.PushIpcInterface<IStorage>(system, std::move(memory)); 207 rb.PushIpcInterface<IStorage>(
208 system, AM::CreateTransferMemoryStorage(ctx.GetMemory(), transfer_mem.GetPointerUnsafe(),
209 params.is_writable, params.size));
210} 210}
211 211
212void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) { 212void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) {
@@ -233,12 +233,10 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) {
233 return; 233 return;
234 } 234 }
235 235
236 std::vector<u8> memory(transfer_mem->GetSize());
237 ctx.GetMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size());
238
239 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 236 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
240 rb.Push(ResultSuccess); 237 rb.Push(ResultSuccess);
241 rb.PushIpcInterface<IStorage>(system, std::move(memory)); 238 rb.PushIpcInterface<IStorage>(
239 system, AM::CreateHandleStorage(ctx.GetMemory(), transfer_mem.GetPointerUnsafe(), size));
242} 240}
243 241
244} // namespace Service::AM 242} // namespace Service::AM
diff --git a/src/core/hle/service/am/storage.cpp b/src/core/hle/service/am/storage.cpp
index 9a86c867a..4e82afd1c 100644
--- a/src/core/hle/service/am/storage.cpp
+++ b/src/core/hle/service/am/storage.cpp
@@ -1,60 +1,59 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/am/am_results.h"
5#include "core/hle/service/am/library_applet_storage.h"
4#include "core/hle/service/am/storage.h" 6#include "core/hle/service/am/storage.h"
5#include "core/hle/service/am/storage_accessor.h" 7#include "core/hle/service/am/storage_accessor.h"
6#include "core/hle/service/ipc_helpers.h" 8#include "core/hle/service/ipc_helpers.h"
7 9
8namespace Service::AM { 10namespace Service::AM {
9 11
10IStorageImpl::~IStorageImpl() = default; 12IStorage::IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl_)
11 13 : ServiceFramework{system_, "IStorage"}, impl{std::move(impl_)} {
12class StorageDataImpl final : public IStorageImpl { 14 static const FunctionInfo functions[] = {
13public: 15 {0, &IStorage::Open, "Open"},
14 explicit StorageDataImpl(std::vector<u8>&& buffer_) : buffer{std::move(buffer_)} {} 16 {1, &IStorage::OpenTransferStorage, "OpenTransferStorage"},
15 17 };
16 std::vector<u8>& GetData() override {
17 return buffer;
18 }
19
20 const std::vector<u8>& GetData() const override {
21 return buffer;
22 }
23
24 std::size_t GetSize() const override {
25 return buffer.size();
26 }
27
28private:
29 std::vector<u8> buffer;
30};
31
32IStorage::IStorage(Core::System& system_, std::vector<u8>&& buffer)
33 : ServiceFramework{system_, "IStorage"},
34 impl{std::make_shared<StorageDataImpl>(std::move(buffer))} {
35 Register();
36}
37
38void IStorage::Register() {
39 // clang-format off
40 static const FunctionInfo functions[] = {
41 {0, &IStorage::Open, "Open"},
42 {1, nullptr, "OpenTransferStorage"},
43 };
44 // clang-format on
45 18
46 RegisterHandlers(functions); 19 RegisterHandlers(functions);
47} 20}
48 21
22IStorage::IStorage(Core::System& system_, std::vector<u8>&& data)
23 : IStorage(system_, CreateStorage(std::move(data))) {}
24
49IStorage::~IStorage() = default; 25IStorage::~IStorage() = default;
50 26
51void IStorage::Open(HLERequestContext& ctx) { 27void IStorage::Open(HLERequestContext& ctx) {
52 LOG_DEBUG(Service_AM, "called"); 28 LOG_DEBUG(Service_AM, "called");
53 29
30 if (impl->GetHandle() != nullptr) {
31 IPC::ResponseBuilder rb{ctx, 2};
32 rb.Push(AM::ResultInvalidStorageType);
33 return;
34 }
35
54 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 36 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
37 rb.Push(ResultSuccess);
38 rb.PushIpcInterface<IStorageAccessor>(system, impl);
39}
40
41void IStorage::OpenTransferStorage(HLERequestContext& ctx) {
42 LOG_DEBUG(Service_AM, "called");
55 43
44 if (impl->GetHandle() == nullptr) {
45 IPC::ResponseBuilder rb{ctx, 2};
46 rb.Push(AM::ResultInvalidStorageType);
47 return;
48 }
49
50 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
56 rb.Push(ResultSuccess); 51 rb.Push(ResultSuccess);
57 rb.PushIpcInterface<IStorageAccessor>(system, *this); 52 rb.PushIpcInterface<ITransferStorageAccessor>(system, impl);
53}
54
55std::vector<u8> IStorage::GetData() const {
56 return impl->GetData();
58} 57}
59 58
60} // namespace Service::AM 59} // namespace Service::AM
diff --git a/src/core/hle/service/am/storage.h b/src/core/hle/service/am/storage.h
index d47a8d89f..10d00b141 100644
--- a/src/core/hle/service/am/storage.h
+++ b/src/core/hle/service/am/storage.h
@@ -7,36 +7,25 @@
7 7
8namespace Service::AM { 8namespace Service::AM {
9 9
10class IStorageImpl { 10class LibraryAppletStorage;
11public:
12 virtual ~IStorageImpl();
13 virtual std::vector<u8>& GetData() = 0;
14 virtual const std::vector<u8>& GetData() const = 0;
15 virtual std::size_t GetSize() const = 0;
16};
17 11
18class IStorage final : public ServiceFramework<IStorage> { 12class IStorage final : public ServiceFramework<IStorage> {
19public: 13public:
14 explicit IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl_);
20 explicit IStorage(Core::System& system_, std::vector<u8>&& buffer); 15 explicit IStorage(Core::System& system_, std::vector<u8>&& buffer);
21 ~IStorage() override; 16 ~IStorage() override;
22 17
23 std::vector<u8>& GetData() { 18 std::shared_ptr<LibraryAppletStorage> GetImpl() const {
24 return impl->GetData(); 19 return impl;
25 } 20 }
26 21
27 const std::vector<u8>& GetData() const { 22 std::vector<u8> GetData() const;
28 return impl->GetData();
29 }
30
31 std::size_t GetSize() const {
32 return impl->GetSize();
33 }
34 23
35private: 24private:
36 void Register();
37 void Open(HLERequestContext& ctx); 25 void Open(HLERequestContext& ctx);
26 void OpenTransferStorage(HLERequestContext& ctx);
38 27
39 std::shared_ptr<IStorageImpl> impl; 28 const std::shared_ptr<LibraryAppletStorage> impl;
40}; 29};
41 30
42} // namespace Service::AM 31} // namespace Service::AM
diff --git a/src/core/hle/service/am/storage_accessor.cpp b/src/core/hle/service/am/storage_accessor.cpp
index 7d8c82de3..a1184b065 100644
--- a/src/core/hle/service/am/storage_accessor.cpp
+++ b/src/core/hle/service/am/storage_accessor.cpp
@@ -1,21 +1,22 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/k_transfer_memory.h"
4#include "core/hle/service/am/am_results.h" 5#include "core/hle/service/am/am_results.h"
6#include "core/hle/service/am/library_applet_storage.h"
5#include "core/hle/service/am/storage_accessor.h" 7#include "core/hle/service/am/storage_accessor.h"
6#include "core/hle/service/ipc_helpers.h" 8#include "core/hle/service/ipc_helpers.h"
7 9
8namespace Service::AM { 10namespace Service::AM {
9 11
10IStorageAccessor::IStorageAccessor(Core::System& system_, IStorage& backing_) 12IStorageAccessor::IStorageAccessor(Core::System& system_,
11 : ServiceFramework{system_, "IStorageAccessor"}, backing{backing_} { 13 std::shared_ptr<LibraryAppletStorage> impl_)
12 // clang-format off 14 : ServiceFramework{system_, "IStorageAccessor"}, impl{std::move(impl_)} {
13 static const FunctionInfo functions[] = { 15 static const FunctionInfo functions[] = {
14 {0, &IStorageAccessor::GetSize, "GetSize"}, 16 {0, &IStorageAccessor::GetSize, "GetSize"},
15 {10, &IStorageAccessor::Write, "Write"}, 17 {10, &IStorageAccessor::Write, "Write"},
16 {11, &IStorageAccessor::Read, "Read"}, 18 {11, &IStorageAccessor::Read, "Read"},
17 }; 19 };
18 // clang-format on
19 20
20 RegisterHandlers(functions); 21 RegisterHandlers(functions);
21} 22}
@@ -28,55 +29,62 @@ void IStorageAccessor::GetSize(HLERequestContext& ctx) {
28 IPC::ResponseBuilder rb{ctx, 4}; 29 IPC::ResponseBuilder rb{ctx, 4};
29 30
30 rb.Push(ResultSuccess); 31 rb.Push(ResultSuccess);
31 rb.Push(static_cast<u64>(backing.GetSize())); 32 rb.Push(impl->GetSize());
32} 33}
33 34
34void IStorageAccessor::Write(HLERequestContext& ctx) { 35void IStorageAccessor::Write(HLERequestContext& ctx) {
35 IPC::RequestParser rp{ctx}; 36 IPC::RequestParser rp{ctx};
36 37
37 const u64 offset{rp.Pop<u64>()}; 38 const s64 offset{rp.Pop<s64>()};
38 const auto data{ctx.ReadBuffer()}; 39 const auto data{ctx.ReadBuffer()};
39 const std::size_t size{std::min<u64>(data.size(), backing.GetSize() - offset)}; 40 LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, data.size());
40 41
41 LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, size); 42 const auto res{impl->Write(offset, data.data(), data.size())};
42
43 if (offset > backing.GetSize()) {
44 LOG_ERROR(Service_AM,
45 "offset is out of bounds, backing_buffer_sz={}, data_size={}, offset={}",
46 backing.GetSize(), size, offset);
47
48 IPC::ResponseBuilder rb{ctx, 2};
49 rb.Push(AM::ResultInvalidOffset);
50 return;
51 }
52
53 std::memcpy(backing.GetData().data() + offset, data.data(), size);
54 43
55 IPC::ResponseBuilder rb{ctx, 2}; 44 IPC::ResponseBuilder rb{ctx, 2};
56 rb.Push(ResultSuccess); 45 rb.Push(res);
57} 46}
58 47
59void IStorageAccessor::Read(HLERequestContext& ctx) { 48void IStorageAccessor::Read(HLERequestContext& ctx) {
60 IPC::RequestParser rp{ctx}; 49 IPC::RequestParser rp{ctx};
61 50
62 const u64 offset{rp.Pop<u64>()}; 51 const s64 offset{rp.Pop<s64>()};
63 const std::size_t size{std::min<u64>(ctx.GetWriteBufferSize(), backing.GetSize() - offset)}; 52 std::vector<u8> data(ctx.GetWriteBufferSize());
64 53
65 LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, size); 54 LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, data.size());
66 55
67 if (offset > backing.GetSize()) { 56 const auto res{impl->Read(offset, data.data(), data.size())};
68 LOG_ERROR(Service_AM, "offset is out of bounds, backing_buffer_sz={}, size={}, offset={}",
69 backing.GetSize(), size, offset);
70 57
71 IPC::ResponseBuilder rb{ctx, 2}; 58 ctx.WriteBuffer(data);
72 rb.Push(AM::ResultInvalidOffset);
73 return;
74 }
75
76 ctx.WriteBuffer(backing.GetData().data() + offset, size);
77 59
78 IPC::ResponseBuilder rb{ctx, 2}; 60 IPC::ResponseBuilder rb{ctx, 2};
61 rb.Push(res);
62}
63
64ITransferStorageAccessor::ITransferStorageAccessor(Core::System& system_,
65 std::shared_ptr<LibraryAppletStorage> impl_)
66 : ServiceFramework{system_, "ITransferStorageAccessor"}, impl{std::move(impl_)} {
67 static const FunctionInfo functions[] = {
68 {0, &ITransferStorageAccessor::GetSize, "GetSize"},
69 {1, &ITransferStorageAccessor::GetHandle, "GetHandle"},
70 };
71
72 RegisterHandlers(functions);
73}
74
75ITransferStorageAccessor::~ITransferStorageAccessor() = default;
76
77void ITransferStorageAccessor::GetSize(HLERequestContext& ctx) {
78 IPC::ResponseBuilder rb{ctx, 4};
79 rb.Push(ResultSuccess);
80 rb.Push(impl->GetSize());
81}
82
83void ITransferStorageAccessor::GetHandle(HLERequestContext& ctx) {
84 IPC::ResponseBuilder rb{ctx, 4, 1};
79 rb.Push(ResultSuccess); 85 rb.Push(ResultSuccess);
86 rb.Push(impl->GetSize());
87 rb.PushCopyObjects(impl->GetHandle());
80} 88}
81 89
82} // namespace Service::AM 90} // namespace Service::AM
diff --git a/src/core/hle/service/am/storage_accessor.h b/src/core/hle/service/am/storage_accessor.h
index 8648bfc13..b9aa85a66 100644
--- a/src/core/hle/service/am/storage_accessor.h
+++ b/src/core/hle/service/am/storage_accessor.h
@@ -10,7 +10,7 @@ namespace Service::AM {
10 10
11class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { 11class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
12public: 12public:
13 explicit IStorageAccessor(Core::System& system_, IStorage& backing_); 13 explicit IStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl_);
14 ~IStorageAccessor() override; 14 ~IStorageAccessor() override;
15 15
16private: 16private:
@@ -18,7 +18,20 @@ private:
18 void Write(HLERequestContext& ctx); 18 void Write(HLERequestContext& ctx);
19 void Read(HLERequestContext& ctx); 19 void Read(HLERequestContext& ctx);
20 20
21 IStorage& backing; 21 const std::shared_ptr<LibraryAppletStorage> impl;
22};
23
24class ITransferStorageAccessor final : public ServiceFramework<ITransferStorageAccessor> {
25public:
26 explicit ITransferStorageAccessor(Core::System& system_,
27 std::shared_ptr<LibraryAppletStorage> impl_);
28 ~ITransferStorageAccessor() override;
29
30private:
31 void GetSize(HLERequestContext& ctx);
32 void GetHandle(HLERequestContext& ctx);
33
34 const std::shared_ptr<LibraryAppletStorage> impl;
22}; 35};
23 36
24} // namespace Service::AM 37} // namespace Service::AM