diff options
| author | 2018-01-20 21:32:36 -0500 | |
|---|---|---|
| committer | 2018-01-21 15:51:43 -0500 | |
| commit | 8e50d6002bd12dde7e4ba4fd3da1b53864c4058c (patch) | |
| tree | be6d0f47d8418a61a8e6f86ce0dcdbecf801bebd /src | |
| parent | deconstructed_rom_directory: Implement istorage loading for RomFS. (diff) | |
| download | yuzu-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.h | 5 | ||||
| -rw-r--r-- | src/core/hle/result.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/filesystem.h | 15 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.cpp | 92 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.h | 13 |
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 | ||
| 307 | template <> | 307 | template <> |
| 308 | inline s64 RequestParser::Pop() { | ||
| 309 | return static_cast<s64>(Pop<u64>()); | ||
| 310 | } | ||
| 311 | |||
| 312 | template <> | ||
| 308 | inline bool RequestParser::Pop() { | 313 | inline 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 @@ | |||
| 19 | enum class ErrorDescription : u32 { | 19 | enum 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 | |
| 11 | namespace FileSys { | ||
| 12 | class FileSystemBackend; | ||
| 13 | class FileSystemFactory; | ||
| 14 | class Path; | ||
| 15 | } // namespace FileSys | ||
| 12 | 16 | ||
| 13 | namespace Service { | 17 | namespace Service { |
| 18 | |||
| 19 | namespace SM { | ||
| 20 | class ServiceManager; | ||
| 21 | } // namespace SM | ||
| 22 | |||
| 14 | namespace FileSystem { | 23 | namespace 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. |
| 38 | void InstallInterfaces(SM::ServiceManager& service_manager); | 47 | void 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 | ||
| 80 | FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { | 70 | FSP_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 | ||
| 80 | void 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 | |||
| 90 | void FSP_SRV::Initalize(Kernel::HLERequestContext& ctx) { | 91 | void 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 | ||
| 96 | void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { | 98 | void 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 | ||
| 103 | void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { | 106 | void 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 | ||
| 127 | void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { | 132 | void 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 | ||
| 10 | namespace FileSys { | ||
| 11 | class FileSystemBackend; | ||
| 12 | } | ||
| 13 | |||
| 9 | namespace Service { | 14 | namespace Service { |
| 10 | namespace FileSystem { | 15 | namespace FileSystem { |
| 11 | 16 | ||
| 12 | class FSP_SRV final : public ServiceFramework<FSP_SRV> { | 17 | class FSP_SRV final : public ServiceFramework<FSP_SRV> { |
| 13 | public: | 18 | public: |
| 14 | FSP_SRV(); | 19 | explicit FSP_SRV(); |
| 15 | ~FSP_SRV() = default; | 20 | ~FSP_SRV() = default; |
| 16 | 21 | ||
| 17 | private: | 22 | private: |
| 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 |