summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-01-20 21:32:36 -0500
committerGravatar bunnei2018-01-21 15:51:43 -0500
commit8e50d6002bd12dde7e4ba4fd3da1b53864c4058c (patch)
treebe6d0f47d8418a61a8e6f86ce0dcdbecf801bebd /src
parentdeconstructed_rom_directory: Implement istorage loading for RomFS. (diff)
downloadyuzu-8e50d6002bd12dde7e4ba4fd3da1b53864c4058c.tar.gz
yuzu-8e50d6002bd12dde7e4ba4fd3da1b53864c4058c.tar.xz
yuzu-8e50d6002bd12dde7e4ba4fd3da1b53864c4058c.zip
fsp_srv: Various improvements to IStorage:Read implementation.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/ipc_helpers.h5
-rw-r--r--src/core/hle/result.h2
-rw-r--r--src/core/hle/service/filesystem/filesystem.h15
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp92
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.h13
5 files changed, 79 insertions, 48 deletions
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index 4c9b0de28..a27cfbc2d 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -305,6 +305,11 @@ inline u64 RequestParser::Pop() {
305} 305}
306 306
307template <> 307template <>
308inline s64 RequestParser::Pop() {
309 return static_cast<s64>(Pop<u64>());
310}
311
312template <>
308inline bool RequestParser::Pop() { 313inline bool RequestParser::Pop() {
309 return Pop<u8>() != 0; 314 return Pop<u8>() != 0;
310} 315}
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index 10ddc4feb..656e1b4a7 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -19,6 +19,8 @@
19enum class ErrorDescription : u32 { 19enum class ErrorDescription : u32 {
20 Success = 0, 20 Success = 0,
21 RemoteProcessDead = 301, 21 RemoteProcessDead = 301,
22 InvalidOffset = 6061,
23 InvalidLength = 6062,
22}; 24};
23 25
24/** 26/**
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
index 52db83e62..a674c9493 100644
--- a/src/core/hle/service/filesystem/filesystem.h
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -6,11 +6,20 @@
6 6
7#include <memory> 7#include <memory>
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/file_sys/filesystem.h"
10#include "core/hle/result.h" 9#include "core/hle/result.h"
11#include "core/hle/service/service.h" 10
11namespace FileSys {
12class FileSystemBackend;
13class FileSystemFactory;
14class Path;
15} // namespace FileSys
12 16
13namespace Service { 17namespace Service {
18
19namespace SM {
20class ServiceManager;
21} // namespace SM
22
14namespace FileSystem { 23namespace FileSystem {
15 24
16/// Supported FileSystem types 25/// Supported FileSystem types
@@ -37,5 +46,5 @@ ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type,
37/// Registers all Filesystem services with the specified service manager. 46/// Registers all Filesystem services with the specified service manager.
38void InstallInterfaces(SM::ServiceManager& service_manager); 47void InstallInterfaces(SM::ServiceManager& service_manager);
39 48
40} // namespace Filesystem 49} // namespace FileSystem
41} // namespace Service 50} // namespace Service
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 47a97f0fd..ef1915e5a 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -20,9 +20,8 @@ public:
20 IStorage(std::unique_ptr<FileSys::StorageBackend>&& backend) 20 IStorage(std::unique_ptr<FileSys::StorageBackend>&& backend)
21 : ServiceFramework("IStorage"), backend(std::move(backend)) { 21 : ServiceFramework("IStorage"), backend(std::move(backend)) {
22 static const FunctionInfo functions[] = { 22 static const FunctionInfo functions[] = {
23 {0, &IStorage::Read, "Read"}, {1, &IStorage::Write, "Write"}, 23 {0, &IStorage::Read, "Read"}, {1, nullptr, "Write"}, {2, nullptr, "Flush"},
24 {2, &IStorage::Flush, "Flush"}, {3, &IStorage::SetSize, "SetSize"}, 24 {3, nullptr, "SetSize"}, {4, nullptr, "GetSize"},
25 {4, &IStorage::GetSize, "GetSize"},
26 }; 25 };
27 RegisterHandlers(functions); 26 RegisterHandlers(functions);
28 } 27 }
@@ -32,49 +31,40 @@ private:
32 31
33 void Read(Kernel::HLERequestContext& ctx) { 32 void Read(Kernel::HLERequestContext& ctx) {
34 IPC::RequestParser rp{ctx}; 33 IPC::RequestParser rp{ctx};
35 u64 offset = rp.Pop<u64>(); 34 const s64 offset = rp.Pop<s64>();
36 u64 length = rp.Pop<u64>(); 35 const s64 length = rp.Pop<s64>();
36 const auto& descriptor = ctx.BufferDescriptorB()[0];
37 37
38 LOG_DEBUG(Service, "called, offset=0x%llx, length=0x%llx", offset, length); 38 LOG_DEBUG(Service_FS, "called, offset=0x%llx, length=0x%llx", offset, length);
39 39
40 auto descriptor = ctx.BufferDescriptorB()[0]; 40 // Error checking
41 std::vector<u8> output(length); 41 ASSERT_MSG(length == descriptor.Size(), "unexpected size difference");
42 if (length < 0) {
43 IPC::RequestBuilder rb{ctx, 2};
44 rb.Push(ResultCode(ErrorModule::FS, ErrorDescription::InvalidLength));
45 return;
46 }
47 if (offset < 0) {
48 IPC::RequestBuilder rb{ctx, 2};
49 rb.Push(ResultCode(ErrorModule::FS, ErrorDescription::InvalidOffset));
50 return;
51 }
42 52
53 // Read the data from the Storage backend
54 std::vector<u8> output(length);
43 ResultVal<size_t> res = backend->Read(offset, length, output.data()); 55 ResultVal<size_t> res = backend->Read(offset, length, output.data());
44 if (res.Failed()) { 56 if (res.Failed()) {
45 IPC::RequestBuilder rb{ctx, 2}; 57 IPC::RequestBuilder rb{ctx, 2};
46 rb.Push(res.Code()); 58 rb.Push(res.Code());
59 return;
47 } 60 }
48 61
62 // Write the data to memory
49 Memory::WriteBlock(descriptor.Address(), output.data(), descriptor.Size()); 63 Memory::WriteBlock(descriptor.Address(), output.data(), descriptor.Size());
50 64
51 IPC::RequestBuilder rb{ctx, 2}; 65 IPC::RequestBuilder rb{ctx, 2};
52 rb.Push(RESULT_SUCCESS); 66 rb.Push(RESULT_SUCCESS);
53 } 67 }
54
55 void Write(Kernel::HLERequestContext& ctx) {
56 IPC::RequestBuilder rb{ctx, 2};
57 rb.Push(RESULT_SUCCESS);
58 LOG_WARNING(Service, "(STUBBED) called");
59 }
60
61 void Flush(Kernel::HLERequestContext& ctx) {
62 IPC::RequestBuilder rb{ctx, 2};
63 rb.Push(RESULT_SUCCESS);
64 LOG_WARNING(Service, "(STUBBED) called");
65 }
66
67 void SetSize(Kernel::HLERequestContext& ctx) {
68 IPC::RequestBuilder rb{ctx, 2};
69 rb.Push(RESULT_SUCCESS);
70 LOG_WARNING(Service, "(STUBBED) called");
71 }
72
73 void GetSize(Kernel::HLERequestContext& ctx) {
74 IPC::RequestBuilder rb{ctx, 2};
75 rb.Push(RESULT_SUCCESS);
76 LOG_WARNING(Service, "(STUBBED) called");
77 }
78}; 68};
79 69
80FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { 70FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
@@ -87,46 +77,62 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
87 RegisterHandlers(functions); 77 RegisterHandlers(functions);
88} 78}
89 79
80void FSP_SRV::TryLoadRomFS() {
81 if (romfs) {
82 return;
83 }
84 FileSys::Path unused;
85 auto res = OpenFileSystem(Type::RomFS, unused);
86 if (res.Succeeded()) {
87 romfs = std::move(res.Unwrap());
88 }
89}
90
90void FSP_SRV::Initalize(Kernel::HLERequestContext& ctx) { 91void FSP_SRV::Initalize(Kernel::HLERequestContext& ctx) {
92 LOG_WARNING(Service_FS, "(STUBBED) called");
93
91 IPC::RequestBuilder rb{ctx, 2}; 94 IPC::RequestBuilder rb{ctx, 2};
92 rb.Push(RESULT_SUCCESS); 95 rb.Push(RESULT_SUCCESS);
93 LOG_WARNING(Service, "(STUBBED) called");
94} 96}
95 97
96void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { 98void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
99 LOG_WARNING(Service_FS, "(STUBBED) called");
100
97 IPC::RequestBuilder rb{ctx, 4}; 101 IPC::RequestBuilder rb{ctx, 4};
98 rb.Push(RESULT_SUCCESS); 102 rb.Push(RESULT_SUCCESS);
99 rb.Push<u32>(5); 103 rb.Push<u32>(5);
100 LOG_WARNING(Service, "(STUBBED) called");
101} 104}
102 105
103void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { 106void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
104 FileSys::Path path; 107 LOG_DEBUG(Service_FS, "called");
105 auto filesystem = OpenFileSystem(Type::RomFS, path); 108
106 if (filesystem.Failed()) { 109 TryLoadRomFS();
110 if (!romfs) {
111 // TODO (bunnei): Find the right error code to use here
112 LOG_CRITICAL(Service_FS, "no file system interface available!");
107 IPC::RequestBuilder rb{ctx, 2}; 113 IPC::RequestBuilder rb{ctx, 2};
108 rb.Push(filesystem.Code()); 114 rb.Push(ResultCode(-1));
109 return; 115 return;
110 } 116 }
111 117
112 auto storage = filesystem.Unwrap()->OpenFile({}, {}); 118 // Attempt to open a StorageBackend interface to the RomFS
119 auto storage = romfs->OpenFile({}, {});
113 if (storage.Failed()) { 120 if (storage.Failed()) {
121 LOG_CRITICAL(Service_FS, "no storage interface available!");
114 IPC::RequestBuilder rb{ctx, 2}; 122 IPC::RequestBuilder rb{ctx, 2};
115 rb.Push(storage.Code()); 123 rb.Push(storage.Code());
116 return; 124 return;
117 } 125 }
118 126
119 // TODO: What if already opened?
120
121 IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; 127 IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
122 rb.Push(RESULT_SUCCESS); 128 rb.Push(RESULT_SUCCESS);
123 rb.PushIpcInterface<IStorage>(std::move(storage.Unwrap())); 129 rb.PushIpcInterface<IStorage>(std::move(storage.Unwrap()));
124 LOG_WARNING(Service, "(STUBBED) called");
125} 130}
126 131
127void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { 132void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) {
133 LOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess");
128 OpenDataStorageByCurrentProcess(ctx); 134 OpenDataStorageByCurrentProcess(ctx);
129} 135}
130 136
131} // namespace Filesystem 137} // namespace FileSystem
132} // namespace Service 138} // namespace Service
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h
index b41ba6bd1..15be8edc1 100644
--- a/src/core/hle/service/filesystem/fsp_srv.h
+++ b/src/core/hle/service/filesystem/fsp_srv.h
@@ -4,22 +4,31 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <memory>
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8 9
10namespace FileSys {
11class FileSystemBackend;
12}
13
9namespace Service { 14namespace Service {
10namespace FileSystem { 15namespace FileSystem {
11 16
12class FSP_SRV final : public ServiceFramework<FSP_SRV> { 17class FSP_SRV final : public ServiceFramework<FSP_SRV> {
13public: 18public:
14 FSP_SRV(); 19 explicit FSP_SRV();
15 ~FSP_SRV() = default; 20 ~FSP_SRV() = default;
16 21
17private: 22private:
23 void TryLoadRomFS();
24
18 void Initalize(Kernel::HLERequestContext& ctx); 25 void Initalize(Kernel::HLERequestContext& ctx);
19 void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); 26 void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
20 void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); 27 void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
21 void OpenRomStorage(Kernel::HLERequestContext& ctx); 28 void OpenRomStorage(Kernel::HLERequestContext& ctx);
29
30 std::unique_ptr<FileSys::FileSystemBackend> romfs;
22}; 31};
23 32
24} // namespace Filesystem 33} // namespace FileSystem
25} // namespace Service 34} // namespace Service