summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
authorGravatar bunnei2018-01-21 16:15:15 -0500
committerGravatar GitHub2018-01-21 16:15:15 -0500
commitab8525705bbd0ae62b567f301281ca516e7c5320 (patch)
tree88be854c845cb826366acca96e07ccc62cc96695 /src/core/hle
parentMerge pull request #129 from Rozelette/master (diff)
parentfile_sys: Clang format fixes. (diff)
downloadyuzu-ab8525705bbd0ae62b567f301281ca516e7c5320.tar.gz
yuzu-ab8525705bbd0ae62b567f301281ca516e7c5320.tar.xz
yuzu-ab8525705bbd0ae62b567f301281ca516e7c5320.zip
Merge pull request #123 from bunnei/fs
Initial implementation of RomFS filesystem and fsp-srv
Diffstat (limited to 'src/core/hle')
-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.cpp54
-rw-r--r--src/core/hle/service/filesystem/filesystem.h50
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp138
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.h34
-rw-r--r--src/core/hle/service/service.cpp2
7 files changed, 285 insertions, 0 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.cpp b/src/core/hle/service/filesystem/filesystem.cpp
new file mode 100644
index 000000000..4b47548fd
--- /dev/null
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -0,0 +1,54 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <boost/container/flat_map.hpp>
6#include "core/file_sys/filesystem.h"
7#include "core/hle/service/filesystem/filesystem.h"
8#include "core/hle/service/filesystem/fsp_srv.h"
9
10namespace Service {
11namespace FileSystem {
12
13/**
14 * Map of registered file systems, identified by type. Once an file system is registered here, it
15 * is never removed until UnregisterFileSystems is called.
16 */
17static boost::container::flat_map<Type, std::unique_ptr<FileSys::FileSystemFactory>> filesystem_map;
18
19ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& factory, Type type) {
20 auto result = filesystem_map.emplace(type, std::move(factory));
21
22 bool inserted = result.second;
23 ASSERT_MSG(inserted, "Tried to register more than one system with same id code");
24
25 auto& filesystem = result.first->second;
26 LOG_DEBUG(Service_FS, "Registered file system %s with id code 0x%08X",
27 filesystem->GetName().c_str(), static_cast<u32>(type));
28 return RESULT_SUCCESS;
29}
30
31ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type,
32 FileSys::Path& path) {
33 LOG_TRACE(Service_FS, "Opening FileSystem with type=%d", type);
34
35 auto itr = filesystem_map.find(type);
36 if (itr == filesystem_map.end()) {
37 // TODO(bunnei): Find a better error code for this
38 return ResultCode(-1);
39 }
40
41 return itr->second->Open(path);
42}
43
44void UnregisterFileSystems() {
45 filesystem_map.clear();
46}
47
48void InstallInterfaces(SM::ServiceManager& service_manager) {
49 UnregisterFileSystems();
50 std::make_shared<FSP_SRV>()->InstallAsService(service_manager);
51}
52
53} // namespace FileSystem
54} // namespace Service
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
new file mode 100644
index 000000000..a674c9493
--- /dev/null
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -0,0 +1,50 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include "common/common_types.h"
9#include "core/hle/result.h"
10
11namespace FileSys {
12class FileSystemBackend;
13class FileSystemFactory;
14class Path;
15} // namespace FileSys
16
17namespace Service {
18
19namespace SM {
20class ServiceManager;
21} // namespace SM
22
23namespace FileSystem {
24
25/// Supported FileSystem types
26enum class Type {
27 RomFS = 1,
28};
29
30/**
31 * Registers a FileSystem, instances of which can later be opened using its IdCode.
32 * @param factory FileSystem backend interface to use
33 * @param type Type used to access this type of FileSystem
34 */
35ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& factory, Type type);
36
37/**
38 * Opens a file system
39 * @param type Type of the file system to open
40 * @param path Path to the file system, used with Binary paths
41 * @return FileSys::FileSystemBackend interface to the file system
42 */
43ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type,
44 FileSys::Path& path);
45
46/// Registers all Filesystem services with the specified service manager.
47void InstallInterfaces(SM::ServiceManager& service_manager);
48
49} // namespace FileSystem
50} // namespace Service
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
new file mode 100644
index 000000000..ef1915e5a
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -0,0 +1,138 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6#include "core/core.h"
7#include "core/file_sys/filesystem.h"
8#include "core/file_sys/storage.h"
9#include "core/hle/ipc_helpers.h"
10#include "core/hle/kernel/client_port.h"
11#include "core/hle/kernel/client_session.h"
12#include "core/hle/service/filesystem/filesystem.h"
13#include "core/hle/service/filesystem/fsp_srv.h"
14
15namespace Service {
16namespace FileSystem {
17
18class IStorage final : public ServiceFramework<IStorage> {
19public:
20 IStorage(std::unique_ptr<FileSys::StorageBackend>&& backend)
21 : ServiceFramework("IStorage"), backend(std::move(backend)) {
22 static const FunctionInfo functions[] = {
23 {0, &IStorage::Read, "Read"}, {1, nullptr, "Write"}, {2, nullptr, "Flush"},
24 {3, nullptr, "SetSize"}, {4, nullptr, "GetSize"},
25 };
26 RegisterHandlers(functions);
27 }
28
29private:
30 std::unique_ptr<FileSys::StorageBackend> backend;
31
32 void Read(Kernel::HLERequestContext& ctx) {
33 IPC::RequestParser rp{ctx};
34 const s64 offset = rp.Pop<s64>();
35 const s64 length = rp.Pop<s64>();
36 const auto& descriptor = ctx.BufferDescriptorB()[0];
37
38 LOG_DEBUG(Service_FS, "called, offset=0x%llx, length=0x%llx", offset, length);
39
40 // Error checking
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 }
52
53 // Read the data from the Storage backend
54 std::vector<u8> output(length);
55 ResultVal<size_t> res = backend->Read(offset, length, output.data());
56 if (res.Failed()) {
57 IPC::RequestBuilder rb{ctx, 2};
58 rb.Push(res.Code());
59 return;
60 }
61
62 // Write the data to memory
63 Memory::WriteBlock(descriptor.Address(), output.data(), descriptor.Size());
64
65 IPC::RequestBuilder rb{ctx, 2};
66 rb.Push(RESULT_SUCCESS);
67 }
68};
69
70FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
71 static const FunctionInfo functions[] = {
72 {1, &FSP_SRV::Initalize, "Initalize"},
73 {200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
74 {203, &FSP_SRV::OpenRomStorage, "OpenRomStorage"},
75 {1005, &FSP_SRV::GetGlobalAccessLogMode, "GetGlobalAccessLogMode"},
76 };
77 RegisterHandlers(functions);
78}
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
91void FSP_SRV::Initalize(Kernel::HLERequestContext& ctx) {
92 LOG_WARNING(Service_FS, "(STUBBED) called");
93
94 IPC::RequestBuilder rb{ctx, 2};
95 rb.Push(RESULT_SUCCESS);
96}
97
98void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
99 LOG_WARNING(Service_FS, "(STUBBED) called");
100
101 IPC::RequestBuilder rb{ctx, 4};
102 rb.Push(RESULT_SUCCESS);
103 rb.Push<u32>(5);
104}
105
106void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
107 LOG_DEBUG(Service_FS, "called");
108
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!");
113 IPC::RequestBuilder rb{ctx, 2};
114 rb.Push(ResultCode(-1));
115 return;
116 }
117
118 // Attempt to open a StorageBackend interface to the RomFS
119 auto storage = romfs->OpenFile({}, {});
120 if (storage.Failed()) {
121 LOG_CRITICAL(Service_FS, "no storage interface available!");
122 IPC::RequestBuilder rb{ctx, 2};
123 rb.Push(storage.Code());
124 return;
125 }
126
127 IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
128 rb.Push(RESULT_SUCCESS);
129 rb.PushIpcInterface<IStorage>(std::move(storage.Unwrap()));
130}
131
132void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) {
133 LOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess");
134 OpenDataStorageByCurrentProcess(ctx);
135}
136
137} // namespace FileSystem
138} // namespace Service
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h
new file mode 100644
index 000000000..15be8edc1
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp_srv.h
@@ -0,0 +1,34 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include "core/hle/service/service.h"
9
10namespace FileSys {
11class FileSystemBackend;
12}
13
14namespace Service {
15namespace FileSystem {
16
17class FSP_SRV final : public ServiceFramework<FSP_SRV> {
18public:
19 explicit FSP_SRV();
20 ~FSP_SRV() = default;
21
22private:
23 void TryLoadRomFS();
24
25 void Initalize(Kernel::HLERequestContext& ctx);
26 void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
27 void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
28 void OpenRomStorage(Kernel::HLERequestContext& ctx);
29
30 std::unique_ptr<FileSys::FileSystemBackend> romfs;
31};
32
33} // namespace FileSystem
34} // namespace Service
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 19213a2f4..3f5ce56c6 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -19,6 +19,7 @@
19#include "core/hle/service/aoc/aoc_u.h" 19#include "core/hle/service/aoc/aoc_u.h"
20#include "core/hle/service/apm/apm.h" 20#include "core/hle/service/apm/apm.h"
21#include "core/hle/service/audio/audio.h" 21#include "core/hle/service/audio/audio.h"
22#include "core/hle/service/filesystem/filesystem.h"
22#include "core/hle/service/hid/hid.h" 23#include "core/hle/service/hid/hid.h"
23#include "core/hle/service/lm/lm.h" 24#include "core/hle/service/lm/lm.h"
24#include "core/hle/service/nvdrv/nvdrv.h" 25#include "core/hle/service/nvdrv/nvdrv.h"
@@ -172,6 +173,7 @@ void Init() {
172 AOC::InstallInterfaces(*SM::g_service_manager); 173 AOC::InstallInterfaces(*SM::g_service_manager);
173 APM::InstallInterfaces(*SM::g_service_manager); 174 APM::InstallInterfaces(*SM::g_service_manager);
174 Audio::InstallInterfaces(*SM::g_service_manager); 175 Audio::InstallInterfaces(*SM::g_service_manager);
176 FileSystem::InstallInterfaces(*SM::g_service_manager);
175 HID::InstallInterfaces(*SM::g_service_manager); 177 HID::InstallInterfaces(*SM::g_service_manager);
176 LM::InstallInterfaces(*SM::g_service_manager); 178 LM::InstallInterfaces(*SM::g_service_manager);
177 Nvidia::InstallInterfaces(*SM::g_service_manager); 179 Nvidia::InstallInterfaces(*SM::g_service_manager);