diff options
Diffstat (limited to 'src')
23 files changed, 271 insertions, 214 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 32ff3c345..8416e73b0 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h | |||
| @@ -116,6 +116,8 @@ public: | |||
| 116 | */ | 116 | */ |
| 117 | virtual void LoadContext(const ThreadContext& ctx) = 0; | 117 | virtual void LoadContext(const ThreadContext& ctx) = 0; |
| 118 | 118 | ||
| 119 | virtual void ClearExclusiveState() = 0; | ||
| 120 | |||
| 119 | /// Prepare core for thread reschedule (if needed to correctly handle state) | 121 | /// Prepare core for thread reschedule (if needed to correctly handle state) |
| 120 | virtual void PrepareReschedule() = 0; | 122 | virtual void PrepareReschedule() = 0; |
| 121 | }; | 123 | }; |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 42605374b..3572ee7b9 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp | |||
| @@ -226,6 +226,10 @@ void ARM_Dynarmic::ClearInstructionCache() { | |||
| 226 | jit->ClearCache(); | 226 | jit->ClearCache(); |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | void ARM_Dynarmic::ClearExclusiveState() { | ||
| 230 | jit->ClearExclusiveState(); | ||
| 231 | } | ||
| 232 | |||
| 229 | void ARM_Dynarmic::PageTableChanged() { | 233 | void ARM_Dynarmic::PageTableChanged() { |
| 230 | jit = MakeJit(cb); | 234 | jit = MakeJit(cb); |
| 231 | current_page_table = Memory::GetCurrentPageTable(); | 235 | current_page_table = Memory::GetCurrentPageTable(); |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 128669d01..ed724c3f1 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h | |||
| @@ -39,6 +39,7 @@ public: | |||
| 39 | void LoadContext(const ThreadContext& ctx) override; | 39 | void LoadContext(const ThreadContext& ctx) override; |
| 40 | 40 | ||
| 41 | void PrepareReschedule() override; | 41 | void PrepareReschedule() override; |
| 42 | void ClearExclusiveState() override; | ||
| 42 | 43 | ||
| 43 | void ClearInstructionCache() override; | 44 | void ClearInstructionCache() override; |
| 44 | void PageTableChanged() override; | 45 | void PageTableChanged() override; |
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index f239cf0ea..d2d699e9b 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp | |||
| @@ -263,6 +263,8 @@ void ARM_Unicorn::PrepareReschedule() { | |||
| 263 | CHECKED(uc_emu_stop(uc)); | 263 | CHECKED(uc_emu_stop(uc)); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | void ARM_Unicorn::ClearExclusiveState() {} | ||
| 267 | |||
| 266 | void ARM_Unicorn::ClearInstructionCache() {} | 268 | void ARM_Unicorn::ClearInstructionCache() {} |
| 267 | 269 | ||
| 268 | void ARM_Unicorn::RecordBreak(GDBStub::BreakpointAddress bkpt) { | 270 | void ARM_Unicorn::RecordBreak(GDBStub::BreakpointAddress bkpt) { |
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h index a482a2aa3..a78a0acf2 100644 --- a/src/core/arm/unicorn/arm_unicorn.h +++ b/src/core/arm/unicorn/arm_unicorn.h | |||
| @@ -31,6 +31,7 @@ public: | |||
| 31 | void SaveContext(ThreadContext& ctx) override; | 31 | void SaveContext(ThreadContext& ctx) override; |
| 32 | void LoadContext(const ThreadContext& ctx) override; | 32 | void LoadContext(const ThreadContext& ctx) override; |
| 33 | void PrepareReschedule() override; | 33 | void PrepareReschedule() override; |
| 34 | void ClearExclusiveState() override; | ||
| 34 | void ExecuteInstructions(int num_instructions); | 35 | void ExecuteInstructions(int num_instructions); |
| 35 | void Run() override; | 36 | void Run() override; |
| 36 | void Step() override; | 37 | void Step() override; |
diff --git a/src/core/file_sys/errors.h b/src/core/file_sys/errors.h index d3e9a3829..1f3b8fa84 100644 --- a/src/core/file_sys/errors.h +++ b/src/core/file_sys/errors.h | |||
| @@ -12,6 +12,8 @@ namespace ErrCodes { | |||
| 12 | enum { | 12 | enum { |
| 13 | NotFound = 1, | 13 | NotFound = 1, |
| 14 | SaveDataNotFound = 1002, | 14 | SaveDataNotFound = 1002, |
| 15 | SdCardNotFound = 2001, | ||
| 16 | RomFSNotFound = 2520, | ||
| 15 | }; | 17 | }; |
| 16 | } | 18 | } |
| 17 | 19 | ||
diff --git a/src/core/file_sys/filesystem.h b/src/core/file_sys/filesystem.h index 295a3133e..1a32a373b 100644 --- a/src/core/file_sys/filesystem.h +++ b/src/core/file_sys/filesystem.h | |||
| @@ -167,35 +167,4 @@ public: | |||
| 167 | virtual ResultVal<EntryType> GetEntryType(const std::string& path) const = 0; | 167 | virtual ResultVal<EntryType> GetEntryType(const std::string& path) const = 0; |
| 168 | }; | 168 | }; |
| 169 | 169 | ||
| 170 | class FileSystemFactory : NonCopyable { | ||
| 171 | public: | ||
| 172 | virtual ~FileSystemFactory() {} | ||
| 173 | |||
| 174 | /** | ||
| 175 | * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) | ||
| 176 | */ | ||
| 177 | virtual std::string GetName() const = 0; | ||
| 178 | |||
| 179 | /** | ||
| 180 | * Tries to open the archive of this type with the specified path | ||
| 181 | * @param path Path to the archive | ||
| 182 | * @return An ArchiveBackend corresponding operating specified archive path. | ||
| 183 | */ | ||
| 184 | virtual ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) = 0; | ||
| 185 | |||
| 186 | /** | ||
| 187 | * Deletes the archive contents and then re-creates the base folder | ||
| 188 | * @param path Path to the archive | ||
| 189 | * @return ResultCode of the operation, 0 on success | ||
| 190 | */ | ||
| 191 | virtual ResultCode Format(const Path& path) = 0; | ||
| 192 | |||
| 193 | /** | ||
| 194 | * Retrieves the format info about the archive with the specified path | ||
| 195 | * @param path Path to the archive | ||
| 196 | * @return Format information about the archive or error code | ||
| 197 | */ | ||
| 198 | virtual ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const = 0; | ||
| 199 | }; | ||
| 200 | |||
| 201 | } // namespace FileSys | 170 | } // namespace FileSys |
diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index 84ae0d99b..946fc0452 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp | |||
| @@ -11,28 +11,17 @@ | |||
| 11 | 11 | ||
| 12 | namespace FileSys { | 12 | namespace FileSys { |
| 13 | 13 | ||
| 14 | RomFS_Factory::RomFS_Factory(Loader::AppLoader& app_loader) { | 14 | RomFSFactory::RomFSFactory(Loader::AppLoader& app_loader) { |
| 15 | // Load the RomFS from the app | 15 | // Load the RomFS from the app |
| 16 | if (Loader::ResultStatus::Success != app_loader.ReadRomFS(romfs_file, data_offset, data_size)) { | 16 | if (Loader::ResultStatus::Success != app_loader.ReadRomFS(romfs_file, data_offset, data_size)) { |
| 17 | LOG_ERROR(Service_FS, "Unable to read RomFS!"); | 17 | LOG_ERROR(Service_FS, "Unable to read RomFS!"); |
| 18 | } | 18 | } |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | ResultVal<std::unique_ptr<FileSystemBackend>> RomFS_Factory::Open(const Path& path) { | 21 | ResultVal<std::unique_ptr<FileSystemBackend>> RomFSFactory::Open(u64 title_id) { |
| 22 | // TODO(DarkLordZach): Use title id. | ||
| 22 | auto archive = std::make_unique<RomFS_FileSystem>(romfs_file, data_offset, data_size); | 23 | auto archive = std::make_unique<RomFS_FileSystem>(romfs_file, data_offset, data_size); |
| 23 | return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive)); | 24 | return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive)); |
| 24 | } | 25 | } |
| 25 | 26 | ||
| 26 | ResultCode RomFS_Factory::Format(const Path& path) { | ||
| 27 | LOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName()); | ||
| 28 | // TODO(bunnei): Find the right error code for this | ||
| 29 | return ResultCode(-1); | ||
| 30 | } | ||
| 31 | |||
| 32 | ResultVal<ArchiveFormatInfo> RomFS_Factory::GetFormatInfo(const Path& path) const { | ||
| 33 | LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); | ||
| 34 | // TODO(bunnei): Find the right error code for this | ||
| 35 | return ResultCode(-1); | ||
| 36 | } | ||
| 37 | |||
| 38 | } // namespace FileSys | 27 | } // namespace FileSys |
diff --git a/src/core/file_sys/romfs_factory.h b/src/core/file_sys/romfs_factory.h index e0698e642..c9e20c3ab 100644 --- a/src/core/file_sys/romfs_factory.h +++ b/src/core/file_sys/romfs_factory.h | |||
| @@ -15,16 +15,11 @@ | |||
| 15 | namespace FileSys { | 15 | namespace FileSys { |
| 16 | 16 | ||
| 17 | /// File system interface to the RomFS archive | 17 | /// File system interface to the RomFS archive |
| 18 | class RomFS_Factory final : public FileSystemFactory { | 18 | class RomFSFactory { |
| 19 | public: | 19 | public: |
| 20 | explicit RomFS_Factory(Loader::AppLoader& app_loader); | 20 | explicit RomFSFactory(Loader::AppLoader& app_loader); |
| 21 | 21 | ||
| 22 | std::string GetName() const override { | 22 | ResultVal<std::unique_ptr<FileSystemBackend>> Open(u64 title_id); |
| 23 | return "ArchiveFactory_RomFS"; | ||
| 24 | } | ||
| 25 | ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override; | ||
| 26 | ResultCode Format(const Path& path) override; | ||
| 27 | ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; | ||
| 28 | 23 | ||
| 29 | private: | 24 | private: |
| 30 | std::shared_ptr<FileUtil::IOFile> romfs_file; | 25 | std::shared_ptr<FileUtil::IOFile> romfs_file; |
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index f3aa213af..3ad37b28c 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp | |||
| @@ -12,11 +12,49 @@ | |||
| 12 | 12 | ||
| 13 | namespace FileSys { | 13 | namespace FileSys { |
| 14 | 14 | ||
| 15 | SaveData_Factory::SaveData_Factory(std::string nand_directory) | 15 | std::string SaveDataDescriptor::DebugInfo() { |
| 16 | return fmt::format("[type={:02X}, title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}]", | ||
| 17 | static_cast<u8>(type), title_id, user_id[1], user_id[0], save_id); | ||
| 18 | } | ||
| 19 | |||
| 20 | SaveDataFactory::SaveDataFactory(std::string nand_directory) | ||
| 16 | : nand_directory(std::move(nand_directory)) {} | 21 | : nand_directory(std::move(nand_directory)) {} |
| 17 | 22 | ||
| 18 | ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path& path) { | 23 | ResultVal<std::unique_ptr<FileSystemBackend>> SaveDataFactory::Open(SaveDataSpaceId space, |
| 19 | std::string save_directory = GetFullPath(); | 24 | SaveDataDescriptor meta) { |
| 25 | if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) { | ||
| 26 | if (meta.zero_1 != 0) { | ||
| 27 | LOG_WARNING(Service_FS, | ||
| 28 | "Possibly incorrect SaveDataDescriptor, type is " | ||
| 29 | "SystemSaveData||SaveData but offset 0x28 is non-zero ({:016X}).", | ||
| 30 | meta.zero_1); | ||
| 31 | } | ||
| 32 | if (meta.zero_2 != 0) { | ||
| 33 | LOG_WARNING(Service_FS, | ||
| 34 | "Possibly incorrect SaveDataDescriptor, type is " | ||
| 35 | "SystemSaveData||SaveData but offset 0x30 is non-zero ({:016X}).", | ||
| 36 | meta.zero_2); | ||
| 37 | } | ||
| 38 | if (meta.zero_3 != 0) { | ||
| 39 | LOG_WARNING(Service_FS, | ||
| 40 | "Possibly incorrect SaveDataDescriptor, type is " | ||
| 41 | "SystemSaveData||SaveData but offset 0x38 is non-zero ({:016X}).", | ||
| 42 | meta.zero_3); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | if (meta.type == SaveDataType::SystemSaveData && meta.title_id != 0) { | ||
| 47 | LOG_WARNING(Service_FS, | ||
| 48 | "Possibly incorrect SaveDataDescriptor, type is SystemSaveData but title_id is " | ||
| 49 | "non-zero ({:016X}).", | ||
| 50 | meta.title_id); | ||
| 51 | } | ||
| 52 | |||
| 53 | std::string save_directory = | ||
| 54 | GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); | ||
| 55 | |||
| 56 | // TODO(DarkLordZach): Try to not create when opening, there are dedicated create save methods. | ||
| 57 | // But, user_ids don't match so this works for now. | ||
| 20 | 58 | ||
| 21 | if (!FileUtil::Exists(save_directory)) { | 59 | if (!FileUtil::Exists(save_directory)) { |
| 22 | // TODO(bunnei): This is a work-around to always create a save data directory if it does not | 60 | // TODO(bunnei): This is a work-around to always create a save data directory if it does not |
| @@ -26,6 +64,12 @@ ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path& | |||
| 26 | FileUtil::CreateFullPath(save_directory); | 64 | FileUtil::CreateFullPath(save_directory); |
| 27 | } | 65 | } |
| 28 | 66 | ||
| 67 | // TODO(DarkLordZach): For some reason, CreateFullPath doesn't create the last bit. Should be | ||
| 68 | // fixed with VFS. | ||
| 69 | if (!FileUtil::IsDirectory(save_directory)) { | ||
| 70 | FileUtil::CreateDir(save_directory); | ||
| 71 | } | ||
| 72 | |||
| 29 | // Return an error if the save data doesn't actually exist. | 73 | // Return an error if the save data doesn't actually exist. |
| 30 | if (!FileUtil::IsDirectory(save_directory)) { | 74 | if (!FileUtil::IsDirectory(save_directory)) { |
| 31 | // TODO(Subv): Find out correct error code. | 75 | // TODO(Subv): Find out correct error code. |
| @@ -36,28 +80,35 @@ ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path& | |||
| 36 | return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive)); | 80 | return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive)); |
| 37 | } | 81 | } |
| 38 | 82 | ||
| 39 | ResultCode SaveData_Factory::Format(const Path& path) { | 83 | std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, |
| 40 | LOG_WARNING(Service_FS, "Format archive {}", GetName()); | 84 | u128 user_id, u64 save_id) const { |
| 41 | // Create the save data directory. | 85 | // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should |
| 42 | if (!FileUtil::CreateFullPath(GetFullPath())) { | 86 | // be interpreted as the title id of the current process. |
| 43 | // TODO(Subv): Find the correct error code. | 87 | if (type == SaveDataType::SaveData && title_id == 0) |
| 44 | return ResultCode(-1); | 88 | title_id = Core::CurrentProcess()->program_id; |
| 45 | } | ||
| 46 | 89 | ||
| 47 | return RESULT_SUCCESS; | 90 | std::string prefix; |
| 48 | } | ||
| 49 | 91 | ||
| 50 | ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) const { | 92 | switch (space) { |
| 51 | LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); | 93 | case SaveDataSpaceId::NandSystem: |
| 52 | // TODO(bunnei): Find the right error code for this | 94 | prefix = nand_directory + "system/save/"; |
| 53 | return ResultCode(-1); | 95 | break; |
| 54 | } | 96 | case SaveDataSpaceId::NandUser: |
| 97 | prefix = nand_directory + "user/save/"; | ||
| 98 | break; | ||
| 99 | default: | ||
| 100 | ASSERT_MSG(false, "Unrecognized SaveDataSpaceId: {:02X}", static_cast<u8>(space)); | ||
| 101 | } | ||
| 55 | 102 | ||
| 56 | std::string SaveData_Factory::GetFullPath() const { | 103 | switch (type) { |
| 57 | u64 title_id = Core::CurrentProcess()->program_id; | 104 | case SaveDataType::SystemSaveData: |
| 58 | // TODO(Subv): Somehow obtain this value. | 105 | return fmt::format("{}{:016X}/{:016X}{:016X}", prefix, save_id, user_id[1], user_id[0]); |
| 59 | u32 user = 0; | 106 | case SaveDataType::SaveData: |
| 60 | return fmt::format("{}save/{:016X}/{:08X}/", nand_directory, title_id, user); | 107 | return fmt::format("{}{:016X}/{:016X}{:016X}/{:016X}", prefix, 0, user_id[1], user_id[0], |
| 108 | title_id); | ||
| 109 | default: | ||
| 110 | ASSERT_MSG(false, "Unrecognized SaveDataType: {:02X}", static_cast<u8>(type)); | ||
| 111 | } | ||
| 61 | } | 112 | } |
| 62 | 113 | ||
| 63 | } // namespace FileSys | 114 | } // namespace FileSys |
diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h index 73a42aab6..b96721ac0 100644 --- a/src/core/file_sys/savedata_factory.h +++ b/src/core/file_sys/savedata_factory.h | |||
| @@ -12,22 +12,50 @@ | |||
| 12 | 12 | ||
| 13 | namespace FileSys { | 13 | namespace FileSys { |
| 14 | 14 | ||
| 15 | enum class SaveDataSpaceId : u8 { | ||
| 16 | NandSystem = 0, | ||
| 17 | NandUser = 1, | ||
| 18 | SdCard = 2, | ||
| 19 | TemporaryStorage = 3, | ||
| 20 | }; | ||
| 21 | |||
| 22 | enum class SaveDataType : u8 { | ||
| 23 | SystemSaveData = 0, | ||
| 24 | SaveData = 1, | ||
| 25 | BcatDeliveryCacheStorage = 2, | ||
| 26 | DeviceSaveData = 3, | ||
| 27 | TemporaryStorage = 4, | ||
| 28 | CacheStorage = 5, | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct SaveDataDescriptor { | ||
| 32 | u64_le title_id; | ||
| 33 | u128 user_id; | ||
| 34 | u64_le save_id; | ||
| 35 | SaveDataType type; | ||
| 36 | INSERT_PADDING_BYTES(7); | ||
| 37 | u64_le zero_1; | ||
| 38 | u64_le zero_2; | ||
| 39 | u64_le zero_3; | ||
| 40 | |||
| 41 | std::string DebugInfo(); | ||
| 42 | }; | ||
| 43 | static_assert(sizeof(SaveDataDescriptor) == 0x40, "SaveDataDescriptor has incorrect size."); | ||
| 44 | |||
| 15 | /// File system interface to the SaveData archive | 45 | /// File system interface to the SaveData archive |
| 16 | class SaveData_Factory final : public FileSystemFactory { | 46 | class SaveDataFactory { |
| 17 | public: | 47 | public: |
| 18 | explicit SaveData_Factory(std::string nand_directory); | 48 | explicit SaveDataFactory(std::string nand_directory); |
| 19 | 49 | ||
| 20 | std::string GetName() const override { | 50 | ResultVal<std::unique_ptr<FileSystemBackend>> Open(SaveDataSpaceId space, |
| 21 | return "SaveData_Factory"; | 51 | SaveDataDescriptor meta); |
| 22 | } | ||
| 23 | ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override; | ||
| 24 | ResultCode Format(const Path& path) override; | ||
| 25 | ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; | ||
| 26 | 52 | ||
| 27 | private: | 53 | private: |
| 28 | std::string nand_directory; | 54 | std::string nand_directory; |
| 55 | std::string sd_directory; | ||
| 29 | 56 | ||
| 30 | std::string GetFullPath() const; | 57 | std::string GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, u128 user_id, |
| 58 | u64 save_id) const; | ||
| 31 | }; | 59 | }; |
| 32 | 60 | ||
| 33 | } // namespace FileSys | 61 | } // namespace FileSys |
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index 2e5ffb764..ac6f2f971 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp | |||
| @@ -12,9 +12,9 @@ | |||
| 12 | 12 | ||
| 13 | namespace FileSys { | 13 | namespace FileSys { |
| 14 | 14 | ||
| 15 | SDMC_Factory::SDMC_Factory(std::string sd_directory) : sd_directory(std::move(sd_directory)) {} | 15 | SDMCFactory::SDMCFactory(std::string sd_directory) : sd_directory(std::move(sd_directory)) {} |
| 16 | 16 | ||
| 17 | ResultVal<std::unique_ptr<FileSystemBackend>> SDMC_Factory::Open(const Path& path) { | 17 | ResultVal<std::unique_ptr<FileSystemBackend>> SDMCFactory::Open() { |
| 18 | // Create the SD Card directory if it doesn't already exist. | 18 | // Create the SD Card directory if it doesn't already exist. |
| 19 | if (!FileUtil::IsDirectory(sd_directory)) { | 19 | if (!FileUtil::IsDirectory(sd_directory)) { |
| 20 | FileUtil::CreateFullPath(sd_directory); | 20 | FileUtil::CreateFullPath(sd_directory); |
| @@ -24,16 +24,4 @@ ResultVal<std::unique_ptr<FileSystemBackend>> SDMC_Factory::Open(const Path& pat | |||
| 24 | return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive)); | 24 | return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive)); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | ResultCode SDMC_Factory::Format(const Path& path) { | ||
| 28 | LOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName()); | ||
| 29 | // TODO(Subv): Find the right error code for this | ||
| 30 | return ResultCode(-1); | ||
| 31 | } | ||
| 32 | |||
| 33 | ResultVal<ArchiveFormatInfo> SDMC_Factory::GetFormatInfo(const Path& path) const { | ||
| 34 | LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); | ||
| 35 | // TODO(bunnei): Find the right error code for this | ||
| 36 | return ResultCode(-1); | ||
| 37 | } | ||
| 38 | |||
| 39 | } // namespace FileSys | 27 | } // namespace FileSys |
diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h index 93becda25..09bec7fce 100644 --- a/src/core/file_sys/sdmc_factory.h +++ b/src/core/file_sys/sdmc_factory.h | |||
| @@ -13,16 +13,11 @@ | |||
| 13 | namespace FileSys { | 13 | namespace FileSys { |
| 14 | 14 | ||
| 15 | /// File system interface to the SDCard archive | 15 | /// File system interface to the SDCard archive |
| 16 | class SDMC_Factory final : public FileSystemFactory { | 16 | class SDMCFactory { |
| 17 | public: | 17 | public: |
| 18 | explicit SDMC_Factory(std::string sd_directory); | 18 | explicit SDMCFactory(std::string sd_directory); |
| 19 | 19 | ||
| 20 | std::string GetName() const override { | 20 | ResultVal<std::unique_ptr<FileSystemBackend>> Open(); |
| 21 | return "SDMC_Factory"; | ||
| 22 | } | ||
| 23 | ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override; | ||
| 24 | ResultCode Format(const Path& path) override; | ||
| 25 | ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; | ||
| 26 | 21 | ||
| 27 | private: | 22 | private: |
| 28 | std::string sd_directory; | 23 | std::string sd_directory; |
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index e9c8369d7..d5df9590a 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -115,7 +115,7 @@ ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 valu | |||
| 115 | s32 updated_value; | 115 | s32 updated_value; |
| 116 | if (waiting_threads.size() == 0) { | 116 | if (waiting_threads.size() == 0) { |
| 117 | updated_value = value - 1; | 117 | updated_value = value - 1; |
| 118 | } else if (num_to_wake <= 0 || waiting_threads.size() <= num_to_wake) { | 118 | } else if (num_to_wake <= 0 || waiting_threads.size() <= static_cast<u32>(num_to_wake)) { |
| 119 | updated_value = value + 1; | 119 | updated_value = value + 1; |
| 120 | } else { | 120 | } else { |
| 121 | updated_value = value; | 121 | updated_value = value; |
| @@ -140,7 +140,9 @@ ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool | |||
| 140 | 140 | ||
| 141 | s32 cur_value = static_cast<s32>(Memory::Read32(address)); | 141 | s32 cur_value = static_cast<s32>(Memory::Read32(address)); |
| 142 | if (cur_value < value) { | 142 | if (cur_value < value) { |
| 143 | Memory::Write32(address, static_cast<u32>(cur_value - 1)); | 143 | if (should_decrement) { |
| 144 | Memory::Write32(address, static_cast<u32>(cur_value - 1)); | ||
| 145 | } | ||
| 144 | } else { | 146 | } else { |
| 145 | return ERR_INVALID_STATE; | 147 | return ERR_INVALID_STATE; |
| 146 | } | 148 | } |
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 11c2cb69e..ca8807e19 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp | |||
| @@ -85,6 +85,7 @@ void Scheduler::SwitchContext(Thread* new_thread) { | |||
| 85 | 85 | ||
| 86 | cpu_core->LoadContext(new_thread->context); | 86 | cpu_core->LoadContext(new_thread->context); |
| 87 | cpu_core->SetTlsAddress(new_thread->GetTLSAddress()); | 87 | cpu_core->SetTlsAddress(new_thread->GetTLSAddress()); |
| 88 | cpu_core->ClearExclusiveState(); | ||
| 88 | } else { | 89 | } else { |
| 89 | current_thread = nullptr; | 90 | current_thread = nullptr; |
| 90 | // Note: We do not reset the current process and current page table when idling because | 91 | // Note: We do not reset the current process and current page table when idling because |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index a871b3eaa..0f0ab1e6a 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -4,9 +4,11 @@ | |||
| 4 | 4 | ||
| 5 | #include <cinttypes> | 5 | #include <cinttypes> |
| 6 | #include <stack> | 6 | #include <stack> |
| 7 | #include "core/core.h" | ||
| 7 | #include "core/file_sys/filesystem.h" | 8 | #include "core/file_sys/filesystem.h" |
| 8 | #include "core/hle/ipc_helpers.h" | 9 | #include "core/hle/ipc_helpers.h" |
| 9 | #include "core/hle/kernel/event.h" | 10 | #include "core/hle/kernel/event.h" |
| 11 | #include "core/hle/kernel/process.h" | ||
| 10 | #include "core/hle/service/am/am.h" | 12 | #include "core/hle/service/am/am.h" |
| 11 | #include "core/hle/service/am/applet_ae.h" | 13 | #include "core/hle/service/am/applet_ae.h" |
| 12 | #include "core/hle/service/am/applet_oe.h" | 14 | #include "core/hle/service/am/applet_oe.h" |
| @@ -614,25 +616,14 @@ void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest( | |||
| 614 | 616 | ||
| 615 | void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { | 617 | void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { |
| 616 | IPC::RequestParser rp{ctx}; | 618 | IPC::RequestParser rp{ctx}; |
| 617 | u128 uid = rp.PopRaw<u128>(); | 619 | u128 uid = rp.PopRaw<u128>(); // What does this do? |
| 618 | 620 | ||
| 619 | LOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); | 621 | LOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); |
| 620 | 622 | ||
| 621 | IPC::ResponseBuilder rb{ctx, 4}; | 623 | IPC::ResponseBuilder rb{ctx, 4}; |
| 622 | 624 | rb.Push(RESULT_SUCCESS); | |
| 623 | FileSys::Path unused; | ||
| 624 | auto savedata = FileSystem::OpenFileSystem(FileSystem::Type::SaveData, unused); | ||
| 625 | if (savedata.Failed()) { | ||
| 626 | // Create the save data and return an error indicating that the operation was performed. | ||
| 627 | FileSystem::FormatFileSystem(FileSystem::Type::SaveData); | ||
| 628 | // TODO(Subv): Find out the correct error code for this. | ||
| 629 | rb.Push(ResultCode(ErrorModule::FS, 40)); | ||
| 630 | } else { | ||
| 631 | rb.Push(RESULT_SUCCESS); | ||
| 632 | } | ||
| 633 | |||
| 634 | rb.Push<u64>(0); | 625 | rb.Push<u64>(0); |
| 635 | } | 626 | } // namespace Service::AM |
| 636 | 627 | ||
| 637 | void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) { | 628 | void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) { |
| 638 | // Takes an input u32 Result, no output. | 629 | // Takes an input u32 Result, no output. |
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index f58b518b6..902256757 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include <boost/container/flat_map.hpp> | 5 | #include <boost/container/flat_map.hpp> |
| 6 | #include "common/file_util.h" | 6 | #include "common/file_util.h" |
| 7 | #include "core/file_sys/errors.h" | ||
| 7 | #include "core/file_sys/filesystem.h" | 8 | #include "core/file_sys/filesystem.h" |
| 8 | #include "core/file_sys/savedata_factory.h" | 9 | #include "core/file_sys/savedata_factory.h" |
| 9 | #include "core/file_sys/sdmc_factory.h" | 10 | #include "core/file_sys/sdmc_factory.h" |
| @@ -16,57 +17,77 @@ namespace Service::FileSystem { | |||
| 16 | * Map of registered file systems, identified by type. Once an file system is registered here, it | 17 | * Map of registered file systems, identified by type. Once an file system is registered here, it |
| 17 | * is never removed until UnregisterFileSystems is called. | 18 | * is never removed until UnregisterFileSystems is called. |
| 18 | */ | 19 | */ |
| 19 | static boost::container::flat_map<Type, std::unique_ptr<FileSys::FileSystemFactory>> filesystem_map; | 20 | static std::unique_ptr<FileSys::RomFSFactory> romfs_factory; |
| 20 | 21 | static std::unique_ptr<FileSys::SaveDataFactory> save_data_factory; | |
| 21 | ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& factory, Type type) { | 22 | static std::unique_ptr<FileSys::SDMCFactory> sdmc_factory; |
| 22 | auto result = filesystem_map.emplace(type, std::move(factory)); | 23 | |
| 24 | ResultCode RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory) { | ||
| 25 | ASSERT_MSG(romfs_factory == nullptr, "Tried to register a second RomFS"); | ||
| 26 | romfs_factory = std::move(factory); | ||
| 27 | LOG_DEBUG(Service_FS, "Registered RomFS"); | ||
| 28 | return RESULT_SUCCESS; | ||
| 29 | } | ||
| 23 | 30 | ||
| 24 | bool inserted = result.second; | 31 | ResultCode RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory) { |
| 25 | ASSERT_MSG(inserted, "Tried to register more than one system with same id code"); | 32 | ASSERT_MSG(romfs_factory == nullptr, "Tried to register a second save data"); |
| 33 | save_data_factory = std::move(factory); | ||
| 34 | LOG_DEBUG(Service_FS, "Registered save data"); | ||
| 35 | return RESULT_SUCCESS; | ||
| 36 | } | ||
| 26 | 37 | ||
| 27 | auto& filesystem = result.first->second; | 38 | ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory) { |
| 28 | LOG_DEBUG(Service_FS, "Registered file system {} with id code 0x{:08X}", filesystem->GetName(), | 39 | ASSERT_MSG(sdmc_factory == nullptr, "Tried to register a second SDMC"); |
| 29 | static_cast<u32>(type)); | 40 | sdmc_factory = std::move(factory); |
| 41 | LOG_DEBUG(Service_FS, "Registered SDMC"); | ||
| 30 | return RESULT_SUCCESS; | 42 | return RESULT_SUCCESS; |
| 31 | } | 43 | } |
| 32 | 44 | ||
| 33 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, | 45 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenRomFS(u64 title_id) { |
| 34 | FileSys::Path& path) { | 46 | LOG_TRACE(Service_FS, "Opening RomFS for title_id={:016X}", title_id); |
| 35 | LOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type)); | ||
| 36 | 47 | ||
| 37 | auto itr = filesystem_map.find(type); | 48 | if (romfs_factory == nullptr) { |
| 38 | if (itr == filesystem_map.end()) { | ||
| 39 | // TODO(bunnei): Find a better error code for this | 49 | // TODO(bunnei): Find a better error code for this |
| 40 | return ResultCode(-1); | 50 | return ResultCode(-1); |
| 41 | } | 51 | } |
| 42 | 52 | ||
| 43 | return itr->second->Open(path); | 53 | return romfs_factory->Open(title_id); |
| 44 | } | 54 | } |
| 45 | 55 | ||
| 46 | ResultCode FormatFileSystem(Type type) { | 56 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenSaveData( |
| 47 | LOG_TRACE(Service_FS, "Formatting FileSystem with type={}", static_cast<u32>(type)); | 57 | FileSys::SaveDataSpaceId space, FileSys::SaveDataDescriptor save_struct) { |
| 58 | LOG_TRACE(Service_FS, "Opening Save Data for space_id={:01X}, save_struct={}", | ||
| 59 | static_cast<u8>(space), SaveStructDebugInfo(save_struct)); | ||
| 48 | 60 | ||
| 49 | auto itr = filesystem_map.find(type); | 61 | if (save_data_factory == nullptr) { |
| 50 | if (itr == filesystem_map.end()) { | 62 | return ResultCode(ErrorModule::FS, FileSys::ErrCodes::SaveDataNotFound); |
| 51 | // TODO(bunnei): Find a better error code for this | 63 | } |
| 52 | return ResultCode(-1); | 64 | |
| 65 | return save_data_factory->Open(space, save_struct); | ||
| 66 | } | ||
| 67 | |||
| 68 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenSDMC() { | ||
| 69 | LOG_TRACE(Service_FS, "Opening SDMC"); | ||
| 70 | |||
| 71 | if (sdmc_factory == nullptr) { | ||
| 72 | return ResultCode(ErrorModule::FS, FileSys::ErrCodes::SdCardNotFound); | ||
| 53 | } | 73 | } |
| 54 | 74 | ||
| 55 | FileSys::Path unused; | 75 | return sdmc_factory->Open(); |
| 56 | return itr->second->Format(unused); | ||
| 57 | } | 76 | } |
| 58 | 77 | ||
| 59 | void RegisterFileSystems() { | 78 | void RegisterFileSystems() { |
| 60 | filesystem_map.clear(); | 79 | romfs_factory = nullptr; |
| 80 | save_data_factory = nullptr; | ||
| 81 | sdmc_factory = nullptr; | ||
| 61 | 82 | ||
| 62 | std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); | 83 | std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); |
| 63 | std::string sd_directory = FileUtil::GetUserPath(D_SDMC_IDX); | 84 | std::string sd_directory = FileUtil::GetUserPath(D_SDMC_IDX); |
| 64 | 85 | ||
| 65 | auto savedata = std::make_unique<FileSys::SaveData_Factory>(std::move(nand_directory)); | 86 | auto savedata = std::make_unique<FileSys::SaveDataFactory>(std::move(nand_directory)); |
| 66 | RegisterFileSystem(std::move(savedata), Type::SaveData); | 87 | save_data_factory = std::move(savedata); |
| 67 | 88 | ||
| 68 | auto sdcard = std::make_unique<FileSys::SDMC_Factory>(std::move(sd_directory)); | 89 | auto sdcard = std::make_unique<FileSys::SDMCFactory>(std::move(sd_directory)); |
| 69 | RegisterFileSystem(std::move(sdcard), Type::SDMC); | 90 | sdmc_factory = std::move(sdcard); |
| 70 | } | 91 | } |
| 71 | 92 | ||
| 72 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 93 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index 56d26146e..45272d326 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h | |||
| @@ -6,12 +6,13 @@ | |||
| 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/romfs_factory.h" | ||
| 10 | #include "core/file_sys/savedata_factory.h" | ||
| 11 | #include "core/file_sys/sdmc_factory.h" | ||
| 9 | #include "core/hle/result.h" | 12 | #include "core/hle/result.h" |
| 10 | 13 | ||
| 11 | namespace FileSys { | 14 | namespace FileSys { |
| 12 | class FileSystemBackend; | 15 | class FileSystemBackend; |
| 13 | class FileSystemFactory; | ||
| 14 | class Path; | ||
| 15 | } // namespace FileSys | 16 | } // namespace FileSys |
| 16 | 17 | ||
| 17 | namespace Service { | 18 | namespace Service { |
| @@ -22,35 +23,20 @@ class ServiceManager; | |||
| 22 | 23 | ||
| 23 | namespace FileSystem { | 24 | namespace FileSystem { |
| 24 | 25 | ||
| 25 | /// Supported FileSystem types | 26 | ResultCode RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory); |
| 26 | enum class Type { | 27 | ResultCode RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory); |
| 27 | RomFS = 1, | 28 | ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory); |
| 28 | SaveData = 2, | 29 | |
| 29 | SDMC = 3, | 30 | // TODO(DarkLordZach): BIS Filesystem |
| 30 | }; | 31 | // ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory); |
| 31 | 32 | ||
| 32 | /** | 33 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenRomFS(u64 title_id); |
| 33 | * Registers a FileSystem, instances of which can later be opened using its IdCode. | 34 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenSaveData( |
| 34 | * @param factory FileSystem backend interface to use | 35 | FileSys::SaveDataSpaceId space, FileSys::SaveDataDescriptor save_struct); |
| 35 | * @param type Type used to access this type of FileSystem | 36 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenSDMC(); |
| 36 | */ | 37 | |
| 37 | ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& factory, Type type); | 38 | // TODO(DarkLordZach): BIS Filesystem |
| 38 | 39 | // ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenBIS(); | |
| 39 | /** | ||
| 40 | * Opens a file system | ||
| 41 | * @param type Type of the file system to open | ||
| 42 | * @param path Path to the file system, used with Binary paths | ||
| 43 | * @return FileSys::FileSystemBackend interface to the file system | ||
| 44 | */ | ||
| 45 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, | ||
| 46 | FileSys::Path& path); | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Formats a file system | ||
| 50 | * @param type Type of the file system to format | ||
| 51 | * @return ResultCode of the operation | ||
| 52 | */ | ||
| 53 | ResultCode FormatFileSystem(Type type); | ||
| 54 | 40 | ||
| 55 | /// Registers all Filesystem services with the specified service manager. | 41 | /// Registers all Filesystem services with the specified service manager. |
| 56 | void InstallInterfaces(SM::ServiceManager& service_manager); | 42 | void InstallInterfaces(SM::ServiceManager& service_manager); |
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 82efe7f7d..22d3e645d 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp | |||
| @@ -13,11 +13,21 @@ | |||
| 13 | #include "core/hle/ipc_helpers.h" | 13 | #include "core/hle/ipc_helpers.h" |
| 14 | #include "core/hle/kernel/client_port.h" | 14 | #include "core/hle/kernel/client_port.h" |
| 15 | #include "core/hle/kernel/client_session.h" | 15 | #include "core/hle/kernel/client_session.h" |
| 16 | #include "core/hle/kernel/process.h" | ||
| 16 | #include "core/hle/service/filesystem/filesystem.h" | 17 | #include "core/hle/service/filesystem/filesystem.h" |
| 17 | #include "core/hle/service/filesystem/fsp_srv.h" | 18 | #include "core/hle/service/filesystem/fsp_srv.h" |
| 18 | 19 | ||
| 19 | namespace Service::FileSystem { | 20 | namespace Service::FileSystem { |
| 20 | 21 | ||
| 22 | enum class StorageId : u8 { | ||
| 23 | None = 0, | ||
| 24 | Host = 1, | ||
| 25 | GameCard = 2, | ||
| 26 | NandSystem = 3, | ||
| 27 | NandUser = 4, | ||
| 28 | SdCard = 5 | ||
| 29 | }; | ||
| 30 | |||
| 21 | class IStorage final : public ServiceFramework<IStorage> { | 31 | class IStorage final : public ServiceFramework<IStorage> { |
| 22 | public: | 32 | public: |
| 23 | IStorage(std::unique_ptr<FileSys::StorageBackend>&& backend) | 33 | IStorage(std::unique_ptr<FileSys::StorageBackend>&& backend) |
| @@ -487,17 +497,6 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { | |||
| 487 | RegisterHandlers(functions); | 497 | RegisterHandlers(functions); |
| 488 | } | 498 | } |
| 489 | 499 | ||
| 490 | void FSP_SRV::TryLoadRomFS() { | ||
| 491 | if (romfs) { | ||
| 492 | return; | ||
| 493 | } | ||
| 494 | FileSys::Path unused; | ||
| 495 | auto res = OpenFileSystem(Type::RomFS, unused); | ||
| 496 | if (res.Succeeded()) { | ||
| 497 | romfs = std::move(res.Unwrap()); | ||
| 498 | } | ||
| 499 | } | ||
| 500 | |||
| 501 | void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { | 500 | void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { |
| 502 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 501 | LOG_WARNING(Service_FS, "(STUBBED) called"); |
| 503 | 502 | ||
| @@ -508,8 +507,7 @@ void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { | |||
| 508 | void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { | 507 | void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { |
| 509 | LOG_DEBUG(Service_FS, "called"); | 508 | LOG_DEBUG(Service_FS, "called"); |
| 510 | 509 | ||
| 511 | FileSys::Path unused; | 510 | IFileSystem filesystem(OpenSDMC().Unwrap()); |
| 512 | auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap(); | ||
| 513 | 511 | ||
| 514 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 512 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 515 | rb.Push(RESULT_SUCCESS); | 513 | rb.Push(RESULT_SUCCESS); |
| @@ -519,23 +517,26 @@ void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { | |||
| 519 | void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) { | 517 | void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) { |
| 520 | IPC::RequestParser rp{ctx}; | 518 | IPC::RequestParser rp{ctx}; |
| 521 | 519 | ||
| 522 | auto save_struct = rp.PopRaw<std::array<u8, 0x40>>(); | 520 | auto save_struct = rp.PopRaw<FileSys::SaveDataDescriptor>(); |
| 523 | auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>(); | 521 | auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>(); |
| 524 | u128 uid = rp.PopRaw<u128>(); | 522 | u128 uid = rp.PopRaw<u128>(); |
| 525 | 523 | ||
| 526 | LOG_WARNING(Service_FS, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); | 524 | LOG_WARNING(Service_FS, "(STUBBED) called save_struct = {}, uid = {:016X}{:016X}", |
| 525 | save_struct.DebugInfo(), uid[1], uid[0]); | ||
| 527 | 526 | ||
| 528 | IPC::ResponseBuilder rb{ctx, 2}; | 527 | IPC::ResponseBuilder rb{ctx, 2}; |
| 529 | rb.Push(RESULT_SUCCESS); | 528 | rb.Push(RESULT_SUCCESS); |
| 530 | } | 529 | } |
| 531 | 530 | ||
| 532 | void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { | 531 | void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { |
| 533 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 532 | IPC::RequestParser rp{ctx}; |
| 533 | |||
| 534 | auto space_id = rp.PopRaw<FileSys::SaveDataSpaceId>(); | ||
| 535 | auto unk = rp.Pop<u32>(); | ||
| 536 | LOG_INFO(Service_FS, "called with unknown={:08X}", unk); | ||
| 537 | auto save_struct = rp.PopRaw<FileSys::SaveDataDescriptor>(); | ||
| 534 | 538 | ||
| 535 | // TODO(Subv): Read the input parameters and mount the requested savedata instead of always | 539 | auto filesystem = OpenSaveData(space_id, save_struct); |
| 536 | // mounting the current process' savedata. | ||
| 537 | FileSys::Path unused; | ||
| 538 | auto filesystem = OpenFileSystem(Type::SaveData, unused); | ||
| 539 | 540 | ||
| 540 | if (filesystem.Failed()) { | 541 | if (filesystem.Failed()) { |
| 541 | IPC::ResponseBuilder rb{ctx, 2, 0, 0}; | 542 | IPC::ResponseBuilder rb{ctx, 2, 0, 0}; |
| @@ -559,8 +560,8 @@ void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { | |||
| 559 | void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { | 560 | void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { |
| 560 | LOG_DEBUG(Service_FS, "called"); | 561 | LOG_DEBUG(Service_FS, "called"); |
| 561 | 562 | ||
| 562 | TryLoadRomFS(); | 563 | auto romfs = OpenRomFS(Core::System::GetInstance().CurrentProcess()->program_id); |
| 563 | if (!romfs) { | 564 | if (romfs.Failed()) { |
| 564 | // TODO (bunnei): Find the right error code to use here | 565 | // TODO (bunnei): Find the right error code to use here |
| 565 | LOG_CRITICAL(Service_FS, "no file system interface available!"); | 566 | LOG_CRITICAL(Service_FS, "no file system interface available!"); |
| 566 | IPC::ResponseBuilder rb{ctx, 2}; | 567 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -568,8 +569,8 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { | |||
| 568 | return; | 569 | return; |
| 569 | } | 570 | } |
| 570 | 571 | ||
| 571 | // Attempt to open a StorageBackend interface to the RomFS | 572 | auto storage = romfs.Unwrap()->OpenFile({}, {}); |
| 572 | auto storage = romfs->OpenFile({}, {}); | 573 | |
| 573 | if (storage.Failed()) { | 574 | if (storage.Failed()) { |
| 574 | LOG_CRITICAL(Service_FS, "no storage interface available!"); | 575 | LOG_CRITICAL(Service_FS, "no storage interface available!"); |
| 575 | IPC::ResponseBuilder rb{ctx, 2}; | 576 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -583,8 +584,40 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { | |||
| 583 | } | 584 | } |
| 584 | 585 | ||
| 585 | void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { | 586 | void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { |
| 586 | LOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess"); | 587 | IPC::RequestParser rp{ctx}; |
| 587 | OpenDataStorageByCurrentProcess(ctx); | 588 | |
| 589 | auto storage_id = rp.PopRaw<StorageId>(); | ||
| 590 | auto title_id = rp.PopRaw<u64>(); | ||
| 591 | |||
| 592 | LOG_DEBUG(Service_FS, "called with storage_id={:02X}, title_id={:016X}", | ||
| 593 | static_cast<u8>(storage_id), title_id); | ||
| 594 | if (title_id != Core::System::GetInstance().CurrentProcess()->program_id) { | ||
| 595 | LOG_CRITICAL( | ||
| 596 | Service_FS, | ||
| 597 | "Attempting to access RomFS of another title id (current={:016X}, requested={:016X}).", | ||
| 598 | Core::System::GetInstance().CurrentProcess()->program_id, title_id); | ||
| 599 | } | ||
| 600 | |||
| 601 | auto romfs = OpenRomFS(title_id); | ||
| 602 | if (romfs.Failed()) { | ||
| 603 | LOG_CRITICAL(Service_FS, "no file system interface available!"); | ||
| 604 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 605 | rb.Push(ResultCode(ErrorModule::FS, FileSys::ErrCodes::RomFSNotFound)); | ||
| 606 | return; | ||
| 607 | } | ||
| 608 | |||
| 609 | auto storage = romfs.Unwrap()->OpenFile({}, {}); | ||
| 610 | |||
| 611 | if (storage.Failed()) { | ||
| 612 | LOG_CRITICAL(Service_FS, "no storage interface available!"); | ||
| 613 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 614 | rb.Push(storage.Code()); | ||
| 615 | return; | ||
| 616 | } | ||
| 617 | |||
| 618 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 619 | rb.Push(RESULT_SUCCESS); | ||
| 620 | rb.PushIpcInterface<IStorage>(std::move(storage.Unwrap())); | ||
| 588 | } | 621 | } |
| 589 | 622 | ||
| 590 | } // namespace Service::FileSystem | 623 | } // namespace Service::FileSystem |
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index acb78fac1..4653eee4e 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h | |||
| @@ -19,8 +19,6 @@ public: | |||
| 19 | ~FSP_SRV() = default; | 19 | ~FSP_SRV() = default; |
| 20 | 20 | ||
| 21 | private: | 21 | private: |
| 22 | void TryLoadRomFS(); | ||
| 23 | |||
| 24 | void Initialize(Kernel::HLERequestContext& ctx); | 22 | void Initialize(Kernel::HLERequestContext& ctx); |
| 25 | void MountSdCard(Kernel::HLERequestContext& ctx); | 23 | void MountSdCard(Kernel::HLERequestContext& ctx); |
| 26 | void CreateSaveData(Kernel::HLERequestContext& ctx); | 24 | void CreateSaveData(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 5fdb1d289..0b11bf4f3 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp | |||
| @@ -154,8 +154,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( | |||
| 154 | 154 | ||
| 155 | // Register the RomFS if a ".romfs" file was found | 155 | // Register the RomFS if a ".romfs" file was found |
| 156 | if (!filepath_romfs.empty()) { | 156 | if (!filepath_romfs.empty()) { |
| 157 | Service::FileSystem::RegisterFileSystem(std::make_unique<FileSys::RomFS_Factory>(*this), | 157 | Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this)); |
| 158 | Service::FileSystem::Type::RomFS); | ||
| 159 | } | 158 | } |
| 160 | 159 | ||
| 161 | is_loaded = true; | 160 | is_loaded = true; |
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index 0fd930ae2..b463f369c 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp | |||
| @@ -277,8 +277,7 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) { | |||
| 277 | metadata.GetMainThreadStackSize()); | 277 | metadata.GetMainThreadStackSize()); |
| 278 | 278 | ||
| 279 | if (nca->GetRomFsSize() > 0) | 279 | if (nca->GetRomFsSize() > 0) |
| 280 | Service::FileSystem::RegisterFileSystem(std::make_unique<FileSys::RomFS_Factory>(*this), | 280 | Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this)); |
| 281 | Service::FileSystem::Type::RomFS); | ||
| 282 | 281 | ||
| 283 | is_loaded = true; | 282 | is_loaded = true; |
| 284 | return ResultStatus::Success; | 283 | return ResultStatus::Success; |
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 1c629e21f..7b3d6b837 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -115,7 +115,7 @@ VAddr AppLoader_NSO::LoadModule(const std::string& name, const std::vector<u8>& | |||
| 115 | std::vector<u8> program_image; | 115 | std::vector<u8> program_image; |
| 116 | for (int i = 0; i < nso_header.segments.size(); ++i) { | 116 | for (int i = 0; i < nso_header.segments.size(); ++i) { |
| 117 | std::vector<u8> compressed_data(nso_header.segments_compressed_size[i]); | 117 | std::vector<u8> compressed_data(nso_header.segments_compressed_size[i]); |
| 118 | for (int j = 0; j < nso_header.segments_compressed_size[i]; ++j) | 118 | for (auto j = 0; j < nso_header.segments_compressed_size[i]; ++j) |
| 119 | compressed_data[j] = file_data[nso_header.segments[i].offset + j]; | 119 | compressed_data[j] = file_data[nso_header.segments[i].offset + j]; |
| 120 | std::vector<u8> data = DecompressSegment(compressed_data, nso_header.segments[i]); | 120 | std::vector<u8> data = DecompressSegment(compressed_data, nso_header.segments[i]); |
| 121 | program_image.resize(nso_header.segments[i].location); | 121 | program_image.resize(nso_header.segments[i].location); |